Обзор
Zweig можно подключить к любым вашим системам двумя способами:
- Входящий вебхук — без программирования. Вы получаете адрес, внешний сервис (CI, мониторинг, CRM, 1С) отправляет на него POST с текстом — и сообщение появляется в чате.
- Бот — ваша программа, которая читает сообщения в своих каналах и личке и отвечает. Работает через Bot API по токену.
Всё работает на вашем сервере: адрес API — https://<ваш-сервер>/api, например https://chat.example.ru/api. Данные никуда не уходят.
Входящие вебхуки
- «Панель администратора → Боты → Входящие вебхуки»: выберите канал, при желании — бота, от имени которого писать (по умолчанию общий бот «Вебхук»), и название — например, «GitLab CI».
- Скопируйте адрес — он показывается один раз. Адрес работает как пароль: любой, у кого он есть, может писать в канал.
- Отправьте сообщение:
curl -X POST https://chat.example.ru/api/hooks/zh_… \
-H 'Content-Type: application/json' \
-d '{"text": "Сборка #128 прошла ✅"}'
Принимается JSON с полем text (также message или content), Slack-совместимая форма с полем payload и просто текст в теле запроса. Длина — до 8000 символов. Ответ: {"ok": true, "id": "…"}.
GitLab CI
notify:
stage: .post
when: always
script:
- 'curl -s -X POST "$ZWEIG_HOOK" -H "Content-Type: application/json"
-d "{\"text\": \"$CI_PROJECT_NAME: пайплайн $CI_PIPELINE_ID — $CI_JOB_STATUS\"}"'
Python
import requests
HOOK = "https://chat.example.ru/api/hooks/zh_…"
requests.post(HOOK, json={"text": "Склад: остаток ниже нормы по 12 позициям"}, timeout=10)
Zabbix, Grafana и другие
Подойдёт любой «Webhook» или «Slack»-способ оповещения: укажите адрес вебхука, метод POST и тело {"text": "{ALERT.SUBJECT}"}.
Боты
- «Панель администратора → Боты»: логин (латиница, цифры,
_; по нему бота находят и упоминают,@ci_bot), имя в чатах (как бот подписан в сообщениях, например «Сборки CI»), описание. - Токен
zb_…показывается один раз. Потеряли — «Новый токен», старый сразу перестаёт действовать. - Добавьте бота в нужные каналы — кнопкой «Добавить в канал» или как обычного участника. Написать боту в личку может любой.
- Поле «URL для событий» — необязательное: если указать, сервер будет отправлять туда каждое новое сообщение POST-запросом.
Авторизация
Каждый запрос Bot API — с заголовком:
Authorization: Bearer zb_…
Бот не входит паролем и не может стать обычным пользователем. Все его действия записываются в журнал.
Методы Bot API
GET /api/bot/me | кто я |
GET /api/bot/channels | каналы, где состоит бот |
POST /api/bot/channels/{slug}/messages | написать в канал |
PUT /api/bot/channels/{slug}/messages/{id} | исправить своё сообщение |
DELETE /api/bot/channels/{slug}/messages/{id} | удалить своё сообщение |
POST /api/bot/direct | написать в личку тому, кто уже писал боту |
GET /api/bot/updates | новые сообщения (долгий опрос) |
/api/bot/me{"username": "ci_bot", "display_name": "Сборки CI",
"description": "пишет о сборках", "webhook_url": ""}
/api/bot/channels[{"slug": "sklad", "name": "склад-логистика", "type": "public"},
{"slug": "dm-ci_bot-anna", "name": "", "type": "direct"}]
/api/bot/channels/{slug}/messagesТело: text — обязательно, reply_to — id сообщения, на которое ответить.
curl -X POST https://chat.example.ru/api/bot/channels/sklad/messages \
-H 'Authorization: Bearer zb_…' -H 'Content-Type: application/json' \
-d '{"text": "Машина 4512 на воротах север-3"}'
/api/bot/channels/{slug}/messages/{id}Тело: {"text": "…"}. Править можно только свои сообщения.
/api/bot/channels/{slug}/messages/{id}/api/bot/directТело: {"username": "anna", "text": "…"}. Первым в личку бот не пишет: человек должен сначала написать боту сам.
Получение сообщений
/api/bot/updates?offset=&timeout=Ждёт до timeout секунд (не больше 50) и отдаёт список новых событий:
[{"update_id": 42, "type": "message",
"message": {"id": "…", "channel": {"slug": "ci", "name": "Сборки", "type": "public"},
"sender": "anna", "sender_name": "Анна", "type": "text",
"text": "/ping", "file": null, "reply_to": null,
"timestamp": "2026-10-22T10:00:00+00:00"}}]
Следующий запрос — с offset, равным последнему полученному update_id: всё до него включительно сервер удаляет. Очередь хранит до 1000 событий на бота.
URL для событий
Если у бота указан URL, каждое событие ещё и отправляется туда POST-запросом — тот же JSON, по одному объекту. Очередь для опроса при этом тоже пополняется, так что можно использовать оба способа.
Пример: бот на Python
import requests
API = "https://chat.example.ru/api"
H = {"Authorization": "Bearer zb_…"}
offset = 0
while True:
r = requests.get(f"{API}/bot/updates", headers=H,
params={"offset": offset, "timeout": 50}, timeout=60)
for u in r.json():
offset = u["update_id"]
m = u.get("message") or {}
if m.get("text", "").strip() == "/ping":
requests.post(f"{API}/bot/channels/{m['channel']['slug']}/messages",
headers=H, json={"text": "pong 🏓", "reply_to": m["id"]})
Ограничения и ошибки
- Бот видит только каналы, куда его добавили, и личку, которую ему написали.
- Не больше 30 сообщений в минуту на бота и на каждый вебхук.
- В общих каналах с другими серверами (федерация) сообщения бота доходят как обычные.
400 | пустой текст или тело не разобрать |
401 | нет токена или он недействителен |
403 | бот отключён администратором или нет доступа к каналу |
404 | канал, сообщение или вебхук не найдены |
429 | слишком много сообщений — подождите минуту |
Скоро
- Вебхуки в личку — уведомления лично себе без канала.
- Вебхуки и боты в закрытых чатах — создаёт владелец чата, а не только администратор.
- Команды через
/с подсказками и кнопки под сообщениями.