Files
obsidian-vault/personal/projects/zulip-router.md
T

115 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Zulip Router
_Последнее обновление: 2026-06-16_
## Цель
Event-роутер между Zulip и balda-ботами (Валера, Клавдий).
Решает проблему конкурентного получения событий — сейчас оба бота видят все сообщения одновременно.
## Проблема (root cause)
- Каждый balda-бот регистрирует собственную event queue в Zulip Events API
- Без роутера оба получают все сообщения, и каждый может ответить на @mention другого
- `extractOtherMention()` патч в коде — костыль, не решает проблему полностью
## Как сейчас (до роутера)
```
Zulip
├── Events API ← Валера (valera-bot, poll на :8091) — отключён
├── Events API ← Клавдий (claudio-bot, poll на :8092) — отключён
└── Webhook → оба (outgoing webhook через @mention)
```
## Архитектура (с роутером)
```
Zulip Event Queue
↓ poll (credentials Eagle из ~/.hermes/config.yaml)
[zulip-router] (~/Docker/zulip-router/)
├── @Валера / @Valera → POST http://balda-agent-valera-1:8091/zulip/webhook
├── @Клавдий / @Klavdiy → POST http://claudio-agent-claudio-1:8092/zulip/webhook
└── (default / unknown) → POST http://balda-agent-valera-1:8091/zulip/webhook
↕ ownership: stream+topic → bot (TTL 24h, persisted to /data/ownership.json)
```
**Ключевое:** credentials — Eagle/Орла (не новый бот). Роутер регистрирует свою event queue (отдельную от очереди Eagle).
## Правила маршрутизации
1. `@Валера` или `@Valera` в тексте → Валера (+ ownership обновляется)
2. `@Клавдий` или `@Klavdiy` в тексте → Клавдий (+ ownership обновляется)
3. Топик уже у кого-то → туда же (TTL refreshed)
4. Новый топик без @mention → Валера (default)
5. `reset` без @mention → только владельцу топика
## Что меняется в balda
После деплоя роутера Events API polling уже отключён у обоих ботов (сделано 2026-06-16):
```yaml
zulip:
events_polling:
enabled: false
```
Сообщения приходят **только через webhook** от роутера.
## Код
**Репозиторий:** `~/Developer/zulip-router/` — Go, ~260 LOC (план)
**Deploy:** `~/Docker/zulip-router/docker-compose.yaml`
| Файл | Назначение |
|------|------------|
| `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 к balda webhook endpoints |
## Deployment
**Compose:** `~/Docker/zulip-router/docker-compose.yaml`
### Credentials: Eagle, не новый бот
Роутер использует credentials Eagle/Орла из `~/.hermes/config.yaml``platforms.zulip`.
Не создавать нового бота. Eagle уже имеет права на чтение всех публичных стримов.
### Env vars
Создать `~/Docker/zulip-router/.env`:
```env
# Credentials Eagle/Орла — из ~/.hermes/config.yaml
ZULIP_BOT_EMAIL=eagle-bot@zulip.qentra.top
ZULIP_API_KEY=<скопировать из конфига Eagle>
# Куда форвардить (Docker DNS, сеть balda_default)
VALERA_WEBHOOK=http://balda-agent-valera-1:8091/zulip/webhook
CLAUDIO_WEBHOOK=http://claudio-agent-claudio-1:8092/zulip/webhook
```
### Запуск
```bash
cd ~/Docker/zulip-router
docker-compose up -d
docker logs zulip-router --tail 20 # проверить poll loop
```
## TODO
- [ ] Написать код роутера (~260 LOC)
- [ ] Создать compose `~/Docker/zulip-router/docker-compose.yaml`
- [ ] Набить `.env` с credentials Eagle (из `~/.hermes/config.yaml`)
- [ ] `docker-compose up -d`
- [ ] Проверить логи: `docker logs zulip-router --tail 50`
- [ ] Протестировать: @Клавдий и @Валера в разных топиках
- [ ] Проверить ownership: сообщение в топик без @mention → последний бот
- [ ] Удалить `extractOtherMention()` патч из кода (больше не нужен)