--- tags: - zulip - migration - infrastructure created: '2026-05-11' --- # Zulip Migration ## Статус Zulip развёрнут и работает. Идёт миграция тредов из Discord. ## Инфраструктура - **URL**: https://zulip.qentra.top - **Расположение**: Docker на Mac M4 Max (`~/Developer/zulip/docker-compose.yml`) - **Туннель**: Cloudflare Tunnel (`/Library/LaunchDaemons/com.cloudflare.cloudflared.plist`) — поднимается при загрузке системы - **Docker**: Colima + `restart: unless-stopped` — поднимается при логине (`~/Library/LaunchAgents/com.colima.start.plist`) - **Стримы**: master, daily-brief, executor, inbox, focus, journal, general, sandbox, Zulip ## Настройки безопасности - Регистрация закрыта (`/accounts/register/` → 405) - Только 2 пользователя: `admin@zulip.local`, `eagle-bot@zulip.local` - OAuth отключён (только email+password auth) - Cloudflare TLS end-to-end ## Маппинг Discord → Zulip | Discord канал | Zulip стрим | |---|---| | #master | master | | #executor | executor | | #daily-brief | daily-brief | | #inbox | inbox | | #focus | focus | | #journal | journal | | #projects | projects | ## Миграция тредов (2026-05-11) Скрипт: `/tmp/migrate_discord_zulip.py` Прогресс: `/tmp/migration_done.txt` **Статус: ✅ ЗАВЕРШЕНА** — 44/44 тредов залиты (45-й «Zulip migration ⭐» пропущен намеренно — pitfall #8) ### Залито (44/44): - Все активные треды из master, executor, daily-brief, inbox, focus, journal, projects - «Zulip migration ⭐» — пропущен намеренно (самый активный, мигрировать его нельзя пока он используется) ### Проблемы: - Discord bot HTTP REST API → 403 (нет MESSAGE_CONTENT intent) — решено через discord.py с gateway - `on_ready` срабатывал при reconnect → повторные прогоны — решено флагом `_migrated` - Во время пропадания интернета часть сообщений "Zulip migration ⭐" не залилась (error 1033) ## Апгрейд Zulip Запланирован после завершения миграции. Zulip показывает баннер "running an old version". ## Approval-реакции (UX-идея) Бот слушает emoji-реакции 👍 / 👎 / 🔒 / ♾️ на approval-сообщениях. **Проблема**: emoji picker в Zulip web/mobile не знает, какие реакции нужны, предлагает недавно использованные — неудобно. **Решение**: после отправки approval-сообщения бот сам добавляет эти 4 реакции через `POST /api/v1/messages/{id}/reactions`. Тогда web/mobile показывают их прямо на сообщении — один клик для ответа, без поиска в picker. **Pitfall**: `POST /messages/{id}/reactions` генерирует событие `reaction` — бот получит его и может принять как голос пользователя. Фикс: проверять `user_id != bot_user_id`. ✅ Уже реализовано в `gateway/platforms/zulip.py` (`_handle_reaction_event`, строки 658–660).