Самая частая потребность при разработке бота — это сопоставление пользователя Telegram с пользователем или контрагентом в 1С
Какие способы идентификации предлагаются?
На выбор предлагается 4 способа идентификации:
- Идентификация по связке пользователь 1С / пароль в 1С — предполагает, что пользователь бота является одновременно и пользователем 1С
- Идентификация по номеру телефона — пользователь отправляет номер телефона, на который зарегистрирован Telegram. Способ предполагает, что этот же номер телефона содержится в справочниках 1С
- Идентификация по пригласительной ссылке — внутри 1С генерируется пригласительная ссылка, связывается с объектом 1С и потом высылается пользователю любым другим доступным способом
- Идентификация по команде — вариант идентификации по пригласительной ссылке
Идентификация по связке пользователь 1С / пароль 1С
Создайте параметр "ОжидаетсяВводПользователя", тип возвращаемого значения "Булево":
Отправьте пользователю приглашение к вводу пользователя 1С и пароля 1С:
Код обработки:
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение",
"Введите имя пользователя из 1С,
|потом дефис и пароль, например:
Иван Васильевич - 12345");
ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
УстановитьПараметр(Вход.Пользователь, "ОжидаетсяВводПользователя", Истина);
Обработка ответа от пользователя:
Создайте условие "Это ввод пользователя":
Создайте обработку "Введены пользователь и пароль из 1С" со следующим кодом:
// сразу и обязательно сбрасываем параметр "ОжидаетсяВводПользователя"
УстановитьПараметр(Вход.Пользователь, "ОжидаетсяВводПользователя", Ложь); // Конец фрагмента
ИдентификацияОсуществлена = Ложь;
ВведеннаяСтрока = Вход.Текст;
СимволДефис = Найти(ВведеннаяСтрока, "-");
Если СимволДефис > 0 Тогда
СтрокаПользователь = СокрЛП(Лев(ВведеннаяСтрока, СимволДефис - 1));
ПользовательСсылка = ПользователиИнформационнойБазы.НайтиПоИмени(СтрокаПользователь);
Если ПользовательСсылка <> Неопределено Тогда
СтрокаПароль = СокрЛП(Сред(ВведеннаяСтрока, СимволДефис + 1));
Хеш = Новый ХешированиеДанных(ХешФункция.SHA1);
Хеш.Добавить(СтрокаПароль);
Base64СтрокаПароль = Base64Строка(Хеш.ХешСумма);
ВРегСтрокаПароль = ВРег(СтрокаПароль);
Хеш = Новый ХешированиеДанных(ХешФункция.SHA1);
Хеш.Добавить(ВРегСтрокаПароль);
ВРегBase64СтрокаПароль = Base64Строка(Хеш.ХешСумма);
Если ЗначениеЗаполнено(СтрокаПароль) Тогда
СохраняемоеЗначениеПароля = Base64СтрокаПароль + "," + ВРегBase64СтрокаПароль;
Иначе
СохраняемоеЗначениеПароля = "";
КонецЕсли;
Если ПользовательСсылка.СохраняемоеЗначениеПароля = СохраняемоеЗначениеПароля Тогда
ИдентификацияОсуществлена = Истина;
// здесь подразумевается, что существует параметр
// Пользователь типа СправочникСсылка.Пользователи
УстановитьПараметр(Вход.Пользователь, "Пользователь", ПользовательСсылка);
// отправка сообщения пользователю
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Сопоставление успешно произведено");
ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ИдентификацияОсуществлена = Ложь Тогда
// отправка сообщения пользователю
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Не удалось провести сопоставление — неверная пара пользователь/пароль");
ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
КонецЕсли;
Создайте следующий сервис:
Идентификация по номеру телефона
Создайте клавиатуру с запросом телефонного номера
- Вид клавиатуры — стандартный
- Текст — любой
- Флаг "Запросить контакт" — включен
Отправьте клавиатуру пользователю
- Параметры метода должны содержать ключ "Клавиатура"
- Значение — наименование ранее созданной клавиатуры, "Запрос номера"
Пользователь увидит кнопку отправки номера:
Подтверждение и отправка номера:
После подтверждения и отправки номер следует отловить следующим сервисом:
Где Вход.Сообщение — структура вида https://core.telegram.org/bots/api#message, а Contact — структура вида https://core.telegram.org/bots/api#contact
Результат выполнения обработки — ответ "Вы прислали номер: +nnnnnnnnnnn":
В современных типовых конфигурациях 1С телефонные номера хранятся в табличных частях "КонтактнаяИнформация" таких справочников,
как "КонтактныеЛицаПартнеров", "Контрагенты", "Партнеры", "Пользователи", "ФизическиеЛица" и другие. Табличная часть "КонтактнаяИнформация"
содержит не только телефонные номера, но этот факт не обязательно учитывать, так как интересующая нас колонка "НомерТелефона" заполнена
только для телефонных номеров.
Также, стоит иметь ввиду, что в 1С телефонные номера содержатся без знака "+"
Примерный текст обработки (пусть она называется "Сопоставление") определения физического лица по номеру полученного из Telegram телефона:
// Преобразуем +79776125555 в 79776125555
НомерТелефона1С = Сред(Вход.Сообщение.Contact.phone_number, 2);
// В качестве примера — запрос по справочнику "ФизическиеЛица"
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КИ.Ссылка КАК Ссылка,
| КИ.Ссылка.Представление КАК Наименование
|ИЗ
| Справочник.ФизическиеЛица.КонтактнаяИнформация КАК КИ
|ГДЕ
| КИ.НомерТелефона = &НомерТелефона";
Запрос.УстановитьПараметр("НомерТелефона", НомерТелефона1С);
Результат = Запрос.Выполнить();
Если Результат.Пустой Тогда // Номер телефона в 1С не найден
// Отправка сообщения пользователю — сопоставление не произведено
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Ваш номер телефона в базе не найден, сопоставление не произведено");
ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
Иначе // Есть элементы с заданным номером телефона
Выборка = Результат.Выбрать();
Выборка.Следующий();
// Установка значения параметра.
// Исходим из того, что сопоставление хранится в параметре "ФизЛицо" с типом значения СправочникСсылка.ФизическиеЛица
// как в видео https://youtu.be/WCjbkVfDcRo
УстановитьПараметр(Вход.Пользователь, "ФизЛицо", Выборка.Ссылка);
// Отправка сообщения пользователю — сопоставление произведено
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Сопоставление произведено успешно: " + Выборка.Наименование);
ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
КонецЕсли;
Идентификация по пригласительной ссылке
Перейдя по пригласительной ссылке вида t.me/your_bot?start=b0c35266-2b60-4381-9b73-38c207fa00ef, пользователь начнёт диалог с ботом как обычно, но при этом Вы сразу сможете его идентифицировать.
Формирование пригласительной ссылки
// ссылка на элемент справочника
ФизЛицоСсылка = Справочники.ФизическиеЛица.НайтиПоНаименованию("Петя Иванов");
// получение уникального идентификатора элемента справочника
УникальныйИдентификатор = Строка(ФизЛицоСсылка.УникальныйИдентификатор());
// Текст для пользователя с пригласительной ссылкой
ТекстПриглашения = СтрШаблон(
"Уважаемый(ая) %1, для запуска бота перейдите по персональной ссылке: t.me/%2?start=%3",
ФизЛицоСсылка.Наименование,
ИмяБота,
УникальныйИдентификатор);
Идентификация
Сервис:
Обработка:
Код обработки:
УникальныйИдентификатор = Сред(Вход.Текст, 8);
Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда
ФизЛицоСсылка = Справочники.ФизическиеЛица.ПолучитьСсылку(
Новый УникальныйИдентификатор(УникальныйИдентификатор));
Если ЗначениеЗаполнено(ФизЛицоСсылка.Наименование) Тогда
// элемент найден, производим сопоставление
УстановитьПараметр(Вход.Пользователь, "ФизЛицо", ФизЛицоСсылка); // Фрагмент "Установка параметра"
// Отправляем уведомление
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Сопоставление произведено, здравствуйте, " + ФизЛицоСсылка);
ОтветСервера = ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
Иначе
// элемент справочника не найден, отправляем уведомление
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Произвести сопоставление не удалось — недействительная ссылка");
ОтветСервера = ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
КонецЕсли;
КонецЕсли;
Идентификация по команде
Определитесь с командой для сопоставления. Например, "/invite"
Формирование команды для пользователя
// ссылка на элемент справочника
ФизЛицоСсылка = Справочники.ФизическиеЛица.НайтиПоНаименованию("Петя Иванов");
// получение уникального идентификатора элемента справочника
УникальныйИдентификатор = Строка(ФизЛицоСсылка.УникальныйИдентификатор());
// Текст для пользователя
ТекстДляПользователя = СтрШаблон(
"Уважаемый(ая) %1, для Вашей идентификации введите в диалог с ботом команду /invite %2",
ФизЛицоСсылка.Наименование,
УникальныйИдентификатор);
Идентификация
Сервис:
Обработка:
Код обработки:
УникальныйИдентификатор = Сред(Вход.Текст, 9);
Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда
ФизЛицоСсылка = Справочники.ФизическиеЛица.ПолучитьСсылку(
Новый УникальныйИдентификатор(УникальныйИдентификатор));
Если ЗначениеЗаполнено(ФизЛицоСсылка.Наименование) Тогда
// элемент найден, производим сопоставление
УстановитьПараметр(Вход.Пользователь, "ФизЛицо", ФизЛицоСсылка); // Фрагмент "Установка параметра"
// Отправляем уведомление
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Сопоставление произведено, здравствуйте, " + ФизЛицоСсылка);
ОтветСервера = ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
Иначе
// элемент справочника не найден, отправляем уведомление
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Произвести сопоставление не удалось — недействительная ссылка");
ОтветСервера = ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
КонецЕсли;
КонецЕсли;
Как можно запретить доступ к боту всем не идентифицированным пользователям?
Создайте обработку следующего содержания:
Код:
Если Лев(Вход.Текст, 6) = "/start" Тогда
// это старт использования бота, поэтому ничего не делаем
ИначеЕсли Вход.Сообщение.Свойство("Contact") Тогда
// Это передача контакта — обрабатываем в обработке "Сопоставление"
// Фрагмент "Выполнение обработки"
Обработка = Справочники.ТелеграмОбработки.НайтиПоНаименованию("Сопоставление");
Справочники.ТелеграмОбработки.ВыполнитьОбработку(Обработка, Бот, Вход); // Конец фрагмента
ИначеЕсли НЕ ЗначениеЗаполнено(Вход.ПараметрыПользователя.ФизЛицо) Тогда
// Если пользователь не сопоставлен, то запрещаем пользоваться ботом
ПараметрыМетода = Новый Структура;
ПараметрыМетода.Вставить("Сообщение", "Пользователь не сопоставлен");
ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
Вход.ПрерватьВыполнение = Истина;
КонецЕсли;
Поместите ссылку на неё на закладку "Специальные обработки" бота, событие "Перед выполнением"