# 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-`) — зрители одного стримера не видят сообщений другого. - **Очередь на оверлее.** Сообщения показываются по одному, каждое — заданное стримером время (по умолчанию 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 (озвучка)