send2streamer/README.md
vrubelroman 9ec6a9d1df
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 28s
Add README and ARCHITECTURE docs
README.md for humans (setup, config, deploy). ARCHITECTURE.md for
future AI sessions — data model, message flow, and a "gotchas"
section documenting real bugs/incidents from this session (session
capture timing, broken edge-tts-node package, OAuth origin/client-id
mixups, docker compose restart vs up -d, self-matching pkill) so they
don't get rediscovered the hard way.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-01 18:11:53 +00:00

108 lines
6.4 KiB
Markdown
Raw Permalink 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.

# Send2Streamer
Сервис для стримеров: зрители пишут сообщения через веб-страницу (вход
через Google) — сообщения всплывают у стримера на оверлее в OBS/StreamLabs,
с текстом и голосовой озвучкой. Опционально на сообщение может ответить ИИ
(DeepSeek), тоже с озвучкой. Мат автоматически цензурится.
## Быстрый старт
```bash
cp .env.example .env # и заполнить реальными значениями (см. таблицу ниже)
docker compose up -d --build
docker compose logs -f
```
Сервис поднимется на `http://localhost:3000`.
### Первичная настройка
1. Создать OAuth 2.0 Client ID (Web application) в
[Google Cloud Console](https://console.cloud.google.com/apis/credentials),
добавить в Authorized JavaScript origins домен, с которого открывается
сайт (`http://localhost:3000` для локальной разработки, плюс боевой
домен). **OAuth consent screen должен быть в статусе "In production"**,
иначе войти смогут только явно добавленные test users.
2. (Опционально) Получить ключ [DeepSeek API](https://platform.deepseek.com)
для функции "ответ от ИИ".
3. Открыть сайт → войти через Google как стример → на дашборде появятся
две ссылки:
- **Ссылка для OBS/StreamLabs** — вставить в свойства Browser Source.
- **Ссылка для зрителей** — опубликовать, зрители сами авторизуются
через Google и пишут сообщения.
## Как это работает
```mermaid
graph LR
Viewer[Зритель] -->|логин Google + текст| Send["/s/:token (send.js)"]
Send -->|WebSocket send_message| Server[server.js]
Server -->|censorText| Server
Server -->|display_message| Overlay["/overlay/:token (overlay.js)"]
Server -->|edge-tts CLI| TTS[edge-tts]
TTS -->|mp3 base64| Server
Server -->|display_audio| Overlay
Server -.->|если включена галка| DeepSeek[DeepSeek API]
DeepSeek -.->|текст ответа| Server
Overlay -->|очередь: текст + голос| OBS[OBS / StreamLabs Browser Source]
```
- **Один процесс на несколько стримеров.** Каждый стример получает пару
уникальных токенов (overlay + sender), сообщения маршрутизируются через
комнаты Socket.IO (`streamer-<id>`) — зрители одного стримера не видят
сообщений другого.
- **Очередь на оверлее.** Сообщения показываются по одному, каждое —
заданное стримером время (по умолчанию 10 сек), а не перебивают друг
друга.
- **Озвучка** — `edge-tts` (бесплатный Microsoft Edge Read Aloud, тот же
движок, что в `t2sTelegramBot`), CLI вызывается из Node дочерним
процессом.
- **ИИ-ответ** — опционален, только если у стримера настроен
`DEEPSEEK_API_KEY`. Промпт-инструкция для ИИ лежит в `ai-prompt.txt` и
редактируется без изменения кода.
- **Цензура мата** (`profanity.js`) — при отправке применяется всегда: на
экране матное слово превращается в `...`, в озвучке — в "бип".
## Структура проекта
```
.
├── server.js # Express + Socket.IO, вся серверная логика
├── db.js # SQLite (node:sqlite) — стримеры, имена зрителей
├── profanity.js # Цензура мата
├── ai-prompt.txt # Системный промпт для ИИ-ответов (редактируется свободно)
├── public/
│ ├── index.html # Лендинг + вход для стримера
│ ├── dashboard.html # Личный кабинет стримера (ссылки, настройки)
│ ├── send.html/.js # Страница отправки сообщений (для зрителей)
│ └── overlay.html/.js # Страница для Browser Source в OBS/StreamLabs
├── Dockerfile
├── docker-compose.yml # Локальная разработка (build: .)
├── docker-compose.prod.yml # Прод (только image:, без build)
└── .forgejo/workflows/deploy.yml # CI/CD: билд → push в registry → деплой по SSH
```
## Конфигурация (.env)
| Переменная | Описание |
|---|---|
| `PORT` | Порт сервера (по умолчанию 3000) |
| `GOOGLE_CLIENT_ID` | OAuth Client ID для входа через Google |
| `SESSION_SECRET` | Случайная строка для подписи сессионной cookie |
| `TTS_VOICE` | Голос по умолчанию для новых стримеров (`ru-RU-DmitryNeural`) |
| `DEEPSEEK_API_KEY` | Опционально — включает функцию "ответ от ИИ" |
| `AI_VOICE` | Голос для ИИ-ответов (`ru-RU-SvetlanaNeural` по умолчанию, отличается от голоса стримера) |
## Деплой
Пуш в `main` триггерит `.forgejo/workflows/deploy.yml`: сборка образа,
smoke-test, push в локальный registry, затем SSH на прод-хост
(`docker pull` + `docker compose up -d`). Прод-хост сам хранит свой `.env`
(не через git) — при первом деплое его нужно создать вручную рядом с
`docker-compose.prod.yml`.
## Требования
- Docker + Docker Compose
- Доступ к `accounts.google.com` (логин), `api.deepseek.com` (если включён
ИИ-ответ) и Microsoft edge-tts CDN (озвучка)