Самая частая потребность при разработке бота — это сопоставление пользователя 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") Тогда
        // Это передача контакта — обрабатываем в обработке "Сопоставление"
        // Фрагмент "Выполнение обработки"
        Обработка = Справочники.ТелеграмОбработки.НайтиПоНаименованию("Сопоставление"); 
        Справочники.ТелеграмОбработки.ВыполнитьОбработку(Обработка, Бот, Вход); // Конец фрагмента
    ИначеЕсли НЕ ЗначениеЗаполнено(Вход.ПараметрыПользователя.ФизЛицо) Тогда
        // Если пользователь не сопоставлен, то запрещаем пользоваться ботом
        ПараметрыМетода = Новый Структура;
        ПараметрыМетода.Вставить("Сообщение", "Пользователь не сопоставлен");
        ОтправитьСообщение(Бот, ПараметрыМетода, Вход);
        Вход.ПрерватьВыполнение = Истина;
    КонецЕсли;            
            

Поместите ссылку на неё на закладку "Специальные обработки" бота, событие "Перед выполнением"