3.5 KiB
3.5 KiB
tags, status, created
| tags | status | created | |||||
|---|---|---|---|---|---|---|---|
|
deployed | 2026-06-16 |
Zulip Router
Цель
Event-роутер между Zulip и несколькими Hermes-инстансами.
Решает проблему конкурентного получения событий (Валера, Клавдий и другие боты видели все сообщения одновременно, reset срабатывал у всех).
Проблема (root cause)
- Каждый Hermes-инстанс в polling-режиме регистрирует собственную event queue в Zulip
reset— системная команда Hermes, обрабатывается до хукаwhale-thread-guard- Нет механизма ownership топика между инстансами
Архитектура
Zulip Event Queue
↓ poll (valera-bot credentials)
[zulip-router]
├── @Валера → http://hermes-valera:8765/zulip-webhook
└── @Клавдий → http://hermes-klavdiy:8765/zulip-webhook
↕ ownership: stream+topic → bot (TTL 24h, persisted to /data/ownership.json)
Hermes/Орёл — не трогаем, остаётся в polling-режиме.
Правила маршрутизации
@Валераили@Valeraв тексте → Валера (+ ownership обновляется)@Клавдийили@Klavdiyв тексте → Клавдий (+ ownership обновляется)- Топик уже у кого-то → туда же (TTL refreshed)
- Новый топик без @mention → Валера (default)
resetбез @mention → уходит только к владельцу топика ✓
Код
~/docker/zulip-router/ — Go, ~260 LOC
| Файл | Назначение |
|---|---|
main.go |
Poll loop, routing, dispatch |
config.go |
Config struct + YAML loading + env var expansion |
zulip.go |
Zulip API client (register_queue, get_events, long-poll) |
ownership.go |
Topic ownership store (RW mutex + JSON persistence) |
forwarder.go |
HTTP POST к Hermes webhook endpoints |
Deployment
Compose: ~/docker/hermes/docker-compose.yml — сервис zulip-router
Env vars (~/docker/hermes/.env):
ZULIP_ROUTER_API_KEY=<valera-bot api key из ~/.hermes/profiles/valera/config.yaml>
ZULIP_WEBHOOK_TOKEN=zr-secret-2026
Запуск после заполнения .env:
cd ~/docker/hermes
docker compose up -d --force-recreate
Перезапуск после изменений в профилях:
docker compose restart hermes-valera hermes-klavdiy
Hermes профили
Валера и Клавдий переведены в webhook-режим:
platforms:
zulip:
webhook_port: 8765
webhook_path: /zulip-webhook
webhook_token: 'zr-secret-2026'
Токен должен совпадать с ZULIP_WEBHOOK_TOKEN в .env.
TODO
- Заполнить ZULIP_ROUTER_API_KEY в ~/docker/hermes/.env
docker compose up -d --force-recreate- Проверить логи:
docker compose logs -f zulip-router - Протестировать: написать @Клавдий и @Валера в отдельных топиках
- Проверить ownership: обратиться в топик без @mention — должен отвечать последний бот
- При необходимости: добавить Hermes/Орёл в роутер (отдельная задача)