SMeetBot API

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 (Уведомления владельцу).

Диагностика очереди#

JSON
{
  "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_offsetLong polling: позиция на сервере. Сравните её с тем, что сохранила программа.
leaseLong polling: кто сейчас держит аренду. Если поля нет, никто не опрашивает. Неожиданный consumer_id означает, что работает другая копия.
webhookРежим webhook: state, next_attempt_date и last_error (Проблемы webhook).
maintenancetrue во время технической паузы платформы.

Если бот молчит#

  1. Запущена ли программа? В её логе должна быть строка Running as @<адрес> и не должно быть ошибок.
  2. Работает ли токен? Вызовите getMe с этим токеном. 401 INVALID_TOKEN означает, что токен отозван или скопирован с ошибкой: выпустите новый в «Моих ботах».
  3. Работает ли бот? status в getMe: paused_by_owner снимается командой /resume в BotFather; suspended_by_admin означает, что платформа приостановила бота или владелец вышел из организации: обратитесь в поддержку.
  4. Тот ли режим? delivery_mode в getMe. Программа long polling при боте в режиме webhook получает 409 DELIVERY_MODE_CONFLICT: переключите бота на long polling или запустите приёмник webhook.
  5. Не получает ли события другая копия? lease.consumer_id в getDeliveryInfo. CONSUMER_CONFLICT, который не проходит, означает, что аренду держит вторая копия (Зависшая аренда).
  6. Нажал ли человек «Начать»? До нажатия «Начать» и после остановки до бота ничего не доходит. В организации человек должен оставаться её участником.
  7. Это платформа или организация? 503 BOTS_MAINTENANCE означает техническую паузу: подождите. 403 SPACE_BOTS_DISABLED означает, что организация выключила ботов.
  8. Webhook: state и last_error в getWebhookInfo (Проблемы webhook) и список FAILED. paused означает, что endpoint дал ответ, который можете исправить только вы; исправьте и нажмите Возобновить доставку в «Моих ботах».
  9. Не уходят ответы: 403 BOT_STOPPED_OR_BLOCKED (человек остановил бота), 400 INVALID_REQUEST с error.field, 429 RATE_LIMITED. Сохраните request_id неудачного вызова.

Ошибки по HTTP-статусам#

СтатусКодЧто это значитЧто делать
401INVALID_TOKENТокена нет, он скопирован с ошибкой или отозван, либо бот удалён.Выпустите новый токен в «Моих ботах». Со старым не повторяйте.
403BOT_SUSPENDEDВладелец поставил бота на паузу, платформа его приостановила или владелец вышел из организации./resume или обращение в поддержку. Повторы не помогут.
403SPACE_BOTS_DISABLEDОрганизация выключила ботов.Остановитесь; обратитесь к администраторам организации.
403BOT_STOPPED_OR_BLOCKEDЧеловек остановил или заблокировал бота либо вышел из пространства.Больше не пишите в этот чат и удалите его подписки.
404BOT_NOT_FOUNDБот удалён, пока запрос был в пути.Остановитесь: токен больше не действует.
409CONSUMER_CONFLICTАренду держит другая копия, или long poll ещё ждёт.Подождите retry_after и спросите снова с теми же consumer_id, epoch и offset.
409DELIVERY_MODE_CONFLICTgetUpdates, когда бот в режиме webhook.Смените режим в «Моих ботах» или получайте события через webhook.
409CURSOR_BEHINDoffset меньше подтверждённой позиции.Продолжайте с confirmed_offset из ошибки.
409IDEMPOTENCY_CONFLICTКлюч уже использован с другими параметрами.Для новой операции нужен новый ключ.
409FILE_NOT_READYФайл ещё проверяется.Повторите после retry_after с тем же ключом.
413PAYLOAD_TOO_LARGEТело запроса или файл больше допустимого. limit называет наибольший допустимый размер в байтах; 413 от прокси перед API может прийти без него.Отправьте меньше; повтор того же тела не поможет.
429RATE_LIMITEDСлишком много запросов, в том числе от прокси для одного IP-адреса.Подождите retry_after, повторите с тем же ключом.
429QUOTA_EXCEEDEDСуточный объём загрузок исчерпан.Подождите retry_after, до полуночи UTC.
503TEMPORARILY_UNAVAILABLEВременный сбой.Повторите после retry_after с тем же ключом, увеличивая паузу.
503BOTS_MAINTENANCEТехническая пауза платформы.Повторите после retry_after с тем же ключом и тем же offset (ниже).

Полный список в таблице кодов ошибок.

Проблемы webhook#

getWebhookInfo показывает состояние вашего endpoint:

stateЗначение
activeДоставки идут.
pausedEndpoint дал ответ, который можете исправить только вы, и доставка ждёт вас; 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_403Endpoint отказал в доставке.Пауза до возобновления вами.Секрет, которым программа проверяет подпись.
HTTP_404, HTTP_410По этому адресу ничего нет.Пауза до возобновления вами.Адрес webhook и маршрутизацию.
REDIRECT_NOT_FOLLOWEDEndpoint ответил перенаправлением.Пауза до возобновления вами.Сохраните в «Моих ботах» конечный адрес.
TLS_CERTIFICATE_ERRORСертификат недействителен для этого адреса.Пауза до возобновления вами.Срок действия, имя в сертификате, цепочку.
ADDRESS_FORBIDDENИмя теперь указывает только на частные или зарезервированные адреса.Пауза до возобновления вами.Публичные DNS-записи хоста.
HTTP_<статус> другого статуса, например HTTP_405Ответ, который webhook не принимает.Пауза до возобновления вами.Отвечайте 2xx, а для отклонённого события 400, 413 или 422.
HTTP_400, HTTP_413, HTTP_422Программа отклонила это событие.Переводит его в FAILED и идёт дальше.Лог программы, список FAILED.
HTTP_429Endpoint попросил замедлиться.Ждёт 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 API503 BOTS_MAINTENANCE с retry_after403 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.