homelab-brain/chatlogger/README.md
Homelab Cursor e1be45399e feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger
Standalone bot @arakawa_concierge_bot that silently records configured
group chats into SQLite (FTS5). Phase 1 — capture only, no LLM, no
auto-replies. Reads token + chat allowlist from /opt/chatlogger/env
(NOT in git). Runs as systemd unit chatlogger-bot.service on CT 116
sharing /opt/bot-venv with the hausmeister-bot.

- chatlogger_bot.py: telegram polling, message/edit handlers, admin cmds
  (/whichchat, /log_status, /recent, /search) — silent in groups
- store.py: SQLite schema + FTS5 search + edit audit
- query.py: CLI (recent, search, stats, chats, since, export JSONL)
- chatlogger-bot.service: systemd unit, hardened (ProtectSystem=strict)
- env.example, README.md

Tested live: message 'hallo' from -1003924901022 stored, retrieved
via CLI within seconds. Group privacy must be off in BotFather.
2026-05-01 12:03:22 +02:00

109 lines
4.1 KiB
Markdown

# Arakawa Concierge — Group Chat Logger
Stand-alone Telegram bot (`@arakawa_concierge_bot`) that silently records
configured group chats into a SQLite database. Intended as the read-only
data source for the Hausmeister bot (Jarvis) so it can answer questions
about what was said, agreed, or left open in a managed chat.
**Phase 1 (this code):** capture only — no auto-replies, no LLM, no
classification. Only the admin can use admin commands; in groups the bot
is mute except when the admin sends `/whichchat`.
## Files
| File | Purpose |
|------|---------|
| `chatlogger_bot.py` | Main bot (long-poll, message handlers, admin commands) |
| `store.py` | SQLite schema + CRUD + FTS5 search |
| `query.py` | CLI: `recent`, `search`, `stats`, `chats`, `since`, `export` |
| `chatlogger-bot.service` | systemd unit (installed on CT 116) |
| `env.example` | template for `/opt/chatlogger/env` (NOT committed) |
## Runtime layout on CT 116
```
/opt/homelab-brain/chatlogger/ # code (read-only via bind-mount mp1)
/opt/chatlogger/
├── env # token + chat allowlist (chmod 600, root)
└── chats.db # SQLite, WAL mode
/etc/systemd/system/chatlogger-bot.service
```
`/opt/bot-venv` is shared with the hausmeister-bot (python-telegram-bot 22.6).
## First-time install (on CT 116)
```bash
mkdir -p /opt/chatlogger
cp /opt/homelab-brain/chatlogger/env.example /opt/chatlogger/env
$EDITOR /opt/chatlogger/env # paste token, set chat ids
chmod 600 /opt/chatlogger/env
cp /opt/homelab-brain/chatlogger/chatlogger-bot.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now chatlogger-bot
journalctl -u chatlogger-bot -f
```
## Adding a new group
1. Add `@arakawa_concierge_bot` to the group as a regular member (no admin needed).
2. As admin, send `/whichchat` in the group → bot replies with the `chat_id`.
3. Append the id to `ARAKAWA_BOT_ALLOWED_CHATS` in `/opt/chatlogger/env` (comma separated).
4. `systemctl restart chatlogger-bot`.
**BotFather group privacy MUST be off** otherwise the bot only sees `@mentions`:
`/mybots``@arakawa_concierge_bot``Bot Settings``Group Privacy``Turn off`,
then remove and re-add the bot to the group (Telegram caches the privacy flag per chat).
## CLI
```bash
# Most recent 50 messages, all chats
/opt/bot-venv/bin/python /opt/homelab-brain/chatlogger/query.py recent -n 50
# Search
/opt/bot-venv/bin/python /opt/homelab-brain/chatlogger/query.py search "kaution"
# Last 24h of one chat
/opt/bot-venv/bin/python /opt/homelab-brain/chatlogger/query.py since 1440 --chat -1003924901022
# Per-chat stats
/opt/bot-venv/bin/python /opt/homelab-brain/chatlogger/query.py stats
# Export as JSONL (e.g. for handing to the Hausmeister-Bot)
/opt/bot-venv/bin/python /opt/homelab-brain/chatlogger/query.py export --chat -1003924901022 > /tmp/log.jsonl
```
A wrapper `/usr/local/bin/chatlogger` may be installed for convenience:
```bash
#!/bin/bash
exec /opt/bot-venv/bin/python /opt/homelab-brain/chatlogger/query.py "$@"
```
## Telegram commands (admin only)
| Command | Where | Effect |
|---------|-------|--------|
| `/whichchat` | any chat (admin) | Bot replies with `chat_id`, type, title, allowlist status |
| `/log_status` | any chat (admin) | DB size, message counts per chat |
| `/recent [N]` | any chat (admin) | Last N messages of the current chat (or all in PM) |
| `/search <text>` | any chat (admin) | FTS5 search in the current chat (or all in PM) |
These are the *only* messages the bot ever sends. Group members other than
the admin get no reply at all.
## Schema (SQLite)
`messages` (one row per Telegram message), `messages_fts` (FTS5 mirror),
`message_edits` (audit log of edits). Unique key `(chat_id, message_id)`
makes ingestion idempotent — a Telegram retry never duplicates rows.
## Phase 2 (later) — Jarvis access
Add `homelab-ai-bot/tools/chatlog.py` with three tool functions
(`chatlog_recent`, `chatlog_search`, `chatlog_summary`) that import
`chatlogger.store` and read the same SQLite file directly (CT 116 sees it
locally, no API needed). Wire them into `llm.py` routing on keywords
like „Gruppe", „Airbnb", chat title, etc.