Updates (Long Polling)
Для разработчиков

Updates (Long Polling)

Эндпоинт /api/v1/updatesработает в стиле Telegram Bot API getUpdates: вы передаёте offsetпоследнего полученного события, а сервер отдаёт все новые. Если новых событий нет и указан timeout — сервер «висит» до их появления (или до истечения таймаута).

GET/api/v1/updates

Получить новые события

  • offset — id последнего обработанного события (микросекундный timestamp). 0 при первом запросе.
  • timeout — сколько секунд держать соединение, ожидая новых событий (0–30, default 0).
  • types — фильтр через запятую, например ticket.created,message.created.
200 OK
{
  "updates": [
    {
      "id": 1796543210000123,
      "type": "ticket.created",
      "timestamp": "2026-04-06T10:12:33.123456",
      "data": {
        "ticket_id": "8a3f...",
        "actor_type": "contact",
        "actor_id": "44e1...",
        "payload": {},
        "ticket": { ... }
      }
    },
    {
      "id": 1796543210000999,
      "type": "message.created",
      "timestamp": "2026-04-06T10:12:33.999000",
      "data": { "id": "f1...", "content": "...", ... }
    }
  ]
}

Типы событий

Long-polling читает события из БД (TicketEvent + Message-таблица), поэтому отдаёт более узкий subset чем webhooks:

  • ticket.created
  • ticket.assigned / ticket.transferred / ticket.force_taken
  • ticket.closed / ticket.reopened / ticket.rated
  • ticket.identify_confirmed и другие system-event'ы из TicketEvent
  • message.created

Чего НЕТ в long-polling (только в webhooks): message.edited, message.deleted, message.reaction.*, contact.*, operator.status.changed, billing.*. Если они нужны — регистрируйте webhook на POST /api/v1/webhooks (см. справочник webhooks).

Фильтр через query types= — список через запятую: types=ticket.created,message.created.

Клиент на Python

poll.py
import requests

API = "https://api.support.forestsnet.com/api/v1"
HEAD = {"Authorization": "Bearer sk_xxx"}
offset = 0

while True:
    r = requests.get(
        f"{API}/updates",
        headers=HEAD,
        params={"offset": offset, "timeout": 25},
        timeout=35,
    )
    r.raise_for_status()
    for ev in r.json()["updates"]:
        print(ev["type"], ev["data"])
        offset = max(offset, ev["id"])

Клиент на Node.js

poll.mjs
const API = "https://api.support.forestsnet.com/api/v1";
const HEAD = { Authorization: "Bearer sk_xxx" };
let offset = 0;

while (true) {
  const url = new URL(API + "/updates");
  url.searchParams.set("offset", offset);
  url.searchParams.set("timeout", "25");
  const r = await fetch(url, { headers: HEAD });
  const { updates } = await r.json();
  for (const ev of updates) {
    console.log(ev.type, ev.data);
    if (ev.id > offset) offset = ev.id;
  }
}
offset — это последний обработанный id. Сохраняйте его в БД или файле, чтобы при перезапуске не получить старые события заново.
Была ли страница полезной?