SMeet Bot API
Мини-приложения
Мини-приложение является веб-страницей автора бота, которая открывается внутри SMeet в окне поверх чата с ботом. Бот открывает её кнопкой, а форма, которую человек отправил из неё, приходит боту событием в той же очереди, что и сообщения.
Что такое мини-приложение#
У бота может быть одно мини-приложение. Владелец создаёт его в «Моих ботах» (экран открывает SMeet BotFather), указывает адрес рабочей и тестовой версии на своём HTTPS-сервере и отправляет на проверку; в рабочей среде работает только проверенная конфигурация. Перед каждым запуском SMeet показывает человеку, кто сделал мини-приложение и что оно получит, а перед каждой формой, которую оно отправляет боту, просит человека подтвердить отправку.
Страница и её сервер принадлежат автору. Программе бота не нужно их обслуживать: она получает то, что отправил человек, и отвечает в чате, как на любое сообщение.
Страница, вход человека, сервер автора и публикация описаны в документации SMeet Mini Apps: SDK, Вход, Ваш сервер и Публикация. Здесь описано то, что видит бот.
getMe сообщает, работают ли на этом сервере мини-приложения, и описывает мини-приложение бота:
{
"capabilities": ["chat_context", "access_revisions", "message_revisions", "initiator_conditions",
"strict_conditions", "mini_apps"],
"mini_app": {"id": "1000", "status": "active", "published": true}
}mini_appsвcapabilitiesозначает, что кнопкаmini_appи событиеmini_app_submissionсейчас работают на этом сервере. Если значения нет (старый сервер или мини-приложения выключены на платформе), отправляйте тот же текст без кнопки.mini_appесть, пока у бота есть мини-приложение.statusравенactive,paused_by_ownerилиblocked_by_admin;publishedговорит, работает ли проверенная конфигурация.idсовпадает сapp_idотправок этого бота.
Кнопка mini_app#
Кнопка с mini_app открывает мини-приложение бота, а не отправляет боту нажатие:
{
"chat_id": "70051",
"text": "Заполните форму заявки. Она открывается в SMeet: нажмите кнопку ниже.",
"reply_markup": {
"inline_keyboard": [
[{"text": "Открыть форму", "mini_app": {"start_param": "vpn-access"}}],
[{"text": "Помощь", "callback_data": "help"}]
]
}
}- У кнопки ровно одно из полей
callback_data,urlиmini_app.mini_appявляется объектом;start_paramнеобязателен, до 64 символов изA-Z a-z 0-9 _ -, и передаётся мини-приложению при открытии. Пустое значение означает, что параметра нет. - Только в личном чате бота, у которого есть мини-приложение, и не удалённое. В группе, теме или канале, а также у бота без мини-приложения sendMessage, editMessageText, sendPhoto и sendDocument отвечают
400 INVALID_REQUESTс"field": "reply_markup"и"reason": "mini_app_not_configured". Неверныйstart_paramполучаетINVALID_REQUESTс"field": "reply_markup"и безreason. - Кнопка открывает только опубликованную конфигурацию. Пока её нет, а также пока мини-приложение приостановлено или заблокировано, человек видит, что оно недоступно; кнопка остаётся в чате.
- О нажатии бот не узнаёт. Результат вызова показывает кнопку в том виде, в каком вы её написали, только пустой
start_paramвозвращается как отсутствующий. - Приложения без поддержки мини-приложений (SMeet для Android, приложение для компьютера и старые версии веб-приложения и SMeet для iOS) показывают кнопку неактивной и ничего не объясняют. Напишите в тексте, где открывается форма, как в примере.
Ссылка на мини-приложение#
То же окно открывается по ссылке на профиль бота с startapp: https://messenger.scrile.com/u/<bot_username>?startapp=<param>, где param подчиняется правилу start_param и может быть пустым. Человеку, который открыл ссылку, не запустив бота, предлагается запустить бота и открыть мини-приложение одним действием.
Событие mini_app_submission#
Когда человек подтверждает форму, бот получает:
{
"update_id": "4380",
"event_id": "2c7a1e94-3b6f-4d1a-8e2b-6f0c9d3a5b17",
"type": "mini_app_submission",
"date": "2026-10-10T12:00:00Z",
"mini_app_submission": {
"id": "6f1c9a2e-8a8f-4d6b-9a4e-6d2f0a3b7c11",
"app_id": "1000",
"environment": "production",
"client_request_id": "f3b0c9e2-form-1",
"from": {"id": "103", "display_name": "Дмитрий", "username": "dmitry", "is_bot": false},
"chat": {"id": "5501", "type": "private", "access_revision": "1088"},
"data": {"subject": "VPN", "priority": "high"},
"date": "2026-10-10T12:00:00Z"
}
}app_id,environment,fromиchatопределяет SMeet: страница не может их выбрать.from.idозначает того же человека, чтоfrom.idего сообщений, аchat.idявляется вашим личным чатом с ним.dataсодержит форму ровно в том виде, в каком её отправила страница: JSON-объект до 16 КиБ. Проверяйте его так же, как любой ввод людей.- Одна отправка даёт одно событие. Страница называет каждую форму своим
requestId, который приходит какclient_request_id; когда страница отправляет ту же форму снова (после сетевой ошибки, перезагрузки, из второго окна), SMeet возвращает ту же отправку и второго события не пишет. Свою работу защищайте от повторов поevent_id, как для любого события (Защита от повторов). idобозначает отправку так, как её знают приложение человека и мини-приложение.- Отправки приходят через getUpdates или ваш webhook в порядке очереди, с теми же подтверждением, списком FAILED и сроком хранения 7 дней, что и любое событие (Получение событий).
Ответ человеку#
Отвечайте в chat.id. chat.access_revision отправки является версией диалога на момент, когда человек открыл мини-приложение; передайте её как expected_access_revision, а ключ постройте из события:
POST /bot-api/v1/sendMessage HTTP/1.1
Host: messenger.scrile.com
Authorization: Bearer sbt1_EXAMPLE_REPLACE_WITH_YOUR_TOKEN
Idempotency-Key: 2c7a1e94-3b6f-4d1a-8e2b-6f0c9d3a5b17:reply
Content-Type: application/json
{"chat_id": "5501", "text": "Заявка SM-1042 создана. Ответим здесь.",
"expected_access_revision": "1088"}403 BOT_STOPPED_OR_BLOCKED: человек остановил или заблокировал бота.409 ACCESS_REVISION_CONFLICT: диалог изменился после отправки формы (например, Stop и снова Start). Оба ответа окончательны для этого ответа: не повторяйте его, а если работа важна, дождитесь, когда человек вернётся (Условные запросы).- Сервер без
access_revisionsвcapabilitiesусловие не проверяет: старый сервер пропускает параметр и выполняет действие без условия, а сервер 1.2.0 с выключенными условиями отклоняет вызов с400 INVALID_REQUESTи"field": "expected_access_revision". Передавайте условие, только когда возможность есть в списке (Возможности сервера, правило 1). - Человек мог отозвать доступ мини-приложения через его меню. Тогда отправки, которые бот ещё не получил, отменяются, а сам диалог остаётся: на уже полученное бот может ответить.
Когда отправка отменяется#
Отправка, которая ещё не дошла до бота, отменяется, и программа на long polling видит её в skipped с причиной cancelled, когда:
| Что произошло | Что отменяется |
|---|---|
| Человек остановил или заблокировал бота либо вышел из пространства бота | Как любое событие этого чата |
| Человек выбрал «Отозвать доступ» в меню мини-приложения | Ожидающие и FAILED отправки этого диалога |
| Владелец удалил мини-приложение | Ожидающие и FAILED отправки этого мини-приложения |
| Платформа заблокировала мини-приложение или все мини-приложения его владельца | Ожидающие и FAILED отправки этого мини-приложения |
| Организация выключила работу ботов | Сразу все ожидающие и FAILED события бота (Эксплуатация) |
| Организация выключила мини-приложения | В момент, когда SMeet собирается передать отправку боту |
| Тестовая отправка, отправитель которой больше не владелец, не принявший приглашение тестировщик и не проверяющий | В момент, когда SMeet собирается передать отправку боту |
Те же проверки выполняются, когда владелец повторяет FAILED-отправку: отправка, которая больше не может дойти до бота, отменяется вместо повтора. Пауза владельцем, техническая пауза платформы, закрытое окно и истёкший вход страницы ничего не отменяют; отправка ждёт в очереди, как и другие события.
Что видит человек#
Страница мини-приложения может спросить у SMeet, в каком состоянии её отправка:
| Состояние | Значит |
|---|---|
pending | В очереди бота, ещё не подтверждена |
delivered | Бот подтвердил её: offset long polling за ней или ответ 2xx вашего webhook |
failed | Она в списке FAILED у владельца |
cancelled | Она отменена до доставки, или владелец её пропустил |
expired | Её не подтвердили за 7 дней, или она старше этого срока |
Поэтому подтверждайте отправку, только когда она сохранена у вас: с этого момента страница может сказать человеку «доставлено».
Тестовая среда#
"environment": "test" приходит из тестового адреса мини-приложения, который открывают только владелец, тестировщики, принявшие приглашение, и проверяющие открытой заявки. Рабочая и тестовая среды никогда не делят отправку, даже с одинаковым requestId. Не смешивайте тестовые отправки с настоящей работой: тестовая форма не должна создавать настоящую заявку.