Для AI-агентов: markdown этой страницы — /docs-content/infra/event-subscriptions/handler.md индекс документации — /llms.txt
Обработчик на стороне приложения
Приём доставленного события в приложении на Black Hole-сервере. Платформа доставляет каждое событие POST-запросом на субдомен приложения по пути appPath в формате application/x-www-form-urlencoded — это стандартное тело события Битрикс24. Обработчик читает event и data, сверяет auth[application_token] со своим application_token и отвечает 2xx. Платформа повторяет доставку при ответе не 2xx и будит спящий сервер.
// Express-обработчик: поля формы Битрикс24 приходят в req.body
import express from 'express'
const APP_TOKEN = process.env.APPLICATION_TOKEN // application_token приложения
const app = express()
app.use(express.urlencoded({ extended: true }))
app.post('/api/webhooks/b24', (req, res) => {
// Сверка токена приложения — события без верного токена отклоняются
if (req.body.auth?.application_token !== APP_TOKEN) {
return res.status(403).json({ ok: false })
}
const event = req.body.event // например "ONTASKADD"
const taskId = req.body.data?.FIELDS?.ID // ID сущности из события
// Повторное событие не должно сработать дважды — платформа может доставить его снова
console.log(`Событие ${event}, задача #${taskId}`)
// Ответить 2xx, иначе платформа повторит доставку
res.status(200).json({ ok: true })
})
Тело события
Пример тела, которое приходит в обработчик:
event=ONTASKADD&data[FIELDS][ID]=20152&ts=1780843200&auth[access_token]=<токен Битрикс24>&auth[refresh_token]=<токен обновления Битрикс24>&auth[application_token]=<application_token приложения>&auth[domain]=your-portal.bitrix24.ru&auth[member_id]=...
Тело несёт токены пользователя Битрикс24. auth[application_token] обработчик сверяет, чтобы отклонить чужие события. auth[access_token] — токен Битрикс24 для прямых вызовов REST Битрикс24. Как ключ V1 API напрямую он не работает, но его можно обменять на токен сессии — это второй способ авторизации ниже.
Токенов auth[access_token] и auth[refresh_token] в теле нет в трёх случаях:
- Ключ, которому принадлежит сервер, или ключ авторизации приложения подписки не меняет данные Битрикс24.
- Любой из этих ключей удалён или отозван либо у приложения нет активного ключа авторизации.
- Адрес приложения
appUrlуказывает не на сервер платформы — ни на субдомен Black Hole, ни на подключённый к серверу собственный домен. На внешний адрес платформа токены не отправляет при любых режимах ключей.
auth[application_token], auth[user_id] и данные события при этом приходят. Второй способ авторизации такому обработчику недоступен — вызывайте V1 API персональным ключом по первому способу, вызовы пойдут от лица владельца ключа.
Если адрес указывает на сервер платформы, событие без токенов от пользователя, которому политика доступа этого сервера закрыта, не доставляется. Событие на внешний адрес политикой доступа не фильтруется — сверяйте auth[user_id] в обработчике сами.
Чтобы токены снова приходили, переведите оба ключа в режим «Чтение и запись» — Режим доступа ключа. На внешний адрес токены не приходят и тогда.
Авторизация вызовов V1 API из обработчика
Обработчик часто вызывает V1 API в ответ на событие — читает связанную сущность или создаёт новую. Платформа доставляет событие сама и не добавляет заголовков авторизации: в запросе приходит только Content-Type и тело события. Авторизацию вызова обработчик задаёт сам. Есть два рабочих способа — выбор зависит от того, под чьим ключом должны идти вызовы.
Способ 1. Персональный ключ `vibe_api_`
Самый короткий путь: персональный ключ в заголовке X-Api-Key, сессия не нужна. Вызовы идут от лица владельца ключа. Подходит, когда их не обязательно делать под тем же приложением, что и подписка.
app.post('/api/webhooks/b24', async (req, res) => {
if (req.body.auth?.application_token !== APP_TOKEN) {
return res.status(403).json({ ok: false })
}
const taskId = req.body.data?.FIELDS?.ID
// Вызов V1 API — персональный ключ в заголовке X-Api-Key
const task = await fetch(
`https://vibecode.bitrix24.tech/v1/tasks/${taskId}`,
{ headers: { 'X-Api-Key': process.env.VIBE_API_KEY } },
).then((r) => r.json())
console.log('Задача из события:', task.data)
res.status(200).json({ ok: true })
})
Персональный ключ vibe_api_ создают в личном кабинете — порядок создания описан в Ключах и авторизации. Скоупы Битрикс24 закрепляются за ключом при выпуске: отметьте те группы данных, к которым обращается обработчик (для примера с задачами — tasks).
Способ 2. Ключ авторизации `vibe_app_` под тем же приложением
Если вызовы должны идти под тем же ключом авторизации, что и подписка, то есть от лица пользователя портала — обработчику нужна сессия. Тело события несёт токены этого пользователя: auth[access_token], auth[member_id], auth[domain] и auth[refresh_token]. Их обменивают на токен сессии vibe_session_ запросом POST /v1/oauth/placement-session с телом { app_key, access_token, member_id, domain, refresh_token }. Полученную сессию передают в Authorization: Bearer рядом с X-Api-Key:
curl https://vibecode.bitrix24.tech/v1/tasks/20152 \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
Как получить сессию из токенов события — раздел «Приложение на своём сервере» в «Ключах и авторизации». Сессия живёт 24 часа, продления нет.
Частые ошибки авторизации
Три сочетания заголовков, которые не сработают, и код ответа для каждого:
| Что передали | Ответ | Причина |
|---|---|---|
Ключ авторизации vibe_app_ в X-Api-Key без Bearer |
401 TOKEN_MISSING |
На самом ключе портальных токенов нет — нужна сессия в Authorization: Bearer рядом с X-Api-Key (Способ 2) |
Ключ авторизации vibe_app_ в Authorization: Bearer |
401 WRONG_AUTH_SCHEME |
В Bearer идёт токен сессии vibe_session_, а не ключ приложения |
Токен auth[access_token] из события в Authorization: Bearer |
401 MISSING_API_KEY |
Это токен Битрикс24, а не ключ V1. В Bearer V1 API принимает только токены vibe_ — токен Битрикс24 сначала обменивают на сессию (Способ 2) |
Подробный разбор TOKEN_MISSING — Диагностика проблем бот-платформы.
Известные особенности
- Доставка проходит через туннель — публичный URL приложению не нужен. Платформа регистрирует обработчик на своей стороне, Битрикс24 шлёт событие туда, а платформа доставляет его в приложение через туннель Black Hole с проверкой
auth[application_token]. Своего публичного адреса приложению не требуется. - Спящий сервер просыпается под доставку. Если на момент события сервер спит, платформа будит его и доставляет событие после подключения туннеля. Поэтому первое событие после простоя приходит с задержкой на пробуждение.
- Доставка надёжная, но не бесконечная. Неуспешные доставки повторяются с нарастающей задержкой. После исчерпания попыток доставка переходит в
FAILED, подписка помечаетсяDEGRADED, владелец получает уведомление. Статусы доставок видны вGET /v1/infra/servers/:id/event-subscriptions. - Повторная доставка не должна дублировать эффект. Одно и то же событие может прийти повторно. Обрабатывайте его так, чтобы второй приём с тем же
data[FIELDS][ID]не сделал работу дважды.