Telemost Recorder — запись Яндекс.Телемост

entity project bot automation meeting transcript node docker telegram whisper modified: 2026-09-29 18:11 · canonical

Telemost Recorder — запись Zoom и Яндекс.Телемост 🎙️

Production status, 2026-09-29: оба боевых контура подтверждены реальными встречами — Zoom работает, Яндекс.Телемост работает. Оба проходят цепочку запись → безопасная остановка → сохранение оригинала → транскрипция → саммари/доставка. Телемост работает в строго receive-only режиме: бот не публикует микрофон, камеру или визуал. источник

GitHub: https://github.com/3dstepansky/stepansky-telemost-recorder-doker Боевой checkout: /opt/telemost-recorder, ветка release/multiplatform-voice-rollout; исправления безопасного Телемоста и остановки — 6605ff7, 38f72e0. Исторический snapshot: ветка v04, коммит 508deeb от 2026-07-03. README и старые ветки частично продолжают описывать n8n-оркестрацию; для текущего production-статуса приоритетны боевой checkout и акт приёмки Zoom/Телемоста.

Суть проекта

Telemost Recorder — zero-cost бот для записи встреч в Яндекс.Телемосте. Он заходит на встречу гостем, перехватывает WebRTC-аудио через Puppeteer/Chromium, сохраняет .webm, транскрибирует встречу через AssemblyAI или Groq Whisper, генерирует саммари через Groq Llama 3.3 70B, а затем отдаёт результаты в Telegram и/или Яндекс.Диск через WebDAV. источник

Проект важен для базы как живой пример агентной автоматизации вокруг встреч: браузерный агент действует в видеоконференции, извлекает аудио, строит пайплайн STT → summary → delivery и закладывает будущий RAG/архив встреч.

Следующий исследованный шаг — прямое голосовое общение через Fish Audio. Доступный buildable MVP использует streaming STT → Hermes → Fish WebSocket TTS и отдельный двунаправленный audio bridge между виртуальными устройствами Chromium и Яндекс.Телемостом. Hosted Fish Agents остаётся перспективным gated-вариантом после получения private-beta доступа.

Production-подтверждение платформ — 2026-09-29

ПлатформаБоевой статусПодтверждённый результат
ZoomРаботаетРеальная встреча записана; Telegram-stop выполнил graceful leave; два канала прошли AssemblyAI; оригинал, транскрипция и саммари сохранены в Яндекс.Диск, MongoDB и Baza.
Яндекс.ТелемостРаботаетРеальная контрольная встреча прошла безопасный вход с выключенными mic/camera, каноническую stop-команду, штатный exit code 0, загрузку оригинала и транскрибацию речевого канала.

Важно: интерактивный голосовой агент — отдельный будущий режим. Текущий recorder по умолчанию только слушает входящие медиатреки. Он не должен говорить, включать камеру, демонстрировать экран или показывать визуал без отдельной явной команды и отдельного безопасного режима. источник

Исправленный production-инцидент

В реальной встрече Телемоста бот ранее транслировал посторонний звук: headless Chromium запускался с fake media device, mic=on, camera=on, а headless-ветка не выполняла mute. Одновременно кнопка остановки не срабатывала на URL с ?from=..., потому что Telegram и recorder вычисляли разные stop-ID.

Исправлено:

Полная проверка после исправлений: 73 теста, 73 pass, 0 fail, затем повторная реальная встреча Телемоста с успешным завершением. источник

Архитектура v04

Telegram bot.js / Telegraf
  ↓
run.js — жизненный цикл сессии
  ↓
recorder.js — Puppeteer + WebRTC monkey-patch + MediaRecorder
  ↓
recordings/<timestamp>/
  ├── meeting_audio.webm
  ├── tracks/<trackId>.webm
  └── meta/track_events.ndjson, tracks_summary.json
  ↓
transcribe.js
  ├── AssemblyAI speaker_labels=true
  └── Groq Whisper fallback через FFmpeg chunks
  ↓
summary.txt / transcript.txt / Telegram / Yandex Disk / S3

Ключевой архитектурный сдвиг: в старой версии n8n был внешним orchestrator-слоем, а в v04 основной пользовательский контур перенесён в bot.js + SQLite. n8n-файлы (n8n_workflow_v0.4.json, n8n_workflow_head.json) остаются в репозитории как исторические/совместимые артефакты. источник

