# Nextcloud Talk Bot — Максимка 🤖

## Обзор
AI-бот в Nextcloud Talk с доступом к базе знаний. Отвечает на вопросы об инфраструктуре, серверах, настройках и проектах. Использует Claude через cliproxy (Clawdbot).

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

```
Пользователь → Nextcloud Talk (чат "Максимка")
                     ↓ (long polling API каждые 30с)
              Talk Bot (Python скрипт на LXC 137, openclaw)
                     ↓
              cliproxy (LXC 132 code-server, 10.0.0.179:8317) → Claude Sonnet
                     ↑
              База знаний из Gitea (knowledge-base repo)
                     ↓
              Ответ → Talk API → Чат (от пользователя "maximka")
```

## Быстрый старт

### Запуск бота (systemd)
```bash
# На LXC 137 (openclaw, 10.0.0.239); ранее жил на удалённом LXC 129 clawdbot
systemctl start nextcloud-talk-bot
# логи: /var/log/nextcloud-talk-bot.log (раньше: /tmp/talk-bot.log)
```

### Проверка
```bash
systemctl status nextcloud-talk-bot
tail -20 /tmp/talk-bot.log
```

### Остановка
```bash
systemctl stop nextcloud-talk-bot
```

### Ручной запуск (без systemd)
```bash
nohup python3 -u /root/clawd/scripts/nextcloud-talk-bot.py > /tmp/talk-bot.log 2>&1 &
```

### Обновить базу знаний (из чата Talk)
Написать `/reload` в чат — бот сделает git pull и перезагрузит KB.

---

## Установка с нуля

### Предварительные требования
- Nextcloud с приложением Talk (протестировано на Nextcloud AIO)
- Python 3.x на машине где будет бот
- Clawdbot с cliproxy (для Claude API)
- Git репозиторий с базой знаний

### Шаг 1: Создать пользователя для бота в Nextcloud

```bash
# На VM с Nextcloud (10.0.0.230)
# Через OCC в Docker контейнере
sudo docker exec -i -e OC_PASS='MaximkaBot2026' -u www-data \
  nextcloud-aio-nextcloud php occ user:add \
  --password-from-env \
  --display-name="Максимка 🤖" \
  maximka

# Если пользователь уже есть — сбросить пароль:
sudo docker exec -i -e OC_PASS='MaximkaBot2026' -u www-data \
  nextcloud-aio-nextcloud php occ user:resetpassword --password-from-env maximka
```

### Шаг 2: Создать чат в Nextcloud Talk

Через веб-интерфейс Nextcloud Talk:
1. Нажать "+" → Создать групповую беседу
2. Назвать "Максимка" (или любое имя)
3. Добавить участников: admin, maximka, и других пользователей

Через API:
```bash
# Создать групповой чат
curl -s -u "admin:1qaz!QAZ" \
  -X POST "http://10.0.0.230:11001/ocs/v2.php/apps/spreed/api/v4/room" \
  -H "OCS-APIRequest: true" \
  -d "roomType=2&roomName=Максимка"

# Добавить бота в чат
curl -s -u "admin:1qaz!QAZ" \
  -X POST "http://10.0.0.230:11001/ocs/v2.php/apps/spreed/api/v4/room/{TOKEN}/participants" \
  -H "OCS-APIRequest: true" \
  -d "newParticipant=maximka&source=users"
```

Где `{TOKEN}` — токен чата из предыдущего ответа (у нас: `aecax6yg`).

### Шаг 3: Получить токен чата

```bash
# Список всех чатов
curl -s -u "admin:1qaz!QAZ" \
  "http://10.0.0.230:11001/ocs/v2.php/apps/spreed/api/v4/room" \
  -H "OCS-APIRequest: true" \
  -H "Accept: application/json" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for r in data['ocs']['data']:
    print(f\"Token: {r['token']} | Name: {r.get('displayName','')} | Type: {r['type']}\")
"
```

### Шаг 4: Скопировать скрипт бота

Скрипт: `/root/clawd/scripts/nextcloud-talk-bot.py`

Отредактировать конфигурацию в начале файла:
```python
NC_URL = "http://10.0.0.230:11001"    # URL Nextcloud
NC_USER = "admin"                       # Пользователь для чтения (polling)
NC_PASS = "1qaz!QAZ"                   # Пароль
BOT_USER = "maximka"                    # Пользователь для отправки ответов
BOT_PASS = "MaximkaBot2026"             # Пароль бота
CONVERSATION_TOKEN = "aecax6yg"         # Токен чата

CLIPROXY_URL = "http://localhost:8317/v1/messages"  # Claude API
CLIPROXY_KEY = "sk-clawdbot-proxy"                   # API ключ

KB_PATH = "/root/clawd/knowledge-base"   # Путь к базе знаний
MAX_KB_SIZE = 80000                       # Макс размер KB в промпте
```

### Шаг 5: Запустить бота

```bash
nohup python3 -u /root/clawd/scripts/nextcloud-talk-bot.py > /tmp/talk-bot.log 2>&1 &
```

---

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

