Архитектура Shalter
Shalter — это однопроцессный мессенджер на Node.js с Express, SQLite (WAL) и WebSocket-сервером. Клиент построен на чистом ES module JavaScript без фреймворков.
Технологический стек
| Слой | Технология |
|---|---|
| Сервер | Node.js, Express 5 |
| База данных | SQLite 3 (better-sqlite3, WAL-режим) |
| Веб-сокеты | ws (Node.js Web Server API) |
| Видеосвязь | WebRTC PeerConnection |
| Клиент (web) | Чистый HTML, CSS, ES module JavaScript |
| Десктоп | Tauri (Linux, Windows) |
| Мобильный | Android (Kotlin) |
| Сборка клиента | esbuild (минификация, бандл) |
| Шифрование текста | server/lib/textCrypto.js (AES-GCM) |
Сервер
Точка входа — server/index.js. Express-приложение монтирует маршруты по группам:
| Префикс | Модуль | Описание |
|---|---|---|
| /api/bot-api | server/routes/botApi.js | Bot API |
| /api/oauth | server/routes/oauth.js | OAuth 2.0 (SSO в сторонние сервисы) |
| /api/chats | server/routes/chats.js | Чаты, группы, каналы |
| /api/messages | server/routes/messages.js | Сообщения |
| /api/calls | server/routes/calls.js | Звонки |
| /api/users | server/routes/users.js | Пользователи |
| /api/stories | server/routes/stories.js | Stories |
| /api/bots | server/routes/bots.js | Управление ботами |
| /api/gifts | server/routes/gifts.js | Подарки |
| /api/premium | server/routes/premium.js | Premium и звёзды |
| /api/export | server/routes/export.js | Экспорт данных |
| /api/shalter-ai | server/routes/shalterAi.js | ИИ-ассистент |
| /api/games | server/routes/games.js | Мини-игры |
| /api/ads | server/routes/ads.js | Рекламные кампании |
| /api/live | server/routes/live.js | Прямые трансляции |
| /api/partners | server/routes/partners.js | Партнёрская программа |
Статические файлы из public/ обслуживаются через express.static().
SPA-режим: любой не-API путь, не начинающийся с /api/, отображает
index.html (клиентский роутинг).
База данных
SQLite 3 через better-sqlite3. Журнал WAL (Write-Ahead Logging) для
одновременного чтения и записи. Схема в server/db.js.
Основные таблицы
| Таблица | Описание |
|---|---|
| users | Аккаунты: id, name, username, phone, email, isBot, isPremium, stars, тотп |
| chats | Чаты: id, type (dm|group|channel), title, username, ownerId, pinned, muted, archived |
| chat_members | Связь чат ↔ пользователь (many-to-many), isAdmin, isOwner, isModerator |
| messages | Сообщения: id, chatId, senderId, type, text (зашифр.), attachments, reactions, readByIds |
| chat_reads | Граница прочитанного по чату (оптимизация) |
| bots | Боты: userId, ownerId, token, description, commands, appUrl, appCode |
| chat_members → restrictions | Ограничения (молчание) — JSON на чате |
| sessions | Активные сессии с токенами доступа |
| stories | Stories: userId, kind, url, expiresAt, viewedByIds |
| sticker_packs | Паки стикеров (JSON колонка) |
| custom_emoji | Кастомные эмодзи |
| games | Мини-игры (HTML5, iframe) |
| gift_issues | Выпущенные эксклюзивные подарки с серийными номерами |
| scheduled_messages | Отложенные сообщения |
| data_exports | Аудит экспорта данных для правовых запросов |
textCrypto.js). Поиск по сообщениям
работает через FTS5-индекс по токенам (строятся из зашифрованного текста — токены поисковые,
текст не раскрывается). Файлы вложений хранятся на диске и отдаются через serveUpload.
WebSocket
server/ws.js + public/js/lib/wsClient.js. WebSocket используется для:
- Мгновенной доставки сообщений (
message:new,message:updated,message:deleted) - Статуса печати (
typing:update) - Сигнализации звонков (WebRTC offer/answer/candidate)
- Обновлений статуса онлайна
- Подачи постов и обновлений каналов в реальном времени
HTTP polling сохраняется как fallback для переподключения и догрузки истории.
WebRTC (звонки)
Голос и видео на WebRTC PeerConnection. Сигналинг через WebSocket (server/routes/calls.js,
server/ws.js). Групповые звонки до 50 участников, PiP-режим, приглашение по ссылке
с токеном доступа (calls.joinToken).
Клиент
Клиент — чистый ES module JavaScript без фреймворков (public/js/).
Сервис-воркер (public/sw.js) кэширует оболочку для офлайн-работы.
Роутинг — клиентский (public/js/router.js), view-компоненты в public/js/views/.
npm run build (esbuild) в public/dist/.
В режиме разработки (npm run dev) обслуживаются сырые исходники из public/.
HTTP API
REST API на /api/. Авторизация через HTTP-only cookie с device token
(см. server/middleware/auth.js). API возвращает JSON. Основные группы:
/api/bootstrap— загрузка данных пользователя и списка чатов при старте/api/chats— CRUD чатов, участники, права/api/messages— список, поиск, редактирование, удаление, реакции/api/calls— история звонков, создание звонков/api/users— профиль, статус, поиск/api/stories— истории и отзывы/api/gifts— каталог подарков, покупка за звёзды/api/ads— рекламные кампании/api/live— прямые трансляции/api/games— мини-игры/api/shalter-ai— ИИ-ассистент/api/export— экспорт данных пользователя
Bot API
Bot API доступен на /api/bot-api/. Все методы требуют заголовка
Authorization: Bearer <token>. Обновления приходят через long-polling
(/updates?after=ISO&timeout=50). Подробная документация:
справочник методов и полная документация.
Авторизация
- По номеру телефона — SMS или звонок с кодом
- Двухфакторная аутентификация (TOTP)
- OAuth 2.0 — «Войти через Shalter» для сторонних сервисов
- Recovery-коды при потере доступа к TOTP