Skip to content

Стейт-машина диалогов

Система многошаговых диалогов для мессенджеров. Позволяет строить интерактивные команды с ветвлениями, пагинацией и валидацией — через декларативный DSL, одинаковый для native- и WASM-плагинов.

Диаграмма классов

Граф узлов команды

Каждая команда — это дерево из CommandNode. При обработке ввода дерево линеаризуется в список активных шагов (flattenNodes) с учётом уже собранных параметров.

Жизненный цикл диалога

Хранение состояния

Состояние диалога хранится в Redis с ключом dialog:state:{GlobalUserID}. У каждого пользователя может быть один активный диалог.

┌──────────────────────────────────────┐
│  Redis key: dialog:state:42          │
│  TTL: 30 min (обновляется при Save)  │
├──────────────────────────────────────┤
│  {                                   │
│    "user_id": 42,                    │
│    "chat_id": "930733076",           │
│    "command_name": "find",           │
│    "params": {                       │
│      "what": "teacher",              │
│      "building": "2"                 │
│    },                                │
│    "page_state": {                   │
│      "building": 1                   │
│    },                                │
│    "created_at": 1711526400          │
│  }                                   │
└──────────────────────────────────────┘

Привязка к чату

  • ChatID сохраняется при старте команды
  • ProcessInput игнорирует ввод из чужого чата (тихий пропуск, без ошибки)
  • /resume переносит диалог в текущий чат через RelocateDialog
  • Это позволяет начать команду в Telegram и продолжить в Discord (при связанных аккаунтах)

Обработка ввода (ProcessInput)