При разработке ботов для Telegram на базе 1С:Предприятие часто возникает необходимость настроить получение входящих сообщений (обновлений) через вебхуки (Webhook). Платформа 1С отлично справляется с ролью бэкенда через публикацию HTTP-сервисов. Однако на этапе подключения мы часто сталкиваемся с тем, что вебхук регистрируется успешно, но сообщения от бота не приходят.
Если мы проверим статус вебхука (например, через метод Telegram API getWebhookInfo), то можем увидеть следующую ошибку:
{
"ok": true,
"result": {
"url": "наш URL",
"has_custom_certificate": false,
"pending_update_count": 22,
"last_error_date": 1638516963,
"last_error_message": "Wrong response from the webhook: 401 Unauthorized",
"max_connections": 40
}
}
Эта ошибка означает, что сервер Telegram смог достучаться до нашего веб-сервера (Apache или IIS), но конечная точка (база 1С) отклонила запрос, потребовав авторизацию. Проанализируем ситуацию и разберем несколько способов решения этой проблемы.
Если при попытке отправить POST-запрос через Postman или браузер на адрес нашего HTTP-сервиса мы видим окно ввода логина и пароля, а в заголовках ответа присутствует строка Basic realm=1C:Enterprise, это однозначно указывает на то, что авторизацию запрашивает сама платформа 1С, а не веб-сервер.
Проблема кроется в том, что Telegram при отправке вебхука не умеет передавать стандартные заголовки базовой авторизации (например, Authorization: Basic ...). Telegram просто отправляет POST-запрос с JSON-данными. Следовательно, нам нужно настроить 1С так, чтобы она принимала эти запросы без явного окна авторизации, но при этом сохранялась безопасность. Рассмотрим основные способы решения.
Самый распространенный подход — это создание специального системного пользователя в конфигурации 1С и «жесткая» прописка его реквизитов в файле публикации веб-сервера default.vrd. В этом случае все внешние запросы будут автоматически авторизоваться под этим пользователем.
Разберем по шагам, что нужно сделать:
tg_webhook_user).Теперь отредактируем файл default.vrd. Нам нужно добавить логин и пароль в строку соединения с базой (атрибут ib). Также иногда помогает добавление параметра authentication="Standard".
<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
base="/mybase"
ib="Srvr=MyServer;Ref=MyBase;Usr=tg_webhook_user;Pwd=MySecretPassword;"
authentication="Standard">
<httpServices>
<publish name="tg_service" rootUrl="tg" enable="true"/>
</httpServices>
</point>
После сохранения файла обязательно перезапустите веб-сервер (Apache или IIS). Теперь 1С не будет просить авторизацию у Telegram, а сразу выполнит код под указанным пользователем.
Если по каким-то причинам изменение default.vrd не подходит, мы можем прокинуть Basic-авторизацию прямо в URL при регистрации вебхука в Telegram. Сервер Telegram поддерживает такой синтаксис.
Формат ссылки для метода setWebhook будет выглядеть следующим образом:
https://логин:пароль@адрес_сервера/имя_базы/hs/имя_сервиса/
Важное замечание: Современные версии веб-серверов (особенно Apache) могут вырезать такие данные из URL в целях безопасности. Поэтому данный метод считается устаревшим и менее надежным по сравнению с настройкой default.vrd.
Рассмотрим более современный и безопасный метод, который предоставляет сам Telegram. Это использование секретного токена. В данном случае мы делаем нашу точку в 1С публичной (через default.vrd, как описано в первом способе), но саму верификацию запроса осуществляем внутри кода 1С.
При регистрации вебхука через метод setWebhook мы передаем дополнительный параметр secret_token (это может быть любая придуманная вами строка от 1 до 256 символов).
После этого Telegram будет прикреплять этот токен к каждому POST-запросу в виде специального заголовка: X-Telegram-Bot-Api-Secret-Token.
Посмотрим на пример того, как это обрабатывается в модуле HTTP-сервиса 1С:
Функция ОбработатьВходящийЗапрос(Запрос)
// Получаем токен из заголовков запроса
СекретныйТокен = Запрос.Заголовки.Получить("X-Telegram-Bot-Api-Secret-Token");
// Сверяем с нашим токеном (его лучше хранить в константах)
Если СекретныйТокен <> "МойСуперСекретныйТокен123" Тогда
// Если токен не совпал или его нет, возвращаем ошибку 403 Forbidden
Ответ = Новый HTTPСервисОтвет(403);
Возврат Ответ;
КонецЕсли;
// Если токен верный, продолжаем обработку тела запроса
ТелоСтрока = Запрос.ПолучитьТелоКакСтроку();
// ... логика разбора JSON и ответа ...
Возврат Новый HTTPСервисОтвет(200);
КонецФункции
Этот способ гарантирует, что даже если кто-то узнает адрес вашего вебхука, он не сможет выполнить код в 1С, так как не знает секретного токена.
Часто разработчики для тестирования вебхуков на локальной машине используют сервис ngrok. Проанализируем возможные подводные камни при такой архитектуре.
Во-первых, Apache имеет свойство «съедать» заголовок авторизации до того, как он доберется до платформы 1С. Если вы используете Basic-авторизацию, убедитесь, что в конфигурационном файле Apache (обычно это httpd.conf) прописана следующая директива:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
Во-вторых, обратите внимание на переадресацию портов. Убедитесь, что ngrok корректно направляет трафик на нужный порт вашего веб-сервера. Если вы настроили SSL локально на Apache, трафик с ngrok должен идти на HTTPS-порт, иначе может возникнуть бесконечный цикл редиректов или сброс сессии, что также приведет к тому, что вебхук не сработает.
Мы подробно разобрали, почему возникает ошибка 401 Unauthorized при работе Telegram-бота с 1С. Подведем итоги совместной работы:
default.vrd.X-Telegram-Bot-Api-Secret-Token и проверять его внутри функции HTTP-сервиса 1С.Выполнив эти шаги, вы настроите стабильный и безопасный канал связи между серверами Telegram и вашей базой 1С:Предприятие.