Создать телеграм бота 1с
Много строк исписано про интеграцию Телеграма и 1С. Но нигде не увидел полной инструкции по установке и настройке вебхуков. Попробую её написать.
Для всего этого нам понадобится (или правильнее будет сказать, что было использовано мной):
- Apache 2.2.24
- OpenSSL (входящий в установку апача)
- 1C (с модулями веб-сервера)
- Свой домен
- Созданный бот в Телеграм (не буду описывать его создание, т.к. оно достаточно тривиально)
YOURPRIVATE.key — закрытый ключ сертификата. Будет использован в апаче
YOURPUBLIC.pem — открытый ключ сертификата. Будет использован при регистрации вебхука
YOURDOMAIN.EXAMPLE — адрес вашего домена с вебхуком. Должен таки совпадать с адресом вебхука.
После выполнения этого кода в папке openssl ( у меня это «C:\Program Files\Apache Software Foundation\Apache2.2\bin») появятся файлы ключей.
Я их скопировал в папку conf апача.
Переходим к настройке Apache.
Я видел много разных способов. У меня сработал следующий:
для того, чтобы апач «слушал» 443 порт.
Блок приведен к следующему виду:
В самом конце добавлены строчки, где указываю пути к сертификату:
И раскомменитурйте строчку:
В моём случае указаны следующие параметры:
Имя: ТГВебхук
КорневойURL: webhook
Повторное использование сеансов: Не использовать (с автоматическим режимом у меня не заработало)
Время жизни: 20
Шаблоны URL: создан шаблон «Любой» с двумя методами: GET и POST
Обработчики методов создаются по умолчанию. В обработчик POST добавлю следующее, просто для проверки связи:
ВашДомен/ИмяБазы/hs/ИмяСервиса/v1
Прошу не пинать ногами за код, некоторые вещи умышленно сделаны хардкодом, т.к. это всё делалось исключительно в демонстрационных целях.
Публикация была написана, т.к. ни одного рабочего примера по работе с вебхуками на сайте не нашел, кроме Конструктор ботов Телеграм. Но она платная и, возможно, не всем нужна в таком виде.
Задача:
Создать телеграм бота и научится работать с ним в «1С:Предприятие 8», через long polling и webhooks, используя Telegram bot API.
02.04.2021 Обновлено:
— Добавлено видео «Интеграция 1С с Telegram за 12 минут», где показано как с помощью системы взаимодействия работать с телеграм ботом.
В результате, будет сформирован токен доступа, который необходимо сохранить и держать в секрете, а созданного бота добавить себе в приложение «Телеграм».
2. Два способа работы с телеграм ботом.
При помощи «Telegram Bot API», есть два взаимоисключающих способа работы с телеграм ботом:
- Метод «getUpdates» – самостоятельно, выполняем запрос получения новых обновлений.
- Использование «Webhooks» – обновления приходят автоматически от сервера, на указанный URL-адрес.
Ответ приходит в виде JSON, не обработанные обновления хранятся на сервере до тех пор, пока бот их не получит, но они не будут храниться дольше 24 часов.
3. Подготовка конфигурации.
3.2 Создаем пустую (вспомогательную) конфигурацию и выполняем «Загрузить конфигурацию из файлов…», используя папку «src» (см. п. 3.1):
Коннектор: Загрузка конфигурации
Перенос общего модуля
3.4 Создаем константу «Токен» (тип «Строка», длина 100) и сохраняем в ней полученный токен из п. 1.
3.5 Добавляем подсистему и обработку «РаботаСБотом».
3.6 В обработке добавляем форму, далее реквизит формы «Журнал» (тип «ТекстовыйДокумент») и команду «ТестТокена», для которой создаем функцию обработчик с директивой «&НаСервереБезКонтекста». В обработчике, отправляем запрос к методу API «getMe» — который используется для проверки токена аутентификации и возвращает основную информацию о боте:
4. Метод «getUpdates».
Из 1С, самостоятельно, периодически обращаемся к методу API «getUpdates», для получения 100 самых ранних неподтвержденных (не полученных ранее) обновлений, в виде JSON объекта «Update».
4.1 На форму обработки, добавляем команду «Обновить» и функцию обработчик с директивой «&НаСервереБезКонтекста». Перед отправкой запроса, при необходимости заполняются параметры:
offset | Идентификатор возвращаемого обновления — каждое обновление имеет свой числовой идентификатор «update_id». |
limit | Ограничивает количество получаемых обновлений. Принимаются значения от 1 до 100. |
timeout | Тайм-аут в секундах для длительного опроса. |
allowed_updates | Задается список типов обновлений, которые должен получать бот. |
Для нашего примера, будет заполнен только параметр offset равным 0, для того чтобы получить все не обработанные обновления. Процедура обработки команды «Обновить» на клиенте:
Методы «ОбновитьНаСервере» и «ОбработатьОбновление»:
5. Использование «Webhooks»
5.4 Откройте «Open Server Panel», но не запускайте, должен быть красный флажок. В конфигураторе открыть, меню «Администрирование – Публикация на веб-сервере…» выбрать каталог и нажать «Опубликовать», без перезапуска веб-сервера.
Их нужно сохранить в шаблоне «C:\OpenServer\userdata\config\Apache_2.4-PHP_7.2-7.4_server.conf», для того чтобы при следующем запуске «Open Server» они не затерлись.
Для проверки воспользуемся приложением «Postman»:
В результате, внутренние локальные сервисы, станут доступны для внешнего взаимодействия:
Postman test ngrok
Для эксперимента, попробуем это сделать через «Postman»:
Для удаление webhook и переход на метод «getUpdates», достаточно вызвать метод «deleteWebhook»:
Теперь схема работы выглядит следующий образом:
Для начала зарегистрируем бота, получим его id - токен. В Telegram для этого создан специальный бот — @BotFather. Добавляем его в контакт. Получаем получаем список его команд, написав ему /start.
Этого, в принципе, достаточно.
2. Создание обработки в 1С
Создадим внешнюю обработку. Добавим реквизиты обработки строковый переменной длины «Бот», «Токен», «Сервер».
Т.к. обработку не будем привязывать к конкретной конфигурации, то список понимаемых команд будем хранить в табличной части обработки «ТаблицаПонимаемыхКоманд» (а так, в принципе, команды можно хранить в справочнике конфигурации).
Реквизиты ТЧ строковые: «Имя», «ВыполняемоеДействие», «Параметр», «Описание»
Команды пользователя (те, которые он буде писать боту) по той же причине будем хранить в табличной части «КомандыПользователей» (если не делать обработку универсальной, то, конечно, предпочтительно использовать регистр сведений – далее, в листингах кода укажем примеры и для регистра сведений тоже).
Реквизиты ТЧ: числовые «chat_id», «date», булево «Выполнено» и строковый «Команда»
Теперь создадим управляемую форму обработки, назначим ее основной и разместим реквизиты «Бот» и «Токен» (необязательно, но для наглядности):
Также создадим реквизит формы «Дерево» – тип «ДеревоЗначений». В нем будут отображаться чаты. Для наглядности выведем его на форму. Колонки дерева создадим программно (см.далее).
Для события формы ПриСозданииНаСервере добавим процедуру:
Если Вы используете версию 1С 8.3.6 и выше, то в процедура ПрочитатьДвоичныеДанныеОтвета() будем использовать новый объект ЧтениеJSON().
В процедуре ЗаполнитьРС() будем заполнять табличную часть «КомандыПользователей» (или же регистр сведений). (код процедуры далее).
Процедура ЗаполнитьСтруктуруИзОтветаJSON() заполняет дерево чатов:
Если Вы используете версию 1С ниже 8.3.6 то процедура ПрочитатьДвоичныеДанныеОтвета() будет такой:
Как уже было сказано, в процедуре ЗаполнитьРС() будем заполнять табличную часть «КомандыПользователей» (или же регистр сведений). (код процедуры далее).
Процедура ЗаполнитьСтруктуруИзОтветаJSON() – это парсер JSON и рекурсивное заполнение дерева для версии ниже 1С 8.3.6:
Теперь опишем процедуру, заполняющую табличную часть «КомандыПользователей» либо регистр сведений:
Если вы будете использовать регистр сведений (я назвал его «КомандыПользователей»), то закомментируйте/раскомментируйте соответствующие участки кода.
Обратите внимание, что если версия ниже 1С 8.3.6, то в коде переменную Параметр надо преобразовать из Юникода (этот участок обозначен в коде в комментарии):
Для этого используем две функции Юникод – парсер (он нужен только для версии 1С ниже 8.3.6):
В процедуре ЗаполнитьРС() вызывается функция ВыполнитьКомандуБота(ЗаписьРегистра, Параметр), где ЗаписьРегистра – это строка табличной части ТаблицаПонимаемыхКоманд. Параметр – параметр команды (то, что написал боту пользователь).
Вот и все – обработка прилагается.
Отдельное спасибо пользователю Инфостарт igo1 - перекодировка из Юникода (Unicode) в строку.
Основу для построения чата для версии 1С ниже 8.3.6 (парсер JSON) получил отсюда
UPD. В комментариях был задан вопрос " как отправлять файлы ".
Вот текст процедуры, которая выполняет отчет "Продажи" (на СКД), сохраняет результат в Excel и отправляет в Telegram:
? возникает ошибка типа Ошибка при вызове метода контекста (ОбъединитьФайлы)
ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);
по причине:
Ошибка сборки файла
по причине:
Ошибка совместного доступа к файлу 'C:\Users\Гуру\AppData\Local\Temp\v8_7B5A_12.txt'
(163) А зачем посылать клавиатуру в тот момент когда отсылаем картинку? В момент отправки картинки на сервер Телеграм, он возвращает уникальный номер картинки, поэтому в дальнейшем достаточно покупателю отсылать этот номер, а сервер находит вашу картинку и посылает её. Порядок работы нужно изменить. Сначала отсылаем ВСЕ КАРТИНКИ и получаем их номера из Телеграм и записываем их у себя в базу. А теперь имея номер картинки посылаем file_id и подпись под картинкой и необходимую клавиатуру, то есть манипулируем уже не картинками, а номерами file_id. Об этом же все написано в документации Телеграм Bot API.
Ух, жесть какая-то :)
Все больше на ИС обработок скрещивания1С и прочего и прочего :)
Это замечательно, но напоминает анекдот о том, как британские ученые скрещивали слона и слона, не для пользы, а так просто, "позырить" :)
- я так частенько от наработок других программистов что-то интересное для себя нахожу, поэтому и сам готов поделиться.
Luchik , отличная статья, толково и не затянуто. Надо будет поэкспериментировать с Telegram, а то раньше все руки не доходили разобраться.
Спасибо, "плюс в репу".
(198) Кто за прогресс, за развитие науки и технологий, тот, кто и сам занимается этим развитием в 1С, не может быть резистом.
Телеграм это тема! Жаль что у меня сервер в закрытой сети, так бы тоже нашел применение. Автору респект за труды и статью.
Столкнулся вот с такой ошибкой:
: Ошибка при вызове метода контекста (ПрочитатьДвоичныеДанныеОтвета)
ПрочитатьДвоичныеДанныеОтвета(ДвоичныеДанныеОтвета);
по причине:
Переполнение стека встроенного языка на сервере
по причине:
Обработка.ТелеграммБот.Форма.Форма.Форма : 32 : СформироватьДерево(ДеревоЗн, ДеревоЗн, ЧтениеJSON);
Обработка.ТелеграммБот.Форма.Форма.Форма : 71 : СформироватьДерево(Дерево, НовСтр, ЧтениеJSON);
Обработка.ТелеграммБот.Форма.Форма.Форма : 75 : СформироватьДерево(Дерево, СтрДерево, ЧтениеJSON, ЧтениеJSON.ТекущееЗначение);
Обработка.ТелеграммБот.Форма.Форма.Форма : 83 : СформироватьДерево(Дерево, СтрДерево, ЧтениеJSON);
.
Обработка.ТелеграммБот.Форма.Форма.Форма : 75 : СформироватьДерево(Дерево, СтрДерево, ЧтениеJSON, ЧтениеJSON.ТекущееЗначение);
Обработка.ТелеграммБот.Форма.Форма.Форма : 83 : СформироватьДерево(Дерево, СтрДерево, ЧтениеJSON);
Обработка.ТелеграммБот.Форма.Форма.Форма : 75 : СформироватьДерево(Дерево, СтрДерево, ЧтениеJSON, ЧтениеJSON.ТекущееЗначение);
Обработка.ТелеграммБот.Форма.Форма.Форма : 0
по причине:
Переполнение стека встроенного языка на сервере
(97) Проблему решил следующим образом:
(100) Я давал выше вариант, при котором никаких проблем нет. Уже несколько ботов сделал и они прекрасно работают.
(104). не нашел ваш вариант решения ошибки "Переполнение стека встроенного языка на сервере ", который вы давали выше. Могли бы вы продублировать?
Вторая
Опрашиваем через GetUpdates - пишем в регистр ID, текст, ChatID и статус - отвечено или нет
ну а потом просто сравниваем то что пришло и отвечено - игнорим, то что пришло и не отвечено отвечаем и пишем статус.
(30) iolko, Да, я как раз выбрал первый способ!
Теперь я задумался над авторизацией пользователя, для открытия доступа к командам бота.
Никто не знает, как можно пограммно провести аудентификацию пользователя?
(31) TreeDogNight, Легко. если пользователь отправляет команду, допустим MyId - то отправляешь ему Его ID дальше ручками вносишь ее в спр пользователи.
а потом уже, чтобы отсеить ненужных проверяешь если ChatId есть в спр пользователей - велком , если нет ну не судьба тогда )))
Это первый вариант - при котором можно использовать первый вариант получения обновлений.
2 вариант - придумка для корпоративных систем (с которым нужно использовать второй вариант получения обновлений) - запрос на добавление, запоминаем ID и просим ввести адрес корпоративной почты, отправляем на этот адрес какой то сгенерированый ПИН, и ждем подтверждения.
(31) TreeDogNight, Ну и Вам адресую этот вопрос)
Есть ли варианты кроме перебора дерева с поиском значения message_id?
Теперь у меня встал новый вопрос. Как вывести клавиатуру?
Как я понял, мы должны передать в метод sendMessage сериализованную JSON-структуру, но к сожалению примеров этой структуры нигде не приводится.
Но к сожалению клавиатура не появилась. Либо текст JSON неправильно сформировали, либо его нужно сувать не в заголовки.
Всё, наконец разобрался с этой клавиатурой!
Оказывается текст с параметрами нужно было приклеить к строке с ресурсмом и установить как тело запроса!
Вот код:
Kireno; maksa2005; mevgenym; AlX0id; JohnyDeath; ui69; rayastar; Renegade; Anchoret; madonov; METAL; WanGoff; _also; Luchik; eskor; + 15 – Ответить
Подскажите как вывести фото с кнопками обратной связи?
Фото получается отослать, а вот вывести вместе с клавиатурой вообще никак.
Легко. если пользователь отправляет команду, допустим MyId - то отправляешь ему Его ID дальше ручками вносишь ее в спр пользователи.
а потом уже, чтобы отсеить ненужных проверяешь если ChatId есть в спр пользователей - велком , если нет ну не судьба тогда )))
также обернуть число chat_id в обертку
Теперь можно вызывать процедуру ПрочитатьДвоичныеДанныеОтвета, передавая ей текстовую строку. Зачем? Чтобы не записывать эти двоичные данные в файл и не читать из него назад:
Испытал удивление от потэгового анализа JSON. Есть функция ПрочитатьJSON(), которая в структурированном виде считывает весь пакет:
В результате чтения публикации Вы получите готовую внешнюю обработку, позволяющую получать из 1С данные, запрашиваемые через Telegram.
В данной статье рассмотрим следующее:
Для начала, зарегистрируем бота, получим его id - токен. В Telegram для этого создан специальный бот — @BotFather.
Добавляем его в контакт. Получаем получаем список его команд, написав ему /start.
Этого, в принципе, достаточно.
2. Создание обработки в 1С
Создадим внешнюю обработку. Добавим реквизиты обработки строковый переменной длины «Бот», «Токен», «Сервер».
Т.к. обработку не будем привязывать к конкретной конфигурации, то список понимаемых команд будем хранить в табличной части обработки «ТаблицаПонимаемыхКоманд» (а так, в принципе, команды можно хранить в справочнике конфигурации).
Реквизиты ТЧ строковые: «Имя», «ВыполняемоеДействие», «Параметр», «Описание»
Команды пользователя (те, которые он буде писать боту) по той же причине будем хранить в табличной части «КомандыПользователей» (если не делать обработку универсальной, то, конечно, предпочтительно использовать регистр сведений – далее, в листингах кода укажем примеры и для регистра сведений тоже).
Реквизиты ТЧ: числовые «chat_id», «date», булево «Выполнено» и строковый «Команда».
Теперь создадим управляемую форму обработки, назначим ее основной и разместим реквизиты «Бот» и «Токен» (необязательно, но для наглядности):
Также создадим реквизит формы «Дерево» – тип «ДеревоЗначений». В нем будут отображаться чаты. Для наглядности выведем его на форму. Колонки дерева создадим программно (см.далее).
Для события формы ПриСозданииНаСервере добавим процедуру:
Если Вы используете версию 1С 8.3.6 и выше, то в процедуре ПрочитатьДвоичныеДанныеОтвета() будем использовать новый объект ЧтениеJSON()
.
В процедуре ЗаполнитьРС() будем заполнять табличную часть «КомандыПользователей» (или же регистр сведений). (код процедуры далее).
Процедура ЗаполнитьСтруктуруИзОтветаJSON() заполняет дерево чатов:
Если Вы используете версию 1С ниже 8.3.6 то процедура ПрочитатьДвоичныеДанныеОтвета() будет такой:
Как уже было сказано, в процедуре ЗаполнитьРС() будем заполнять табличную часть «КомандыПользователей» (или же регистр сведений). (код процедуры далее).
Процедура ЗаполнитьСтруктуруИзОтветаJSON() – это парсер JSON и рекурсивное заполнение дерева для версии ниже 1С 8.3.6:
Теперь опишем процедуру, заполняющую табличную часть «КомандыПользователей» либо регистр сведений:
Если вы будете использовать регистр сведений (я назвал его «КомандыПользователей»), то закомментируйте/разкомментируйте соответствующие участки кода.
Обратите внимание, что если версия ниже 1С 8.3.6, то в коде переменную Параметр надо преобразовать из Юникода (этот участок обозначен в коде в комментарии - разкомментируйте его):
Для этого используем две функции Юникод – парсер (он нужен только для версии 1С ниже 8.3.6):
В процедуре ЗаполнитьРС() вызывается функция ВыполнитьКомандуБота(ЗаписьРегистра, Параметр), где ЗаписьРегистра – это строка табличной части ТаблицаПонимаемыхКоманд (либо запись Вашего регистра сведений). Параметр – параметр команды (то что написал боту пользователь).
- о версии операционной системы;
- о версии используемого 1С:Предприятия 8 в формате ....(например, 8.2.9.200);
- Уникальный идентификатор клиента. Для данного компьютера и данного пользователя операционной системы идентификатор один, вне зависимости от информационной базы и пользователя информационной базы;
- о веб-браузере (userAgent);
- о размере оперативной памяти;
- Идентификатор процессора;
- тип платформы, в рамках которой осуществляется работа.
Для того, чтобы все работало автоматом лучше использовать фоновое задание. Но так как наша Обработка не привязана к конкретной базе данных и к конкретной конфигурации. То подключим обработчик ожидания.
Создадим команду формы «ЗапускФоновыхЗаданий», разместим соответствующую кнопку на форме. Обработчик команды:
Вот и все – Обработка прилагается.
Отдельное спасибо пользователю Инфостарт igo1 - перекодировка из Юникода (Unicode) в строку.
- чем-то проверяем записи регистра,
Вроде бы ничего сложного, но "подводных камней" оказалось нормально так. Например, как для каждой пары "бот-пользователь" вести диалог не перепутав одно с другим? Или такое - как собрать все данные диалога и до окончания диалога не растерять их?
По идее можно на один веб-хук повесить несколько ботов (не проверял). Для бота в справочнике "Константы" создать запись, где "Наименование" должно быть такое же как при установке веб-хука.
В справочнике "Константы" создаем две записи:
Bot_Name_1, значение = ТокенБота1
Bot_Name_2, значение = ТокенБота2
Выглядит это так:
В сухом остатке, так сказать "подытожим":
2. Диалоги с пользователем ведем с помощью регистра "ТелеграмСтекРазговоров"
3. Диалоги и набор диалогов - эта два справочника "БотДиалоги" и "БотСтекДиалогов"
4. На сейчас все сырое, много идей в голове, но все как-то сумбурно ))) Хотел еще диалоги о предоставлении файликов и всякие действия. Но пока отложу. С мыслями надо собраться.
Читайте также: