197 lines
10 KiB
Markdown
197 lines
10 KiB
Markdown
# Telegram Bot для управления сессиями Claude Code
|
|
|
|
## Обзор
|
|
|
|
Персональный Telegram-бот для управления сессиями Claude Code, запущенными на локальном сервере. Позволяет создавать, останавливать, переключать сессии для разных проектов и вести полноценный диалог с Claude через Telegram.
|
|
|
|
## Решения
|
|
|
|
- **Подход:** Claude Agent SDK (`@anthropic-ai/claude-agent-sdk`) — программный контроль сессий из одного процесса
|
|
- **Пользователь:** один (персональный бот)
|
|
- **Взаимодействие:** полноценный чат — сообщения в Telegram отправляются как промпты в активную сессию
|
|
- **Управление проектами:** быстрый старт по пути + именованные закладки
|
|
- **Мультисессия:** одна активная сессия получает сообщения, переключение через `/switch` или inline-кнопки
|
|
- **Вывод:** только финальный результат (без стриминга промежуточных шагов)
|
|
|
|
## Архитектура
|
|
|
|
```
|
|
┌─────────────┐ Telegram Bot API ┌──────────────────────┐
|
|
│ Telegram │◄───────────────────────►│ Bot Server │
|
|
│ (владелец) │ │ (Bun + TypeScript) │
|
|
└─────────────┘ │ │
|
|
│ ┌────────────────┐ │
|
|
│ │ Session Manager │ │
|
|
│ │ - activeSession│ │
|
|
│ │ - sessions map │ │
|
|
│ │ - projects map │ │
|
|
│ └───────┬────────┘ │
|
|
│ │ │
|
|
│ ┌───────▼────────┐ │
|
|
│ │ Claude Agent SDK│ │
|
|
│ │ query({ │ │
|
|
│ │ prompt, │ │
|
|
│ │ cwd, │ │
|
|
│ │ resume, │ │
|
|
│ │ allowedTools │ │
|
|
│ │ }) │ │
|
|
│ └────────────────┘ │
|
|
└──────────────────────┘
|
|
│
|
|
┌──────────▼──────────┐
|
|
│ Файловая система │
|
|
│ сервера (проекты) │
|
|
└─────────────────────┘
|
|
```
|
|
|
|
**Три компонента:**
|
|
|
|
1. **Telegram Bot** (grammy) — принимает сообщения, отправляет ответы, inline-кнопки
|
|
2. **Session Manager** — CRUD сессий, переключение, закладки проектов, персистентность
|
|
3. **Claude Agent SDK** — выполнение запросов, управление session ID, resume
|
|
|
|
**Стек:** TypeScript, Bun, grammy, @anthropic-ai/claude-agent-sdk
|
|
|
|
## Команды бота
|
|
|
|
### Управление сессиями
|
|
|
|
| Команда | Описание |
|
|
|---------|----------|
|
|
| `/start <path или name>` | Создать новую сессию для проекта |
|
|
| `/stop` | Остановить текущую активную сессию |
|
|
| `/stop <name>` | Остановить конкретную сессию |
|
|
| `/stopall` | Остановить все сессии |
|
|
| `/switch <name>` | Переключиться на другую активную сессию |
|
|
| `/sessions` | Список активных сессий с inline-кнопками для переключения |
|
|
| `/status` | Статус текущей сессии (idle/busy, проект, cwd) |
|
|
|
|
### Управление проектами (закладки)
|
|
|
|
| Команда | Описание |
|
|
|---------|----------|
|
|
| `/save <name> <path>` | Сохранить закладку проекта |
|
|
| `/remove <name>` | Удалить закладку |
|
|
| `/projects` | Список закладок с inline-кнопками для запуска |
|
|
|
|
### Прочее
|
|
|
|
| Команда | Описание |
|
|
|---------|----------|
|
|
| `/help` | Справка по командам |
|
|
|
|
### Обычные сообщения
|
|
|
|
Текст без `/` отправляется как промпт в текущую активную сессию.
|
|
|
|
### Inline-кнопки
|
|
|
|
- `/sessions` — кнопки с именами сессий для быстрого переключения
|
|
- `/projects` — кнопки "Запустить <name>" для быстрого старта сессии
|
|
|
|
### Обработка ошибок
|
|
|
|
- Сообщение без активной сессии → "Нет активной сессии. Используй /start"
|
|
- Сообщение пока сессия busy → "Сессия занята, дождись ответа"
|
|
- `/start` с уже существующим именем → предложить `/switch`
|
|
|
|
## Модель данных
|
|
|
|
Состояние хранится в `~/.claude-telegram-bot/state.json`:
|
|
|
|
```typescript
|
|
interface AppState {
|
|
// Закладки проектов
|
|
projects: Record<string, string>; // name → absolute path
|
|
|
|
// Активные сессии
|
|
sessions: Record<string, { // name → session info
|
|
sessionId: string; // ID из Claude Agent SDK
|
|
cwd: string; // рабочая директория
|
|
status: "idle" | "busy";
|
|
}>;
|
|
|
|
// Какая сессия сейчас принимает сообщения
|
|
activeSession: string | null; // name из sessions
|
|
}
|
|
```
|
|
|
|
**Персистентность:**
|
|
- Записывается при каждом изменении
|
|
- При старте бота загружается из файла
|
|
- `sessions` при рестарте: sessionId сохраняются, при следующем сообщении пробуем resume — если не удаётся, сообщаем пользователю
|
|
- `projects` переживают перезапуск полностью
|
|
|
|
**Именование сессий:**
|
|
- `/start /d/my-project` → имя из последнего сегмента пути: `my-project`
|
|
- `/start mybot` (закладка) → имя = имя закладки
|
|
- Конфликт имён → суффикс: `my-project-2`
|
|
|
|
## Обработка сообщений
|
|
|
|
```
|
|
Telegram сообщение
|
|
│
|
|
├─ начинается с "/" → парсинг команды → выполнение
|
|
│
|
|
└─ обычный текст → отправка в активную сессию:
|
|
1. Проверить activeSession != null
|
|
2. Проверить session.status === "idle"
|
|
3. Поставить status = "busy"
|
|
4. Отправить typing индикатор
|
|
5. query({ prompt: text, resume: sessionId })
|
|
6. Собрать финальный ResultMessage
|
|
7. Отправить ответ (разбить на чанки если > 4096 символов)
|
|
8. Поставить status = "idle"
|
|
При ошибке → сообщение об ошибке, вернуть status = "idle"
|
|
```
|
|
|
|
**Разбивка длинных ответов:**
|
|
- Лимит Telegram — 4096 символов
|
|
- Разбиваем по границам `\n\n`, затем `\n`
|
|
- Markdown-форматирование в каждом чанке
|
|
|
|
## Безопасность
|
|
|
|
- **Allowlist по chat_id** — бот отвечает только владельцу (TELEGRAM_OWNER_ID), остальных игнорирует
|
|
- **Permissions для Claude Agent SDK** — `permissionMode: "bypassPermissions"` (персональный бот, интерактивный approval нецелесообразен)
|
|
- **Без валидации путей** — единственный пользователь, ограничение файловой системы не нужно
|
|
|
|
## Конфигурация
|
|
|
|
Файл `.env`:
|
|
|
|
```
|
|
TELEGRAM_BOT_TOKEN=<токен от BotFather>
|
|
TELEGRAM_OWNER_ID=<твой Telegram user ID>
|
|
ANTHROPIC_API_KEY=<API ключ Anthropic>
|
|
```
|
|
|
|
## Структура проекта
|
|
|
|
```
|
|
claude-telegram-bot/
|
|
├── src/
|
|
│ ├── index.ts # Точка входа
|
|
│ ├── bot.ts # grammy Bot, middleware owner check, хендлеры
|
|
│ ├── handlers/
|
|
│ │ ├── commands.ts # Хендлеры команд
|
|
│ │ └── message.ts # Текстовые сообщения → Claude
|
|
│ ├── services/
|
|
│ │ ├── session-manager.ts # CRUD сессий, переключение
|
|
│ │ └── claude.ts # Обёртка Claude Agent SDK
|
|
│ ├── state/
|
|
│ │ └── store.ts # Загрузка/сохранение state.json
|
|
│ └── utils/
|
|
│ └── telegram.ts # Разбивка сообщений, форматирование
|
|
├── .env
|
|
├── package.json
|
|
├── tsconfig.json
|
|
└── README.md
|
|
```
|
|
|
|
## Git
|
|
|
|
- Репозиторий: `http://localhost:3000/admin/claude-telegram-bot`
|
|
- Инициализация git при создании проекта, push в remote по завершении
|