Примеры использования
Для разработчиков

Примеры использования

Пример 1. CRM → SupportHub

Менеджер в CRM заводит обращение клиента — интеграция создаёт тикет в SupportHub, чтобы поддержка увидела его в общем интерфейсе.

crm_to_supporthub.py
import requests

def create_support_ticket(crm_user, text):
    requests.post(
        "https://api.support.forestsnet.com/api/v1/tickets",
        headers={"Authorization": "Bearer sk_xxx"},
        json={
            "subject": text[:80],
            "priority": "normal",
            "tags": ["from-crm"],
            "contact": {
                "email": crm_user.email,
                "name": crm_user.full_name,
            },
            "message": text,
        },
        timeout=10,
    ).raise_for_status()

Пример 2. Автоответ через long polling

Бот без публичного адреса забирает события через long polling и отвечает на новые сообщения клиентов. Ответ уходит от имени бота: клиент увидит его в виджете на сайте, а в Telegram, VK, WhatsApp и на email он не отправляется.

bot.py
import time
import requests

API = "https://api.support.forestsnet.com/api/v1"
HEAD = {"Authorization": "Bearer sk_xxx"}
offset = int(time.time() * 1_000_000)  # только новые события

while True:
    r = requests.get(
        f"{API}/updates",
        headers=HEAD,
        params={"offset": offset, "timeout": 25, "types": "message.created"},
        timeout=35,
    )
    if r.status_code != 200:
        time.sleep(5)
        continue
    for ev in r.json()["updates"]:
        offset = max(offset, ev["id"])
        msg = ev["data"]
        if msg["sender_type"] != "contact":
            continue
        requests.post(
            f"{API}/tickets/{msg['ticket_id']}/messages",
            headers=HEAD,
            json={"content": "Спасибо, скоро ответим!"},
            timeout=10,
        )

Пример 3. События во внутренний дашборд

Сервис на Node.js забирает события и передаёт их в свой дашборд (notifyDashboard — ваша функция).

dashboard-bridge.mjs
const API = "https://api.support.forestsnet.com/api/v1";
const HEAD = { Authorization: "Bearer sk_xxx" };
let offset = Date.now() * 1000;

while (true) {
  const url = new URL(API + "/updates");
  url.searchParams.set("offset", String(offset));
  url.searchParams.set("timeout", "25");
  url.searchParams.set("types", "ticket.created,message.created");
  const r = await fetch(url, { headers: HEAD });
  if (!r.ok) {
    await new Promise((resolve) => setTimeout(resolve, 5000));
    continue;
  }
  const { updates } = await r.json();
  for (const ev of updates) {
    if (ev.id > offset) offset = ev.id;
    if (ev.type === "ticket.created") notifyDashboard("new_ticket", ev.data.ticket);
    if (ev.type === "message.created" && !ev.data.is_internal) notifyDashboard("new_message", ev.data);
  }
}
Сценарии можно совмещать: одна часть системы пишет через POST /api/v1/messages, другая получает события через /updates или webhooks. Лимит запросов общий для всего API и считается по ключу: все части системы с одним ключом делят один бюджет (см. Лимиты и ошибки).
Была ли страница полезной?