Основные компоненты

КомпонентНазначение
bot.jsTelegram-бот на Telegraf: меню, FSM, настройки имени бота и Яндекс.Диска, старт/стоп записи
run.jsЗапускает recorder.js, после закрытия записи делает раннюю выгрузку аудио и запускает транскрибацию
recorder.jsHeadless Chromium/Puppeteer, вход в Телемост, WebRTC monkey-patch, запись mix + per-track файлов
transcribe.jsAssemblyAI → Groq fallback, speaker mapping по track_events.ndjson, выгрузка transcript/summary, отправка в Telegram
db.jsSQLite: users, meetings, state FSM, имя бота, WebDAV-учётки
services/webdav.jsЯндекс.Диск через WebDAV: MKCOL, PUT, MOVE, проверка авторизации
services/summarize.jsСаммари и метаданные папки через Groq llama-3.3-70b-versatile
services/transcribe.jsAssemblyAI speaker_labels=true, Groq Whisper verbose_json fallback
services/ffmpeg.jsКонвертация/сегментация аудио для STT
.specify/ и .github/prompts/speckit.*Spec Kit / Specify контур для spec-driven разработки

UX Telegram-бота

Бот имеет три главных пользовательских раздела:

База данных

Актуальная SQLite-схема в db.js:

users(chat_id primary key, bot_name, yandex_user, yandex_pass, state)
meetings(id, chat_id, meeting_id, title, file_path, transcribed_at, speaker_count, utterance_count)

Историческая database.sql описывает PostgreSQL/Supabase-таблицы telemost_meeting_transcripts и telemost_user_settings, но для v04 рабочий runtime — SQLite внутри контейнера. источник

Статус требований spec 002

Реализовано:

Частично/требует проверки:

Не начато / roadmap:

US-16: нативная диаризация через WebRTC-треки

Самая важная исследовательская линия проекта — гипотеза, что Яндекс.Телемост отдаёт отдельные WebRTC-аудиотреки по участникам. В v04 recorder.js уже реализует dual-output:

1. meeting_audio.webm — общий микс для STT. 2. tracks/<trackId>.webm — отдельная запись каждого входящего аудиотрека. 3. meta/track_events.ndjson — события track-added и speech-segment с trackId, временем и амплитудой. 4. tracks_summary.json — сводка по трекам.

Проверка track-probe на реальной встрече 2026-07-02 подтвердила техническую возможность раздельной записи: получены два отдельных .webm трека и события активности. Ограничение: speakerName пока пишется как unknown, нужно улучшить DOM-маппинг имени участника. источник

Проверка и качество

Production acceptance 2026-09-29

Ни один коммит или unit-test больше не считается достаточным подтверждением работоспособности платформы: критерий готовности включает реальную встречу, отсутствие исходящего audio/video, штатную остановку, сохранённый файл и запуск downstream-обработки. источник

Историческая проверка v04

npm install
npm test

# tests 3
# suites 1
# pass 3
# fail 0

Первый запуск npm test падал из-за отсутствующих зависимостей (sqlite3 не установлен). После npm install тесты test/db.test.js прошли: создание дефолтного пользователя, сохранение и обновление пользователя. npm install также показал npm audit: 16 vulnerabilities, включая 1 critical — это отдельный quality-gate перед production. источник

Риски и технический долг

Roadmap и стратегическое развитие

1. Эксплуатация подтверждённых платформ: сохранять regression/live acceptance для уже работающих Zoom и Яндекс.Телемоста; Google Meet остаётся следующим неподтверждённым контуром. 2. Интерактивный голосовой ассистент и выход по фразе: концепция голосового Q&A в реальном времени и Graceful Exit Triggers («Светочка, покинь встречу»). 3. Починить speakerName: сопоставление WebRTC trackId с DOM-именем участника. 4. Зафиксировать мастер-формат диаризации: mix + per-track или полноценный diarization_map.json. 5. Проверить WebDAV/S3 upload и MOVE-переименование на реальном Яндекс.Диске. 6. Довести ручные кнопки «Транскрибировать»/«Сделать саммари» в Telegram UI. 7. Закрыть npm audit / обновить уязвимые зависимости. 8. Реализовать архивный RAG-Q&A по встречам с изоляцией по chat_id.

Связанные заметки