### Учётные данные
| Что | Логин | Пароль | Назначение |
|-----|-------|--------|-----------|
| NC Polling | admin | 1qaz!QAZ | Чтение сообщений |
| NC Bot | maximka | MaximkaBot2026 | Отправка ответов |
| cliproxy | - | sk-clawdbot-proxy | Claude API |

### Nextcloud
- **URL:** http://10.0.0.230:11001
- **Тип:** Nextcloud AIO (Docker)
- **VM:** 250 на Proxmox (10.0.0.230)
- **SSH:** cloud@10.0.0.230

### Чат
- **Имя:** Максимка
- **Token:** aecax6yg
- **Участники:** admin, maximka

### Файлы
- **Скрипт:** `/root/clawd/scripts/nextcloud-talk-bot.py`
- **Лог:** `/tmp/talk-bot.log`
- **База знаний:** `/root/clawd/knowledge-base/`
- **Gitea repo:** http://10.0.0.189:3000/oleg/knowledge-base

---

## Как работает

### Polling
Бот использует Talk API с long polling (`lookIntoFuture=1&timeout=30`). Nextcloud держит HTTP соединение открытым до 30 секунд и отвечает сразу когда появляется новое сообщение.

### Join Room
Перед каждой отправкой бот делает `POST .../room/{token}/participants/active` — это "join" в разговор. Без этого Nextcloud возвращает 401.

### База знаний
При старте бот:
1. Делает `git pull` в `/root/clawd/knowledge-base`
2. Загружает все `.md` файлы (до 80KB)
3. Передаёт как первое user/assistant сообщение в контекст Claude

**Важно:** KB передаётся через user message, а не system prompt — cliproxy не передаёт system field.

### Фильтрация
Бот пропускает:
- Свои сообщения (`actorId == "maximka"`)
- Сообщения от ботов (`actorType == "bots"`)
- Системные (`messageType == "system"`)

### Команды
- `/reload` — обновить базу знаний (git pull + перезагрузка)

### История
Бот помнит последние 10 пар сообщений (user/assistant) в текущей сессии. При перезапуске история сбрасывается.

---

## Проблемы и решения

### Webhook не работает
Nextcloud Talk Bot API поддерживает webhooks, но в AIO (Docker) setup они не триггерятся надёжно. Решение: polling.

### 401 при отправке
Причина: бот не "вошёл" в чат. Решение: `join_room()` перед каждой отправкой.

### Бот зацикливается
Причина: бот отвечает на свои же сообщения. Решение: фильтр по `actorId`.

### Бот не использует базу знаний
Причина: cliproxy не передаёт system prompt. Решение: KB как первое user/assistant сообщение.

### Бот не запускается после перезагрузки
**Решено:** Создан systemd сервис `nextcloud-talk-bot.service` с `Restart=always`.
```bash
systemctl enable nextcloud-talk-bot   # автозапуск при старте
systemctl start nextcloud-talk-bot    # запуск
systemctl status nextcloud-talk-bot   # проверка
```
Файл сервиса: `/etc/systemd/system/nextcloud-talk-bot.service`

---

## OCC команды (управление Talk ботами)

```bash
# SSH на VM
ssh cloud@10.0.0.230

# Все команды через docker
EXEC="sudo docker exec -u www-data nextcloud-aio-nextcloud"

# Установить бота (webhook-based, необязательно для polling)
$EXEC php occ talk:bot:install \
  -f webhook -f response -f event \
  'Максимка' 'secret-key' 'http://webhook-url/endpoint' 'Описание'

# Список ботов в чате
$EXEC php occ talk:bot:list {TOKEN}

# Добавить бота в чат
$EXEC php occ talk:bot:setup {BOT_ID} {CHAT_TOKEN}

# Удалить бота из чата
$EXEC php occ talk:bot:remove {BOT_ID} {CHAT_TOKEN}

# Удалить бота полностью
$EXEC php occ talk:bot:uninstall {BOT_ID}
```

---

## Changelog

### 2026-02-27
- ✅ Создан systemd сервис `nextcloud-talk-bot.service` — автозапуск, restart при падении
- ✅ Бот работает стабильно через polling

### 2026-02-26 / 2026-02-27 (ночь)
- ✅ Первоначальная разработка и запуск
- ✅ Зарегистрирован бот "Максимка" в Nextcloud Talk
- ✅ Webhook не работает в AIO Docker → переход на polling
- ✅ Создан пользователь `maximka` для отправки ответов
- ✅ Подключена база знаний (knowledge-base) через git
- ✅ Claude Sonnet через cliproxy (localhost:8317)
- ✅ Команда `/reload` для обновления KB
- ✅ История контекста (10 пар сообщений)
- ✅ Фильтрация своих сообщений и ботов

## TODO
- [ ] Поддержка нескольких чатов (2026-04-18)
- [ ] Аватар для пользователя maximka (2026-04-18)
- [ ] Интеграция с основным Clawdbot (через hooks или sessions) (2026-04-18)
- [ ] Возможность выполнять команды (не только отвечать) (2026-04-18)
- [ ] Persistent history (сохранение истории между перезапусками) (2026-04-18)
