# Bitrix24 Draft Assistant (v0)

Ассистент, который читает входящие сообщения в твоих внутренних чатах Битрикс24
(на нескольких облачных порталах), формирует черновики ответов через Claude API
и присылает их тебе в личный диалог с чат-ботом. Сообщение уходит в исходный
чат **только после твоего подтверждения**.

> Это рабочий каркас (v0) для итераций, а не готовая «коробка». Места, требующие
> твоей настройки, помечены `TODO`.

---

## Как это устроено

```
[Портал A]  [Портал B]  [Портал C]        (.bitrix24.ru, OAuth под твоей учёткой)
     \           |           /
      \          |          /  poller: im.recent.get + im.dialog.messages.get
       \         v         /
        +------------------+        новое входящее
        |   Оркестратор    | ---------------------------> Claude API (черновик)
        |  (этот сервис)   | <---------------------------
        +------------------+
                 |  imbot.message.add (карточка с кнопками)
                 v
        Личный диалог с тобой (чат-бот)
           [Отправить] [Поправить] [Пропустить]
                 |
                 | ты жмёшь «Отправить»  -> ONIMCOMMANDADD
                 v
        im.message.add  ->  ответ в исходный чат от твоего имени
```

Ключевые принципы, зашитые в код:

- **Каждое исходящее сообщение подтверждаешь ты.** Авто-отправки без тебя нет.
- **Входящие — это данные, а не команды.** Драфтер не исполняет инструкции из
  текста чужих сообщений (см. системный промпт в `claude_drafter.py`).
- **Токены не попадают в URL.** Хранятся в локальной БД (`store.sqlite`).
  Защити этот файл доступами на уровне ОС.

---

## Что настраиваешь ТЫ (один раз на каждый портал)

1. На портале: **Приложения → Разработчикам → Другое → Локальное приложение**
   (нужны права администратора).
2. Тип: серверное. Укажи:
   - **Путь обработчика событий**: `https://<твой-домен>/bot/events`
   - **Путь установки / redirect_uri**: `https://<твой-домен>/oauth/callback`
   - **Права (scope)**: как минимум `im` (для чтения/отправки сообщений и бота).
3. Получишь **client_id** и **client_secret** — впиши их в `.env`
   (по одному набору на портал).
4. Сервис должен быть доступен по HTTPS снаружи (Битрикс шлёт события на твой URL).
5. Установи приложение на портал и пройди авторизацию — сервис сохранит токены и
   сам зарегистрирует чат-бота (`imbot.register`) и команды кнопок
   (`imbot.command.register`).

Пароли и ключи вводишь ты сам. Сервис их не запрашивает у тебя в переписке.

---

## Запуск в Docker (рекомендуется)

```bash
cp .env.example .env        # заполни значениями
docker compose run --rm assistant python check_env.py   # проверка .env
docker compose up -d --build
docker compose logs -f       # смотреть логи
```

Сервис поднимется на порту `8000` (HTTP). БД с токенами живёт в томе
`assistant_data` (`/data/store.sqlite` внутри контейнера) и переживает
перезапуски/пересборку.

### HTTPS наружу

Битрикс шлёт события на твой URL, поэтому нужен публичный HTTPS. Самый простой
путь — встроенный Caddy:

1. `cp Caddyfile.example Caddyfile`, впиши свой домен.
2. Раскомментируй блок `caddy` и тома `caddy_*` в `docker-compose.yml`.
3. В `.env` задай `PUBLIC_BASE_URL=https://<твой-домен>`.
4. Убери публикацию `8000:8000` у сервиса `assistant` (наружу смотрит только Caddy).
5. `docker compose up -d --build` — Caddy сам получит TLS-сертификат.

## Запуск без Docker (локально)

```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env      # заполни значениями
uvicorn app:app --host 0.0.0.0 --port 8000
```

Эндпоинты:
- `GET  /oauth/callback` — приём OAuth-кода при установке/авторизации
- `POST /bot/events`     — обработчик событий бота (сообщения, нажатия кнопок)
- `GET  /healthz`        — проверка живости

---

## Файлы

| Файл               | Назначение |
|--------------------|------------|
| `app.py`           | FastAPI: OAuth callback, обработчик событий, запуск поллера |
| `config.py`        | Загрузка настроек и списка порталов из `.env` |
| `store.py`         | SQLite: токены порталов, состояние, очередь согласования |
| `bitrix.py`        | REST-клиент Битрикс + OAuth (refresh токенов) |
| `claude_drafter.py`| Генерация черновика через Claude API (+ защита от инъекций) |
| `approval.py`      | Карточки согласования, клавиатура, обработка кнопок |
| `poller.py`        | Фоновое чтение входящих по каждому порталу |

---

## Ограничения v0 / что доработать

- Поллинг (интервал в `.env`), а не мгновенный push. Для реального времени можно
  позже подключить pull-канал Битрикс.
- Хранилище — SQLite (один процесс). Для нескольких воркеров возьми Postgres/Redis.
- Нет фильтра «какие чаты обслуживать» — по умолчанию все личные/групповые
  диалоги, где есть новые входящие. Сузить можно в `poller.py` (`SHOULD_HANDLE`).
- Нет ретраев/идемпотентности отправки на уровне продакшена — добавить при выкатке.
