#Получить события (polling)
GET /v1/bots/:botId/events
Основной механизм получения входящих сообщений и команд. Бот периодически запрашивает новые события.
Vibe хранит lastOffset в базе данных — при первом запросе без offset используется сохранённое значение. Это позволяет боту продолжить с места остановки после перезапуска.
#Параметры
| Параметр | Тип | Обяз. | По умолч. | Описание |
|---|---|---|---|---|
botId (path) |
number | да | — | ID бота |
offset (query) |
number | нет | из БД | Начальная позиция. Без параметра — сохранённое в БД значение. offset=0 — начать с начала |
limit (query) |
number | нет | 100 |
Максимальное количество событий (1-1000) |
withUserEvents (query) |
boolean | нет | false |
Включить user-события (ONIMV2*) |
#Примеры
#curl — личный ключ
curl "https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50" \
-H "X-Api-Key: YOUR_API_KEY"
#curl — OAuth-приложение
curl "https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
#JavaScript — личный ключ
const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50', {
headers: {
'X-Api-Key': 'YOUR_API_KEY',
},
})
const { success, data } = await res.json()
console.log('События:', data.events.length, 'Ещё:', data.hasMore)
#JavaScript — OAuth-приложение
const res = await fetch('https://vibecode.bitrix24.tech/v1/bots/42/events?limit=50', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { success, data } = await res.json()
#Поля ответа
| Поле | Тип | Описание |
|---|---|---|
events |
array | Массив событий (см. типы событий) |
events[].eventId |
number | ID события — передайте как offset в следующем запросе |
events[].type |
string | Код события (ONIMBOTV2MESSAGEADD, ONIMBOTV2COMMANDADD и т.д.) |
events[].date |
string | Дата и время события (ISO 8601) |
events[].data |
object | Данные события (структура зависит от типа, ключи в camelCase) |
nextOffset |
number | Смещение для следующего запроса |
hasMore |
boolean | Есть ещё необработанные события |
storedOffset |
number | Текущее сохранённое смещение в БД |
#Пример ответа
{
"success": true,
"data": {
"events": [
{
"eventId": 35,
"type": "ONIMBOTV2MESSAGEADD",
"date": "2026-04-13T17:15:00+03:00",
"data": {
"dialogId": "chat123",
"message": { "id": 1501, "text": "Привет, бот!" },
"user": { "id": 1, "name": "Иван Петров" }
}
}
],
"nextOffset": 36,
"hasMore": false,
"storedOffset": 0
}
}
#Пример ответа при ошибке
404 — бот не найден:
{
"success": false,
"error": {
"code": "BOT_NOT_FOUND",
"message": "Bot 999 not found. Register it first via POST /v1/bots."
}
}
#Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_BOT_ID |
botId не является числом |
| 404 | BOT_NOT_FOUND |
Бот с таким ID не найден |
| 403 | BOT_ACCESS_DENIED |
Бот принадлежит другому API-ключу |
| 502 | BITRIX_ERROR |
Ошибка Bitrix24 (текст ошибки в message) |
| 403 | SCOPE_DENIED |
API-ключ не имеет скоупа imbot |
| 401 | TOKEN_MISSING |
API-ключ не имеет настроенных токенов |
Полный список общих ошибок API — Ошибки.
#Известные особенности
Серверное хранение offset: Vibe хранит lastOffset в БД. При первом запросе без offset — используется сохранённое значение. После получения событий lastOffset обновляется автоматически (fire-and-forget).
offset=0: явная передача offset=0 начинает с начала истории — для отладки или первичной загрузки.
Цепочка запросов:
GET /events → { nextOffset: 42, hasMore: true }
GET /events?offset=42 → { nextOffset: 55, hasMore: false }
GET /events?offset=55 → { events: [], hasMore: false }
Рекомендуемый интервал polling: 2-5 секунд между запросами.
Polling-цикл (готовый пример):
const BOT_ID = 42
const API_KEY = 'YOUR_API_KEY'
const BASE = 'https://vibecode.bitrix24.tech/v1'
async function pollEvents() {
let offset = undefined
while (true) {
try {
const url = new URL(`${BASE}/bots/${BOT_ID}/events`)
if (offset !== undefined) url.searchParams.set('offset', String(offset))
const res = await fetch(url, {
headers: { 'X-Api-Key': API_KEY },
})
const { data } = await res.json()
for (const event of data.events ?? []) {
await handleEvent(event)
}
if (data.nextOffset !== undefined) {
offset = data.nextOffset
}
} catch (err) {
console.error('Poll error:', err.message)
}
await new Promise(r => setTimeout(r, 3000))
}
}
async function handleEvent(event) {
const { data } = event
switch (event.type) {
case 'ONIMBOTV2MESSAGEADD':
// Ответить на сообщение
await fetch(`${BASE}/bots/${BOT_ID}/messages`, {
method: 'POST',
headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
dialogId: data.dialogId,
fields: { message: `Получил: ${data.message.text}` },
}),
})
break
case 'ONIMBOTV2COMMANDADD':
// Ответить на команду
await fetch(`${BASE}/bots/${BOT_ID}/commands/${data.command.id}/answer`, {
method: 'POST',
headers: { 'X-Api-Key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
messageId: data.message.id,
message: `Команда /${data.command.command}: ${data.command.params}`,
}),
})
break
}
}
pollEvents()
#Смотрите также
- Bot-события — 8 типов событий с примерами payload
- User-события — подписка на события чатов
- Отправить сообщение — ответ на событие
- Ответить на команду — обработка ONIMBOTV2COMMANDADD
- Бот-платформа — обзор, быстрый старт, polling-цикл
- Лимиты и оптимизация — rate limits платформы