Как правильно настроить ответ Telegram-боту через вебхук в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с мессенджером Telegram часто возникает необходимость обрабатывать входящие сообщения от пользователей через механизмы вебхуков (Webhook). В этой схеме сервер Telegram отправляет HTTP-запрос на специальный HTTP-сервис 1С при каждом новом событии в чате. Однако разработчики сталкиваются с проблемой: бот получает входящие данные, но отправленные из 1С ответные сообщения не доходят до чата.

В этой статье мы разберем основные причины, почему ответные сообщения не отправляются, рассмотрим типичные ошибки в коде 1С и изучим два рабочих способа реализации взаимодействия с Telegram API.

Анализ проблемы: почему ответ в вебхуке не работает

Посмотрим на распространенный сценарий, когда разработчик пытается передать тело ответа с параметрами команды прямо в возвращаемом объекте HTTPСервисОтвет. В коде 1С это выглядит следующим образом:


СтруктураОтвета = Новый Структура("method, chat_id, text", "sendMessage", Формат(Результат.message.chat.id, "ЧГ=0"), "Hello");

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураОтвета);
СтрокаДляОтвета = ЗаписьJSON.Закрыть();

Ответ = Новый HTTPСервисОтвет(200);    
Ответ.Заголовки.Вставить("Content-type", "application/json; charset=utf-8");

// Ошибка: передается объект Структура вместо сформированной строки JSON
Ответ.УстановитьТелоИзСтроки(СтруктураОтвета); 

Возврат Ответ;

Выясним причину ошибки в данном коде:

  1. Несоответствие типов данных в методе: Метод УстановитьТелоИзСтроки() объекта HTTPСервисОтвет принимает исключительно значение типа Строка и кодировку. Если передать в него объект типа Структура (как в коде выше), платформа 1С сгенерирует исключение, HTTP-сервис вернет ошибку с кодом 500, и Telegram не сможет обработать ответ. В метод необходимо передавать переменную СтрокаДляОтвета.
  2. Форматирование идентификатора чата: Telegram ожидают корректно отформатированный chat_id. Использование функции Формат(chat_id, "ЧГ=0") является обязательным, чтобы исключить разделители групп триад (пробелы) в числовом значении.

Способ 1. Прямой ответ в теле HTTP-сервиса

Telegram API действительно поддерживает отправку одной команды прямым ответом на HTTP-запрос вебхука. Для этого необходимо сформировать JSON-структуру с полем method и корректно передать её в тело ответа.

Рассмотрим правильный пример кода для HTTP-сервиса 1С:


// Формируем структуру ответа согласно спецификации Telegram API
СтруктураОтвета = Новый Структура;
СтруктураОтвета.Вставить("method", "sendMessage");
СтруктураОтвета.Вставить("chat_id", Формат(Результат.message.chat.id, "ЧГ=0"));
СтруктураОтвета.Вставить("text", "<b>Привет!</b> Ответ сформирован в вебхуке.");
СтруктураОтвета.Вставить("parse_mode", "HTML");

// Сериализуем структуру в строку JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураОтвета);
СтрокаJSON = ЗаписьJSON.Закрыть();

// Формируем HTTP-ответ сервера
Ответ = Новый HTTPСервисОтвет(200);    
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8);

Возврат Ответ;

Важные ограничения прямого ответа:

  1. В рамках одного HTTP-ответа можно выполнить только одно действие (один метод Telegram API).
  2. Вы не получите от Telegram подтверждения доставки сообщения (объект Result не возвращается).
  3. Если обработка в 1С займет много времени, Telegram разорвет соединение по таймауту и начнет отправлять повторные вебхуки.

Способ 2. Раздельная обработка через HTTPСоединение (Рекомендуемый подход)

Для обеспечения стабильной работы ботов рекомендуется разделять получение входящего сообщения и отправку ответа. При получении запроса HTTP-сервис 1С мгновенно возвращает пустой ответ с кодом 200 OK, подтверждая приём. После этого 1С отправляет самостоятельный HTTP-запрос к API Telegram с помощью объекта HTTPСоединение.

Проанализируем процесс отправки исходящего запроса из 1С:


ТокенБота = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz";
ИдентификаторЧата = Формат(Результат.message.chat.id, "ЧГ=0");
ТекстСообщения = "Здравствуйте! Ваше сообщение принято в обработку.";

// Формируем ресурс запроса
Ресурс = "bot" + ТокенБота + "/sendMessage?chat_id=" + ИдентификаторЧата + "&text=" + КодироватьСтроку(ТекстСообщения, СпособКодированияСтроки.URLКодирование) + "&parse_mode=HTML";

Запрос = Новый HTTPЗапрос(Ресурс);
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();

// Подключаемся к серверу Telegram
Соединение = Новый HTTPСоединение("api.telegram.org", 443,,,, 10, ЗащищенноеСоединение);

Попытка
    ОтветСервера = Соединение.Получить(Запрос);
    КодСостояния = ОтветСервера.КодСостояния;
    СтрокаОтвета = ОтветСервера.ПолучитьТелоКакСтроку();
Исключение
    ЗаписьЖурналаРегистрации("TelegramBot", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;

А в самом HTTP-сервисе вебхука достаточно вернуть пустой успешный ответ:


Ответ = Новый HTTPСервисОтвет(200);
Возврат Ответ;

Архитектурные рекомендации по интеграции с Telegram

Разберем основные правила создания отказоустойчивых вебхуков в 1С:

  1. Использование фоновых заданий: Если логика обработки сообщения требует длительных операций (поиск данных в базе, проведение документов, построение отчетов), запускайте её асинхронно через ФоновыеЗадания.Выполнить(), предварительно вернув Telegram код 200 OK.
  2. Избегайте повторных вызовов: Если 1С не ответит за несколько секунд, Telegram решит, что сервис недоступен, и начнет дублировать входящие запросы. Это может привести к зацикливанию и повторным отправкам сообщений пользователям.
  3. Проверяйте кодировку: Всегда явно указывайте кодировку UTF-8 при работе с кириллическими текстами и экранируйте спецсимволы при формировании параметров URL.
← На главную