# PRD: Семейный мессенджер ICQ (XMPP) на nixg.ru > Версия: 0.2 · Дата: 2026-08-28 · Статус: в разработке (Этапы 1-2 выполнены ✅, Этап 3 бот — следующий) > ⚠️ Актуальный домен: **nixg.ru** (JID user@nixg.ru). В тексте ниже старый домен chat.nixg.ru > из ранней версии PRD — при реализации везде используется nixg.ru (см. WALKTHROUGH.md). > > **Практический разбор всего сделанного: [WALKTHROUGH.md](WALKTHROUGH.md)** — > пошаговое описание с командами, почему выбрана такая архитектура, и все «засады». > > **Текущее состояние и план: [STATUS.md](STATUS.md)** — учётные данные, что работает, > проблема пустой страницы + план исправления (точка входа для новой сессии). ## 1. Обзор (Executive Summary) Разворачиваем собственный федеративный мессенджер для семьи на базе протокола **XMPP**. Сервер (Prosody) живёт на **bigbox** в каталоге `/opt/icq`, наружу выставляется через **vps02** (Caddy + WireGuard). Домен: **chat.nixg.ru**. Федерализация — обязательное требование: общение с любым XMPP-сервером в мире (email-подобная модель s2s). Дополнительно: **бот-книгоискатель**, который по запросу находит и скачивает книги из сетевых библиотек (OPDS-каталоги) и присылает файл прямо в чат. ## 2. Цели (Goals) - Личный, принадлежащий нам мессенджер для семьи (родители, дети). - Федеративность: связь с пользователями любых XMPP-серверов. - Клиенты под iOS и Android из официальных сторов (Snikket / Monal / Conversations). - Сквозное шифрование (OMEMO) по умолчанию. - Работает через наш туннель и не зависит от публичных мессенджеров. - Бот, автоматизирующий скачивание книг из сетевых библиотек. ## 3. Не-цели (Non-Goals) - Не пытаемся «слямзить» протокол Telegram/MTProto — это закрытый централизованный протокол, серверная часть не существует и не появится. Федеративность = XMPP. - Не строим свой клиент — используем готовые (Element/Snikket/Monal/Conversations). - Пока не делаем мост в Telegram/WhatsApp (mautrix) — только если понадобится позже. ## 4. Архитектура ### 4.1 Компоненты ``` [Клиенты: iOS/Android (Snikket/Monal/Conversations)] │ c2s (5222, TLS) ▼ [bigbox] Prosody (XMPP-сервер, Docker, /opt/icq) │ s2s (5269, TLS) — федерация с другими серверами │ http_upload (XEP-0363) — передача файлов (книги бота) ▼ [Бот-книгоискатель] slixmpp на bigbox, логинится как bot@chat.nixg.ru │ OPDS (HTTP) ▼ [Сетевые библиотеки: Флибуста и др.] ``` ### 4.2 Сеть (доступность) - **bigbox** — внутренний сервер (без публичного IP), Docker Compose. - **vps02** — публичный вход: Caddy (TLS, reverse-proxy WebSocket/HTTP) + WireGuard туннель до bigbox. - **Порты:** 443 (клиенты, веб) + 5222 (прямые клиенты) + 5269 (федерация s2s). - Форвард 5222/5269 с vps02 на bigbox через WireGuard (socat или iptables). ### 4.3 DNS (важно для федерации) ``` A chat.nixg.ru → публичный IP vps02 SRV _xmpp-client._tcp.chat.nixg.ru → chat.nixg.ru:5222 SRV _xmpp-server._tcp.chat.nixg.ru → chat.nixg.ru:5269 ``` Без SRV-записей другие XMPP-серверы не смогут нас найти (федерация не заработает). Входящая федерация требует открытого 5269 на vps02. ### 4.4 TLS / сертификаты - 443: Caddy выпускает сам (Let's Encrypt, http-01). - 5222/5269: dns-01 (домен у нас, DNS контролируем) → e.g. через Caddy/acme.sh. - Сертификат должен покрывать имена `chat.nixg.ru` (+ возможно `conference.chat.nixg.ru` для MUC). ## 5. Стек технологий | Слой | Технология | Почему | |------|-----------|--------| | Протокол | XMPP (RFC 6120/6121) | Федеративный, открытый, XML — как email | | Сервер | Prosody (Lua, Docker) | Лёгкий, гибкий, модули (http_upload, muc), удобен за реверс-прокси | | Внешний доступ | Caddy на vps02 + WireGuard | TLS автоматически, reverse-proxy, WG-туннель до bigbox | | Клиенты iOS | Monal / Snikket | Федерация + OMEMO + push (APNs) | | Клиенты Android | Conversations / Snikket | Федерация + OMEMO + push (FCM) | | Бот | Python + slixmpp | Зрелая живая библиотека XMPP | | Поиск книг | OPDS (Atom/XML каталоги) | Стандарт сетевых библиотек (Флибуста и др.) | | Передача файлов | XMPP HTTP Upload (XEP-0363) | Отправка книг в чат | | Развёртывание | Docker Compose в /opt/icq | Изоляция, простота, переносимость | Примечание: Snikket как *сервер* не берём (спроектирован под прямой 443, капризен за реверс-прокси), но его *клиенты* хороши — используем их. ## 6. Функциональные требования ### 6.1 Обязательные (Must have) - FR-1: Регистрация/вход по JID (user@chat.nixg.ru) с паролем. - FR-2: Личные сообщения 1-на-1, статусы присутствия (presence). - FR-3: Групповые чаты (MUC, конференции). - FR-4: Сквозное шифрование OMEMO. - FR-5: Передача файлов (HTTP Upload) — фото, документы. - FR-6: Федерация s2s — общение с пользователями других серверов. - FR-7: Админка/панель управления сервером (Prosody admin + командная строка). - FR-8: Клиенты iOS и Android из официальных сторов. ### 6.2 Желательные (Should have) - FR-9: Push-уведомления на iOS/Android (APNs/FCM) — через push-шлюз (Snikket/Conversations могут ходить на свой или публичный). - FR-10: Бот-книгоискатель (slixmpp + OPDS). - FR-11: Бэкапы базы/конфигов (в наш общий бэкап /opt/hermes). - FR-12: Логирование и мониторинг (доступность). ### 6.3 Мосты в Telegram и WhatsApp (Bridges) - FR-13: Мост в **Telegram** (mautrix-telegram) — общение с контактами Telegram из нашего клиента. - Двусторонняя переписка: наш пользователь ↔ контакт в Telegram. - Возможность отправлять/принимать файлы, реакции (по возможностям моста). - Авторизация через Telegram (логин/QR/MTProto), управление через панель бота моста. - FR-14: Мост в **WhatsApp** (mautrix-whatsapp) — общение с контактами WhatsApp из нашего клиента. - Двусторонняя переписка: наш пользователь ↔ контакт в WhatsApp. - Авторизация через QR-код WhatsApp Web. - Передача файлов, голосовых (по возможностям моста). - FR-15: Общий мост-хостинг (mautrix с Postgres/базой), регистрация в Prosody как компоненты. - OQ-5: Какие мосты деплоим сразу (оба), какие позже? Сначала Telegram, потом WhatsApp (обычно надёжнее). ## 7. Бот-книгоискатель (детально) ### 7.1 Сценарий 1. Пользователь пишет боту `book@chat.nixg.ru`: «Пушкин Капитанская дочка». 2. Бот ищет по OPDS-каталогам (Флибуста и др.). 3. Находит, скачивает (epub/fb2), присылает файлом через HTTP Upload. 4. (Опц.) Ограничение размера, только легальные источники. ### 7.2 Требования - FR-B1: Приём запросов через личные сообщения. - FR-B2: Поиск по OPDS (Atom feed). - FR-B3: Скачивание и отправка файла в чат (XEP-0363). - FR-B4: Логирование запросов. - FR-B5: Анти-флуд / ограничения. ## 8. Открытые вопросы (Open Questions) - OQ-1: Какая библиотека OPDS основная? Флибуста (нужны ли регистрация/логин)? - OQ-2: ~~Snikket-клиенты работают только со Snikket-серверами?~~ (нет — возьмём Monal + Conversations) - OQ-3: Нужен ли мост Telegram (mautrix-telegram) сразу или позже? - OQ-4: ~~Нужен ли веб-клиент (Converse.js) на 443 через Caddy?~~ **✅ СДЕЛАНО 2026-08-28** — https://chat.nixg.ru, Converse.js v14, локальные ассеты, WebSocket wss://chat.nixg.ru/xmpp-websocket. ## 9. Roadmap (этапы) 1. **Этап 1 — Фундамент (✅ ЗАВЕРШЁН 2026-08-28):** Docker Compose Prosody на bigbox (/opt/icq), базовые модули, DNS на chat.nixg.ru + SRV (A, _xmpp-client, _xmpp-server — внесены на Jino), Caddy на vps02 (443, reverse-proxy), форвард 5222/5269 через WG (iptables DNAT + FORWARD + MASQUERADE), группа безопасности Timeweb (TCP 5222/5269), веб-клиент Converse.js v14 на 443. Проверено: 5222/5269 открыты извне, webchat отдаётся, WebSocket 101 Switching Protocols. Подробности: [WALKTHROUGH.md](WALKTHROUGH.md). 2. **Этап 2 — Семья и федерация:** MUC (есть), OMEMO, **HTTP Upload (XEP-0363)** — установить community-модуль mod_http_upload из prosody-modules (в docker-образе Prosody 0.11.9 его НЕТ), добавление внешнего контакта (проверка s2s), настоящие сертификаты dns-01 для 5222/5269. Приглашение семьи. Клиенты iOS/Android. 3. **Этап 3 — Бот:** slixmpp-бот с OPDS-поиском, HTTP Upload. 4. **Этап 4 — Полировка:** push, бэкапы, мониторинг, (опц.) мосты mautrix. ## 10. Принятые решения (Decisions) - D-1: Протокол = XMPP (не Telegram/MTProto). - D-2: Сервер = Prosody (не Snikket-сервер, не Ejabberd). - D-3: Размещение = bigbox (/opt/icq), внешний вход = vps02 (Caddy + WG). - D-4: Домен = chat.nixg.ru. - D-5: Бот = Python slixmpp + OPDS + HTTP Upload. ## 11. Риски - R-1: Флибуста меняет зеркала/требует VPN/логин — бот должен уметь переключать источники. - R-2: Push на iOS (APNs) сложен для self-hosted — упираемся в публичный push-шлюз. - R-3: Ограничение 5269 у провайдера vps02 — проверить заранее. - R-4: Семейные пользователи малознакомы с XMPP-клиентами — подготовить инструкцию.