Для разработчиков

Обработка форм

Открытие представления

Чтобы открыть модальное окно с представлением, ваше приложение должно иметь действительный, неистекший trigger_id. Это требование связано с тем, чтобы приложение открывало модальное окно только с разрешения пользователя и делало это быстро.

Для открытия представления используйте метод POSTОткрытие представления.

С целью поддержания интерактивности и отзывчивости интерфейсов Пачки, срок жизни trigger_id ограничен и составляет 3 секунды

Получение результатов

После заполнения пользователем полей в представлении и отправки их, в ваше приложение отправляется исходящий вебхук. Вебхук будет отправлен на Webhook URL, который вы указали в настройках бота во вкладке «Исходящий Webhook», от имени которого было отправлено сообщение с кнопкой (нажатие на которую и вызвало открытие представления).

Задача вашего приложения - обработать входяший вебхук в короткое время и дать ответ. Это может быть как успех и команда на закрытие представления пользователю в интерфейсе Пачки, так и набор ошибок, которые необходио отобразить пользователю в представлении.

Ваше приложение должно дать ответ на вебхук в течение 3 секунд. В ином случае, пользователь получит ошибку отправки в интерфейсе Пачки. Все значения полей будут сохранены и пользователь повторит попытку отправки формы.

Так формы работают в основном сценарии. Исключение — бот, у которого адрес исходящего вебхука не задан вовсе: для него есть отдельный способ ответить, он описан в конце страницы.

Вебхук содержит информацию, которая была заложена при открытии представления пользователю (такие поля, как private_metadata и callback_id), и данные заполненных полей представления.

Каждый исходящий вебхук защищён с помощью подписи, основанной на хешировании содержимого. Подробнее об этом — в разделе Безопасность.

ViewSubmitWebhookPayloadobject
Пример вебхука о заполнении формы
{    "type": "view",    "event": "submit",    "private_metadata": "{\"timeoff_id\":4378}",    "callback_id": "timeoff_request_form",    "user_id": 1235523,    "view_id": "01KAJZ2XDSS2S3DSW9EXJZ0TBV",    "submit_id": "791a056b-006c-49dd-834b-c633fde52fe8",    "data": {        "date_start": "2025-07-01",        "date_end": "2025-07-14",        "request_doc": [            {                "name": "request.png",                "size": 19153,                "url": "<url>"            }        ],        "accessibility": "phone_only",        "info": "Поеду в сибирь на свадьбу лучшего друга",        "newsletters": ["new_tasks", "project_updates"],        "team": "success",        "time": "22:00"    },    "webhook_timestamp": 1755075544}

Значение блока file_input приходит массивом объектов с полями name, size и url. Расширение файла проверяйте у себя: список filetypes подставляется в фильтр окна выбора файла.

Скачивайте файл сразу после получения вебхука. Прямая ссылка действует 2 часа, а сам файл хранится сутки с момента отправки формы, после чего удаляется. Если файл нужен дольше, скачайте его по ссылке и сохраните у себя.

Закрытие и отображение ошибок

После заполнения пользователем полей в представлении в приложение будет отправлен исходящий вебхук. В этот момент вы можете сохранить полученные значения или провести валидацию правильности заполнения полей и отправить пользователю ошибки.

Вам необходимо оперативно ответить на вебхук (кодом 200 или 400 со списком ошибок). В ином случае, пользователь получит ошибку отправки в интерфейсе Пачки. Все значения полей будут сохранены и пользователь повторит попытку отправки формы.

С целью поддержания интерактивности и отзывчивости интерфейсов Пачки, время на ответ ограничено. Ваше приложение должно дать ответ на вебхук в течение 3 секунд.

Отображение ошибок

Если вы хотите отобразить пользователю ошибки заполнения конкретных полей представления, то ответ должен быть HTTP 400 Bad Request, а тело ответа содержать массив полей с указанием текста ошибки.

Тело ответа с указанием текста ошибки для каждого поляobject
Пример ответа на вебхук для отображения ошибок
HTTP/1.1 400 Bad RequestServer: nginx/1.14.2Date: Wed, 22 Apr 2025 12:32:29 GMTContent-Type: application/json; charset=utf-8Transfer-Encoding: chunkedConnection: closeETag: W/"4d63aae1430a3bbd35e95e3db6b364df"Cache-Control: max-age=0, private, must-revalidateX-Request-Id: 12f8a05c-c5cf-4a79-8d2f-f82cc477c410X-Runtime: 0.117503Vary: OriginX-Rack-CORS: miss; no-origin {    "errors": {        "date_end": "Дата окончания отпуска не может быть меньше даты начала",        "request_doc": "В заявлении не найдена электронная подпись"    }}

Пример отображения ошибок в интерфейсе представления

Закрытие представления

Если вы хотите просто закрыть пользователю представление (нет необходимости отображать ошибки), то ответ должен быть HTTP 200 OK. Никакое тело ответа не требуется.

Пример ответа на вебхук для закрытия представления
HTTP/1.1 200 OKServer: nginx/1.14.2Date: Wed, 22 Apr 2025 12:32:29 GMTContent-Type: text/plain; charset=utf-8

Ответ через журнал событий

Этот раздел нужен, только если у бота не задан адрес исходящего вебхука. Отвечать на вебхук такому боту некуда, поэтому при включённой истории событий событие view_submit приходит в GETжурнал событий, а ответ отправляется методом POSTОтвет на отправку формы. Значения view_id и submit_id берутся из payload события.

Если адрес вебхука задан, пользуйтесь обычным ответом на вебхук: он проще и не требует опроса журнала.

Ответить нужно в течение 5 секунд с момента отправки формы. Если бот промолчал, пользователь получит ошибку отправки, значения полей сохранятся и он повторит попытку.

Тело запроса без поля errors закрывает представление как успешно отправленное. С полем errors — показывает ошибки под соответствующими полями, как и ответ HTTP 400 на исходящий вебхук.

Пример ответа с ошибками полей
{    "submit_id": "791a056b-006c-49dd-834b-c633fde52fe8",    "errors": {        "date_end": "Дата окончания отпуска не может быть меньше даты начала",        "request_doc": "В заявлении не найдена электронная подпись"    }}
Пример ответа для закрытия представления
{    "submit_id": "791a056b-006c-49dd-834b-c633fde52fe8"}

Повторный ответ на ту же отправку возвращает уже принятый результат в течение 15 минут, а не создаёт второй. Если время на ответ вышло или ответ уже был принят, метод отвечает 410 с кодом submit_expired.