Ответ на Telegram Webhook: тело HTTP-ответа или отдельный sendMessage?
Telegram позволяет вызвать метод Bot API, например sendMessage, прямо в HTTP-ответе на webhook. Однако официальная документация предупреждает: узнать, завершился ли такой вызов успешно, и получить его результат нельзя. Если нужен идентификатор отправленного сообщения или обработка ошибки API, делайте отдельный запрос. Ответ 200 OK, подтверждающий получение обновления, не равнозначен успешной отправке сообщения в чат.
Главное
- Подтверждение HTTP-доставки, результат метода API и прочтение сообщения человеком — разные события.
- Вызов метода в теле ответа сокращает число запросов, но не дает получить результат.
- Отдельный
sendMessageподходит для задач, которым нужны идентификатор сообщения и журнал отправки. - У UnifyPort другой контракт: тело ответа на webhook отбрасывается. Для отправки нужен отдельный API-вызов.
Что можно передать в ответе на Telegram webhook
Официальная документация Bot API описывает специальный механизм: параметры метода передаются в ответе на webhook с типом application/json, application/x-www-form-urlencoded или multipart/form-data, а имя метода — в method.
Например, приложение может вернуть JSON с method: sendMessage, соответствующими chat_id и text. Это параметры вызова метода, а не структура входящего Update. Произвольный текст в HTTP-ответе сам по себе также не становится сообщением в чате.
Официальный FAQ прямо указывает компромисс: запросов меньше, но проверить успех вызова и получить результат невозможно. Запись об успешном HTTP-ответе в журнале сервера не заменяет отсутствующий результат отправки.
Здесь предполагается, что бот уже получает обновления. Если вы еще выбираете тип учетной записи и способ приема, начните со сравнения Telegram Bot API webhook и унифицированного входящего webhook. Выбор между опросом и webhook — не тот же вопрос, что выбор способа ответа пользователю.
Вызов в HTTP-ответе или отдельный sendMessage
| Критерий | Метод в ответе на webhook | Отдельный запрос к Bot API |
|---|---|---|
| Формат | Тело ответа содержит method и параметры | Приложение отдельно вызывает метод |
| Результат метода | Недоступен приложению | Можно проверить JSON от Bot API |
| Идентификатор отправленного сообщения | Этот механизм его не возвращает | Успешный sendMessage возвращает Message |
| Обработка ошибок | Нет результата для выбора ветки обработки | Можно проверить возвращенные ok, description, error_code |
| Подходящая задача | Простой ответ без зависимости от результата | Журналирование отправок, фоновые задачи, последующие действия |
Официальное описание ответов и sendMessage определяет поле ok: успешный результат находится в result, при неудаче возвращается информация об ошибке. Метод sendMessage при успехе возвращает отправленный Message.
Успех метода не доказывает, что человек прочитал сообщение. Кроме того, отдельный запрос тоже может оставить неопределенность: удаленный сервис обработал его, но клиент не получил ответ.
Гипотетический пример: бот отправляет короткую справку, и дальнейшим действиям не нужен идентификатор сообщения. Вызова в HTTP-ответе может быть достаточно. Если же система поддержки должна связать исходящее сообщение с заявкой или выбрать действие по причине отказа API, лучше сделать отдельный вызов и сохранить реальный результат.
Разделяйте подтверждение приема и результат отправки
Для длительной обработки рекомендуем следующую архитектуру приложения. Это рекомендация, а не дополнительная гарантия Telegram:
- Проверить источник webhook и надежно сохранить обновление.
- Подтвердить прием, не дожидаясь AI, CRM или отправки сообщения.
- Вызвать Bot API отдельно из фонового обработчика.
- Записать полученный результат или ошибку в локальную задачу.
- Считать сетевой тайм-аут неопределенным результатом, а не доказанным отказом отправки.
Устраняйте дубликаты обновлений в пределах конкретного бота. Повторная доставка должна находить существующую задачу, а не создавать новый ответ. Назначьте единственного исполнителя отправки: не встраивайте ответ в webhook одновременно с постановкой того же сообщения в очередь.
Telegram документирует повторные попытки неуспешной доставки webhook при статусе вне 2XY. Это повторная доставка входящего обновления, а не замена учета результатов исходящих вызовов. Если обновления приходят, но ответов нет, сначала проверьте журнал отправок, а не меняйте конфигурацию webhook. Руководство по диагностике getWebhookInfo объясняет, почему состояние доставки не подтверждает завершение бизнес-задачи.
Тело ответа UnifyPort не является командой отправки
Неофициальный интерфейс UnifyPort не использует Telegram-механизм вызова метода в ответе. Согласно документации доставки webhook, любой 2xx подтверждает доставку, а тело ответа читается и отбрасывается. JSON с method: sendMessage не вызовет отправку через этот контракт.
Для подключенного аккаунта обмена сообщениями принимайте message.received, проверяйте подпись, сохраняйте событие и затем подтверждайте доставку. При настроенном signing_secret заголовок X-Device-Signature содержит HMAC-SHA256 от X-Device-Timestamp, точки и исходных байтов тела запроса.
Отправляйте сообщения отдельным POST /v1/messages с аутентификацией через X-Api-Key. Справочник текстовых сообщений определяет account_id, to.id, to.type, message.type и message.text. В примере ответа есть data.status: accepted; это не уведомление о прочтении. Для автоматических ответов проверяйте также data.message.direction, чтобы наблюдаемое исходящее сообщение не запускало цикл ответов самому себе.
Если требуется именно бот, оставайтесь на официальном Bot API. Подключение аккаунта через UnifyPort — другая интеграция, а не способ восстановить недоступный результат встроенного Bot API-вызова. REST API для чтения истории сообщений и гарантированного повторного воспроизведения пропущенных событий также нет: сохраняйте нужные события при получении.
Частые вопросы
Можно вернуть JSON sendMessage вместо отдельного API-запроса?
Да, для Telegram Bot API webhook и в документированном формате ответа с методом. Но проверить успех такого вызова и получить результат нельзя.
Ответ 200 OK означает, что сообщение отправлено?
Нет. Он подтверждает доставку webhook. Результат исходящего метода — отдельный факт.
Нужно ли автоматически повторять отдельный API-вызов после тайм-аута?
Не без проверки. Удаленная отправка могла завершиться до потери ответа. Сохраните неопределенный статус и примените явно заданную процедуру сверки или повторной попытки.
Можно поместить ответ пользователю в тело webhook-ответа UnifyPort?
Тело отбрасывается. Используйте отдельный POST /v1/messages.
Следующий шаг и источники
Выберите способ отправки по тому, нужен ли вам наблюдаемый результат. Для подключенного аккаунта начните с контракта API отправки текста.
Официальные источники проверены 2026-09-20:
Превратите интеграцию сообщений в стабильный продуктовый pipeline.
Начните с отправки через единый API, затем возвращайте входящие сообщения в бизнес-систему стандартными событиями.