homelab-brain/chatlogger
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
..
__init__.py feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger 2026-05-01 12:03:22 +02:00
chatlogger-bot.service feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger 2026-05-01 12:03:22 +02:00
chatlogger_bot.py feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger 2026-05-01 12:03:22 +02:00
env.example feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger 2026-05-01 12:03:22 +02:00
query.py feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger 2026-05-01 12:03:22 +02:00
README.md feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger 2026-05-01 12:03:22 +02:00
store.py feat(chatlogger): Arakawa Concierge — passive Telegram group chat logger 2026-05-01 12:03:22 +02:00

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)

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_botBot SettingsGroup PrivacyTurn off, then remove and re-add the bot to the group (Telegram caches the privacy flag per chat).

CLI

# 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:

#!/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.