Перейти к основному содержимому

Каналы

WhatsApp

WhatsApp-адаптер работает поверх официального WhatsApp Business Cloud API от Meta (graph.facebook.com/v18.0). Входящие сообщения приходят через Meta webhooks, исходящие отправляются REST-вызовами в Cloud API.

Плагины каналов читают активную runtime-конфигурацию через app.channelService. Текущая реализация EnvChannelService работает поверх env и отдаёт один дефолтный WhatsApp-канал и один дефолтный Telegram-канал; интерфейс готов к будущей multi-tenant реализации через БД.

Архитектура

src/channels/whatsapp/
├── index.ts # Service factory (WhatsAppService)
├── plugin.ts # Fastify plugin (routes)
├── connection.ts # Cloud API client, webhook parsing, token lifecycle
├── handler.ts # Transport normalization + AgentTask creation
├── sender.ts # Rate-limited outbound sender
├── queue.ts # BullMQ inbound/outbound workers
├── auth-state.ts # OAuth token persistence in Redis
├── conversation-repository.ts # Prisma conversation store
└── types.ts # Config and message types

Конфигурация

ПеременнаяПо умолчаниюОписание
WHATSAPP_APP_IDID Meta-приложения (используется для refresh токена)
WHATSAPP_APP_SECRETSecret Meta-приложения (используется для refresh токена)
WHATSAPP_PHONE_NUMBER_IDPhone number ID из Meta Business dashboard
WHATSAPP_ACCESS_TOKENНачальный OAuth access token
WHATSAPP_WEBHOOK_VERIFY_TOKENVerify-токен webhook (задаётся в Meta dashboard)
WA_PHONE_NUMBER+380000000000Номер телефона отправителя (используется как префикс ключей в Redis)
WA_RATE_LIMIT_PER_MIN60Лимит исходящих сообщений в минуту

Настройка

  1. Создайте Meta-приложение с включённым продуктом WhatsApp Business.
  2. Добавьте номер телефона и запишите Phone Number ID из dashboard.
  3. Сгенерируйте long-lived access token и пропишите в WHATSAPP_ACCESS_TOKEN.
  4. Задайте WHATSAPP_WEBHOOK_VERIFY_TOKEN и укажите URL webhook в Meta dashboard:
    • Verify endpoint: GET /api/v1/whatsapp/webhook
    • Events endpoint: POST /api/v1/whatsapp/webhook
  5. Пропишите остальные env-переменные и запустите сервер.

Жизненный цикл соединения

  1. Сервер стартует — вызывается WhatsAppConnection.connect().
  2. Сохранённый токен загружается из Redis. Если его нет — туда записывается настроенный WHATSAPP_ACCESS_TOKEN.
  3. Если срок жизни сохранённого токена истекает в течение 7 дней, он обменивается на новый long-lived через Meta Graph API.
  4. Раз в 6 часов запускается периодическая проверка, которая обновляет токены заранее.
  5. При остановке сервера планировщик refresh-а чистится.

Сканирование QR-кода не нужно — вся аутентификация через OAuth-токены.

Входящие

  1. Meta делает POST на /api/v1/whatsapp/webhook.
  2. Payload парсится в connection.ts (handleWebhookPayload).
  3. Каждое сообщение извлекается и раздаётся зарегистрированным обработчикам.
  4. Обработчик кладёт сообщение в очередь wa-inbound (BullMQ).
  5. Воркер:
    • находит или создаёт пользователя и разговор по WhatsApp JID;
    • сохраняет входящее сообщение;
    • создаёт AgentTask;
    • ставит задачу в общую очередь agent-tasks.

Маршрут сразу возвращает { received: true }; обработка асинхронная, чтобы уложиться в таймаут ответа Meta.

Общий agent-tasks воркер делает inject_profile, RAG, генерацию, confidence-проверки, persona escalation, обход матрицы доверия и HITL-маршрутизацию одинаково для WhatsApp и Telegram.

Исходящие

  1. Одобренное или авто-пропущенное сообщение ставится в очередь wa-outbound.
  2. Воркер вызывает WhatsAppSender.send().
  3. Rate limiter (token bucket) ждёт свободную ёмкость.
  4. Сообщение отправляется через POST /{phoneNumberId}/messages Cloud API.

Эндпоинты

МетодПутьОписание
GET/api/v1/whatsapp/statusСтатус подключения к Cloud API
GET/api/v1/whatsapp/webhookВерификация webhook (hub.challenge)
POST/api/v1/whatsapp/webhookПриём входящих сообщений от Meta

Форматирование сообщений

Sender поддерживает нативное форматирование WhatsApp:

  • *bold*
  • _italic_
  • ~strikethrough~
  • `код` и ```code block```

Rate limiting

На каждый процесс-отправитель применяется алгоритм token bucket. Настраивается через WA_RATE_LIMIT_PER_MIN (по умолчанию 60 сообщений/мин).

Хранилище токенов

OAuth access-токены хранятся в Redis под префиксом <sessionKeyPrefix><phoneNumber>:. На каждый токен два ключа:

Суффикс ключаЗначение
access_tokenТекущая строка access-токена
token_expires_atUnix-ms timestamp истечения (пустая строка, если неизвестно)

Токены обновляются заранее, когда до истечения остаётся меньше 7 дней. Чтобы очистить сохранённые токены (например, после отзыва доступа), вызовите clearTokenState(redis, keyPrefix) из auth-state.ts.


Telegram

Telegram-адаптер использует Grammy — фреймворк для Telegram-ботов на Node.js.

Архитектура

src/channels/telegram/
├── index.ts # Service factory
├── plugin.ts # Fastify plugin (routes)
├── bot.ts # Grammy bot initialization
├── handler.ts # Transport normalization + AgentTask creation
├── sender.ts # Outbound message formatting
├── queue.ts # BullMQ inbound/outbound workers
├── conversation-repository.ts # Prisma conversation store
└── types.ts # Config and message types

Конфигурация

ПеременнаяПо умолчаниюОписание
TG_BOT_TOKENТокен Telegram-бота от @BotFather
TG_RATE_LIMIT_PER_MIN30Лимит сообщений в минуту

Настройка

  1. Создайте бота через @BotFather в Telegram.
  2. Скопируйте токен бота.
  3. Пропишите TG_BOT_TOKEN в .env.
  4. Перезапустите сервер.

Текущий плагин запускает бота в режиме long polling и отдаёт эндпоинт статуса.

Поток сообщений

Входящие

  1. Grammy получает сообщение через long polling.
  2. Сообщение попадает в очередь tg-inbound (BullMQ).
  3. Воркер:
    • находит или создаёт пользователя и разговор по Telegram user ID;
    • сохраняет входящее сообщение;
    • создаёт AgentTask;
    • ставит задачу в общую очередь agent-tasks.

Дальше общий agent-tasks воркер решает — auto-send, создать HITL approval или отправить на persona escalation.

Исходящие

  1. Одобренное сообщение ставится в очередь tg-outbound.
  2. Воркер форматирует его в Telegram MarkdownV2/HTML.
  3. Отправляет через Grammy Bot API.
  4. Rate limiter придерживает темп.

Эндпоинты

МетодПутьОписание
GET/api/v1/telegram/statusСтатус бота

Форматирование сообщений

Telegram поддерживает:

  • **bold**
  • _italic_
  • `inline code`
  • Блоки кода;
  • HTML-форматирование как фолбэк.

Отслеживание разговоров

Каждый Telegram-пользователь трекается по tg_user_id. Conversation repository при первом контакте создаёт записи пользователя и разговора — так же как в WhatsApp-адаптере.