SMeet Bot API
Эксплуатация
За чем следить и что делать, если что-то пошло не так. Две ситуации, которые похожи, но различаются по сути, техническая пауза платформы и выключение ботов организацией, описаны в отдельных разделах.
Хранение секретов#
У бота два секрета: токен, с которым программа вызывает Bot API, и в режиме webhook секрет webhook, которым SMeet подписывает доставки.
- Храните их в переменных окружения или хранилище секретов. Файл
.envдолжен быть доступен для чтения только пользователю сервиса и никогда не попадать в git. - Передавайте токен только в заголовке
Authorization. Никогда не вставляйте его в URL, лог, чат, скриншот или обращение в поддержку. Примеры пишут в лог идентификаторы событий и чатов и коды ошибок, но не токен, секрет или текст сообщений. - SMeet показывает каждый секрет один раз и хранит только хэш токена и зашифрованную копию секрета webhook. API не возвращает ни один из них, а токен никогда не передаётся в ваш webhook.
- Смена токена: выпустите новый на защищённом экране «Моих ботов»; старый сразу перестаёт работать, поэтому немедленно впишите новый в программу и перезапустите её.
- Смена секрета webhook: сохраните webhook заново на экране «Подключение»; при каждом включении режима webhook создаётся новый секрет, который показывается один раз. Пока нового секрета нет в программе, доставки с новой подписью не проходят вашу проверку, ваш ответ
401приостанавливает доставку, и события ждут (Endpoint на паузе). Впишите новый секрет в программу, перезапустите её и нажмите Возобновить доставку; ничего не теряется. - Если секрет мог утечь, используйте экстренный сброс: новый токен, отобранная аренда long polling и, в режиме webhook, новый секрет webhook за один шаг.
Проверка состояния#
- getMe отвечает, даже когда бот на паузе и во время технической паузы платформы. Вызывайте его при запуске: он подтверждает токен и показывает
status(active,paused_by_owner,suspended_by_admin) иdelivery_mode. - getDeliveryInfo служит главным вызовом для мониторинга (Диагностика очереди). Он никогда не возвращает секреты и тоже отвечает во время технической паузы, с
"maintenance": true. - «Мои боты» и карточка бота в BotFather показывают один из четырёх статусов:
| Статус | Значение |
|---|---|
| Работает | Программа подключена, ничего не застряло. |
| Не подключён | Long polling: токена ещё нет или программа ещё ни разу не обращалась. Webhook: ещё ничего не доставлено и ничего не ждёт. |
| Ошибка доставки | Long polling: события ждут, а программа не обращалась 2 минуты. Webhook: доставка на паузе, пока вы её не возобновите, circuit breaker открыт или платформа выключила webhook. |
| Приостановлен | Владелец поставил бота на паузу, платформа его приостановила, владелец вышел из организации или организация выключила ботов. |
«Работает» означает только то, что программа подключена. О правильности её логики статус ничего не говорит, а webhook, который отклоняет события ответами 400, 413 или 422, из-за этого статуса ошибки не получает: следите за списком FAILED и failed_update_count. В режиме webhook SMeet BotFather ещё и пишет вам, когда доставка приостановлена или событие ушло в FAILED (Уведомления владельцу).
Диагностика очереди#
{
"ok": true,
"result": {
"mode": "polling",
"config_version": "3",
"pending_update_count": 12,
"failed_update_count": 1,
"oldest_pending_date": "2026-09-26T09:58:10Z",
"confirmed_offset": "1840",
"lease": {"consumer_id": "poller-host1", "epoch": "7", "expires_at": "2026-09-26T10:01:00Z"},
"webhook": {"url": "", "state": "none", "pending_update_count": 12, "max_connections": 1},
"maintenance": false,
"retention_seconds": 604800
}
}| Поле | На что смотреть |
|---|---|
pending_update_count | События, которые ждут подтверждения. Число растёт, если программа не работает или не подтверждает. При 10 000 событий или 50 МиБ очередь заполнена, и люди не могут писать боту. |
oldest_pending_date | Самое старое ожидающее событие. Если ему уже несколько минут, программа отстаёт; через 7 суток события истекают. |
failed_update_count | Размер списка FAILED; разберите его в «Моих ботах». |
confirmed_offset | Long polling: позиция на сервере. Сравните её с тем, что сохранила программа. |
lease | Long polling: кто сейчас держит аренду. Если поля нет, никто не опрашивает. Неожиданный consumer_id означает, что работает другая копия. |
webhook | Режим webhook: state, next_attempt_date и last_error (Проблемы webhook). |
maintenance | true во время технической паузы платформы. |
Если бот молчит#
- Запущена ли программа? В её логе должна быть строка
Running as @<адрес>и не должно быть ошибок. - Работает ли токен? Вызовите getMe с этим токеном.
401 INVALID_TOKENозначает, что токен отозван или скопирован с ошибкой: выпустите новый в «Моих ботах». - Работает ли бот?
statusв getMe:paused_by_ownerснимается командой/resumeв BotFather;suspended_by_adminозначает, что платформа приостановила бота или владелец вышел из организации: обратитесь в поддержку. - Тот ли режим?
delivery_modeв getMe. Программа long polling при боте в режиме webhook получает409 DELIVERY_MODE_CONFLICT: переключите бота на long polling или запустите приёмник webhook. - Не получает ли события другая копия?
lease.consumer_idв getDeliveryInfo.CONSUMER_CONFLICT, который не проходит, означает, что аренду держит вторая копия (Зависшая аренда). - Нажал ли человек «Начать»? До нажатия «Начать» и после остановки до бота ничего не доходит. В организации человек должен оставаться её участником.
- Это платформа или организация?
503 BOTS_MAINTENANCEозначает техническую паузу: подождите.403 SPACE_BOTS_DISABLEDозначает, что организация выключила ботов. - Webhook:
stateиlast_errorв getWebhookInfo (Проблемы webhook) и список FAILED.pausedозначает, что endpoint дал ответ, который можете исправить только вы; исправьте и нажмите Возобновить доставку в «Моих ботах». - Не уходят ответы:
403 BOT_STOPPED_OR_BLOCKED(человек остановил бота),400 INVALID_REQUESTсerror.field,429 RATE_LIMITED. Сохранитеrequest_idнеудачного вызова.
Ошибки по HTTP-статусам#
| Статус | Код | Что это значит | Что делать |
|---|---|---|---|
| 401 | INVALID_TOKEN | Токена нет, он скопирован с ошибкой или отозван, либо бот удалён. | Выпустите новый токен в «Моих ботах». Со старым не повторяйте. |
| 403 | BOT_SUSPENDED | Владелец поставил бота на паузу, платформа его приостановила или владелец вышел из организации. | /resume или обращение в поддержку. Повторы не помогут. |
| 403 | SPACE_BOTS_DISABLED | Организация выключила ботов. | Остановитесь; обратитесь к администраторам организации. |
| 403 | BOT_STOPPED_OR_BLOCKED | Человек остановил или заблокировал бота либо вышел из пространства. | Больше не пишите в этот чат и удалите его подписки. |
| 404 | BOT_NOT_FOUND | Бот удалён, пока запрос был в пути. | Остановитесь: токен больше не действует. |
| 409 | CONSUMER_CONFLICT | Аренду держит другая копия, или long poll ещё ждёт. | Подождите retry_after и спросите снова с теми же consumer_id, epoch и offset. |
| 409 | DELIVERY_MODE_CONFLICT | getUpdates, когда бот в режиме webhook. | Смените режим в «Моих ботах» или получайте события через webhook. |
| 409 | CURSOR_BEHIND | offset меньше подтверждённой позиции. | Продолжайте с confirmed_offset из ошибки. |
| 409 | IDEMPOTENCY_CONFLICT | Ключ уже использован с другими параметрами. | Для новой операции нужен новый ключ. |
| 409 | FILE_NOT_READY | Файл ещё проверяется. | Повторите после retry_after с тем же ключом. |
| 413 | PAYLOAD_TOO_LARGE | Тело запроса или файл больше допустимого. limit называет наибольший допустимый размер в байтах; 413 от прокси перед API может прийти без него. | Отправьте меньше; повтор того же тела не поможет. |
| 429 | RATE_LIMITED | Слишком много запросов, в том числе от прокси для одного IP-адреса. | Подождите retry_after, повторите с тем же ключом. |
| 429 | QUOTA_EXCEEDED | Суточный объём загрузок исчерпан. | Подождите retry_after, до полуночи UTC. |
| 503 | TEMPORARILY_UNAVAILABLE | Временный сбой. | Повторите после retry_after с тем же ключом, увеличивая паузу. |
| 503 | BOTS_MAINTENANCE | Техническая пауза платформы. | Повторите после retry_after с тем же ключом и тем же offset (ниже). |
Полный список в таблице кодов ошибок.
Проблемы webhook#
getWebhookInfo показывает состояние вашего endpoint:
state | Значение |
|---|---|
active | Доставки идут. |
paused | Endpoint дал ответ, который можете исправить только вы, и доставка ждёт вас; last_error называет причину. Исправьте и нажмите Возобновить доставку в «Моих ботах» (Endpoint на паузе). |
circuit_open | Три события подряд исчерпали бюджет ошибок; SMeet ждёт, затем делает пробу. next_attempt_date показывает следующую пробу (Circuit breaker). |
disabled_by_platform | Платформа выключила webhook этого бота. Очередь ждёт; переключитесь на long polling или обратитесь в поддержку. |
none | Бот в режиме long polling. |
next_attempt_date показывает и ожидание после неудачного соединения или ответа 429. last_error.code говорит, что случилось последним:
last_error.code | Что произошло | Что делает SMeet | Что проверить |
|---|---|---|---|
HTTP_401, HTTP_403 | Endpoint отказал в доставке. | Пауза до возобновления вами. | Секрет, которым программа проверяет подпись. |
HTTP_404, HTTP_410 | По этому адресу ничего нет. | Пауза до возобновления вами. | Адрес webhook и маршрутизацию. |
REDIRECT_NOT_FOLLOWED | Endpoint ответил перенаправлением. | Пауза до возобновления вами. | Сохраните в «Моих ботах» конечный адрес. |
TLS_CERTIFICATE_ERROR | Сертификат недействителен для этого адреса. | Пауза до возобновления вами. | Срок действия, имя в сертификате, цепочку. |
ADDRESS_FORBIDDEN | Имя теперь указывает только на частные или зарезервированные адреса. | Пауза до возобновления вами. | Публичные DNS-записи хоста. |
HTTP_<статус> другого статуса, например HTTP_405 | Ответ, который webhook не принимает. | Пауза до возобновления вами. | Отвечайте 2xx, а для отклонённого события 400, 413 или 422. |
HTTP_400, HTTP_413, HTTP_422 | Программа отклонила это событие. | Переводит его в FAILED и идёт дальше. | Лог программы, список FAILED. |
HTTP_429 | Endpoint попросил замедлиться. | Ждёт Retry-After. | Собственные ограничения частоты. |
HTTP_408, HTTP_5xx, например HTTP_503, TIMEOUT, NO_RESPONSE, IO_ERROR | Ошибка, нет ответа за 10 секунд или соединение оборвалось после отправки запроса. | Повторяет в пределах бюджета события. | Отвечайте быстрее: сохраните, ответьте 200, работайте потом. |
DNS_ERROR, CONNECT_ERROR, CONNECT_TIMEOUT, TLS_ERROR | Запрос не дошёл до программы. | Ждёт и повторяет, от 5 секунд до 5 минут. | Что имя разрешается, порт открыт, TLS работает. |
DISABLED_BY_PLATFORM | Платформа выключила webhook. | Ничего, пока платформа не разрешит. | Обратитесь в поддержку. |
Могут появиться новые коды; незнакомый код оценивайте по state, который приходит вместе с ним.
Техническая пауза: BOTS_MAINTENANCE#
Операторы SMeet могут приостановить всю платформу ботов, например на время отката выпуска или во время инцидента. Это пауза, а не отзыв разрешения: всё сохраняется.
Во время паузы:
- методы данных Bot API отвечают
503 BOTS_MAINTENANCEсretry_after(30 секунд) и тем же значением в заголовкеRetry-After; ожидающие long poll завершаются этой ошибкой; - getMe, getMyCommands, getDeliveryInfo и getWebhookInfo продолжают отвечать, а getDeliveryInfo показывает
"maintenance": true; - доставка через webhook, которая уже идёт, завершается и засчитывается; новые доставки и проверки файлов не начинаются;
- сообщения людей ботам не отправляются: приложение сообщает, что боты на техническом обслуживании, и оставляет текст в поле ввода;
- очередь, события в FAILED, ключи Idempotency-Key, offset, аренда long polling и разрешения Start сохраняются;
- остановка, блокировка, выход из пространства и удаления по-прежнему действуют и отменяют то, что должны отменять;
- срок хранения продолжает идти: событие, у которого 7 суток закончились во время паузы, истекает.
Что делает программа:
- ждёт
retry_afterи повторяет тот же запрос с тем же ключом и тем же offset; никогда не сбрасывает сохранённую позицию из-за этой ошибки; - после паузы getUpdates с теми же
consumer_id,epochиoffsetпродолжает в той же аренде. Если пауза длилась дольше аренды, вызов получает новую, и сохранённый offset всё равно подтверждает события, потому что аренду между тем никто не брал. Ничего не теряется; - приёмник webhook ничего не делает: доставки возобновятся сами, по порядку.
Клиент примеров делает ровно это: BOTS_MAINTENANCE входит в коды, которые smeet.py повторяет с тем же телом и ключом.
Организация отзывает разрешение#
Владелец или администратор организации может выключить работу ботов (Организации и доступ). Это решение о данных организации, а не техническая пауза, и оно отменяет:
- каждый бот организации получает
403 SPACE_BOTS_DISABLED, а люди видят, что боты в этой организации выключены; - все недоставленные события этих ботов отменяются, включая события в FAILED; повторить их нельзя, и они не вернутся, когда работу включат снова;
- чаты и разрешения Start сохраняются.
Что делает программа: прекращает вызовы в цикле (примеры завершаются с кодом 2 и сообщением) и обращается к администраторам организации. Когда работу снова включат, запустите программу: она получит только то, что происходит с этого момента, а отменённый диапазон придёт как пропуск с причиной cancelled.
| Техническая пауза | Организация отзывает разрешение | |
|---|---|---|
| Кто | Операторы SMeet | Владельцы или администраторы организации |
| Ответ Bot API | 503 BOTS_MAINTENANCE с retry_after | 403 SPACE_BOTS_DISABLED |
| Ожидающие события | Сохраняются и доставляются потом | Отменяются навсегда |
| События в FAILED | Сохраняются, их можно повторить потом | Отменяются, повторить нельзя |
| Idempotency-Key и offset | Сохраняются | Сохраняются, но доставлять уже нечего |
| Ваша программа | Повторяет тот же запрос | Останавливается |
Пауза и приостановка#
| Ситуация | Bot API | Ожидающие события | Как заканчивается |
|---|---|---|---|
| Владелец поставил бота на паузу | 403 BOT_SUSPENDED; getMe показывает paused_by_owner | Сохраняются и доставляются после /resume в пределах 7 суток | /resume в BotFather |
| Платформа приостановила бота | 403 BOT_SUSPENDED; getMe показывает suspended_by_admin | Отменяются; FAILED сохраняются | Платформа снимает приостановку |
| Владелец вышел из организации или его аккаунт отключён | 403 BOT_SUSPENDED; getMe показывает suspended_by_admin | Отменяются; FAILED сохраняются | Поддержка платформы возвращает бота владельцу |
Зависшая аренда#
Когда программа long polling падает, её аренда живёт ещё до 60 секунд после последнего ответа сервера этой программе, а оставленный ею long poll считается до конца своего тайм-аута. Перезапущенная программа, которая сохранила epoch, продолжает сразу; потерявшая её получает CONSUMER_CONFLICT, пока аренда не истечёт. getDeliveryInfo показывает держателя в поле lease.
Если вы уверены, что другой копии нет, нажмите Сбросить подключение на экране «Подключение» в «Моих ботах». Старая epoch после этого становится чужой: копия, которая ещё передаёт её, ничего ею не подтвердит, а неподтверждённые ею события придут снова. Следующий вызов получает новую аренду с подтверждённой позиции.
Помощь#
Напишите на support@scrile.com: адрес бота, время, метод и request_id неудачного вызова (он есть в теле каждой ошибки и в заголовке X-Request-Id). Никогда не присылайте токен или секрет webhook.