Bot Service

Как это работает

Сервис стоит на зарубежном сервере и работает посредником между Telegram и сайтами на RU-серверах, которые не могут достучаться до api.telegram.org напрямую.

  1. Каждый бот поллит Telegram (getUpdates). Полученные апдейты сначала записываются в очередь на диске, и только потом подтверждаются в Telegram, поэтому при перезапуске ничего не теряется.
  2. Очередь доставляется на сайт {web_url}{update_path} строго по порядку. Если сайт недоступен, сервис повторяет попытки с паузой до 5 минут и копит апдейты до 24 часов.
  3. Сайт отправляет сообщения через /api/v1/{bot_id}/..., сервис выполняет их в Telegram.

Апдейты на сайт

POST {web_url}{update_path}
X-Service-Token: {service_token бота}
X-Update-Id: 123456789
Content-Type: application/json

{ "bot_id": "sol-prod", "message": { ...объект message из Telegram... } }
{ "bot_id": "sol-prod", "callback_query": { ... } }

Ключ в теле совпадает с типом апдейта (message, callback_query, edited_message, my_chat_member и т.д.). Какие типы получать, задаётся в настройках бота. По умолчанию только message и callback_query, как раньше.

Как сервис понимает ответ сайта:

Dead-апдейты видны во вкладке «Очередь», их можно переотправить.

API для сайтов

Все запросы POST /api/v1/{bot_id}/... с заголовком X-Service-Token и JSON-телом. Без {bot_id} в пути запрос уходит боту default (старые клиенты).

ПутьТелоМетод Telegram
/messages/send{ chat_id, text, options }sendMessage
/messages/edit{ text, options: { chat_id, message_id, ... } }editMessageText
/messages/edit-reply-markup{ reply_markup, options: { chat_id, message_id } }editMessageReplyMarkup
/messages/delete{ chat_id, message_id }deleteMessage
/callback/answer{ callback_query_id, options }answerCallbackQuery
/commands/set{ commands: [{ command, description }] }setMyCommands
/raw{ method, params }любой метод
/bot/reload-token{ token }смена токена бота

Ответ: результат Telegram как есть (для /raw обёрнут в { ok: true, result }).

Ошибка Telegram: HTTP 502 и тело

{ "error": "ETELEGRAM: 403 Forbidden: bot was blocked by the user", "error_code": 403 }

При 429 от Telegram с коротким retry_after (до 5 с) сервис сам ждёт и повторяет один раз.

Пример

curl -X POST https://resolve.leden4ik.name/api/v1/sol-prod/messages/send \
  -H "X-Service-Token: $SECRET" -H "Content-Type: application/json" \
  -d '{"chat_id":123456,"text":"Привет","options":{"parse_mode":"HTML"}}'

Health-check

GET /healthz, без авторизации, для мониторинга (UptimeRobot и т.п.).

{
  "status": "ok",          // "degraded", если у какого-то бота проблемы
  "service": "bot",
  "polling": true,         // все включённые боты поллят
  "bots": [ { "id": "sol-prod", "polling": true, "healthy": true, "queue": 0 } ]
}

Настройки сервера (.env)

BOT_ADMIN_USER / BOT_ADMIN_PASSвход в панель, без них панель закрыта
BOT_PORT, BOT_HOSTпорт (3001) и адрес (127.0.0.1, сервис стоит за nginx)
DATA_DIRгде лежит база и бэкапы (./data)
QUEUE_MAX_AGE_HOURSсколько хранить недоставленные апдейты (24)
EVENTS_RETENTION_DAYSсколько хранить журнал (7)
PROXY_URLHTTP-прокси до Telegram, нужен пакет undici
TELEGRAM_API_URLсвой Bot API сервер вместо api.telegram.org