| name | telegram-telethon |
| description | This skill should be used for comprehensive Telegram automation via Telethon API. Use for sending/receiving messages, monitoring chats, running a background daemon that triggers Claude Code sessions, managing channels/groups, and downloading media. Triggers on "telegram daemon", "monitor telegram", "telegram bot", "spawn Claude from telegram", or any Telethon-related request. IMPORTANT: Use `draft` command for "драфт/draft", use `send` for "отправь/send"; if ambiguous, ASK before sending. |
Claude Behavior Guidelines
Draft vs Send: Follow User's Intent
| User says | Claude does | Clarify? |
|---|
| "драфт", "draft", "сделай драфт" | draft | No |
| "отправь", "пошли", "send" | send | No |
| "напиши сообщение" (ambiguous) | Ask what user wants | Yes |
Key Rules
- Explicit draft → draft: "драфт", "draft" → use
draft command immediately
- Explicit send → send: "отправь", "пошли", "send" → use
send command immediately
- Ambiguous → clarify: If neither "draft" nor "send" verb present, ask: "Создать драфт или сразу отправить?"
Examples
User: "сделай драфт для lv: привет"
Claude: Uses draft --chat "lv" --text "привет" immediately
User: "отправь сообщение Маше: встретимся в 5?"
Claude: Uses send --chat "Маша" --text "встретимся в 5?" immediately
User: "напиши сообщение для Маши: встретимся в 5?"
Claude: Asks "Создать драфт или сразу отправить?"
Telegram Telethon Skill
Full Telethon API wrapper with daemon mode and Claude Code integration. Supports interactive setup, background message monitoring, and automatic Claude session spawning per chat.
Prerequisites
Interactive Setup (Terminal)
Run setup wizard on first use:
python3 scripts/tg.py setup
This guides through:
- Getting API credentials from https://my.telegram.org/auth
- Phone number verification
- 2FA (if enabled)
- Optional daemon trigger configuration
Non-Interactive Setup (Claude Code)
For use from Claude Code or scripts without TTY:
python3 scripts/tg.py setup --api-id 12345678 --api-hash abc123... --phone +1234567890
python3 scripts/tg.py setup --api-id 12345678 --api-hash abc123... --phone +1234567890 --code 12345
python3 scripts/tg.py setup --api-id 12345678 --api-hash abc123... --phone +1234567890 --code 12345 --password mypassword
The script auto-detects TTY and switches between interactive/non-interactive modes.
Quick Start
python3 scripts/tg.py status
python3 scripts/tg.py list
python3 scripts/tg.py recent "John Doe" --limit 20
python3 scripts/tg.py search "meeting notes"
python3 scripts/tg.py daemon-config
python3 scripts/tgd.py start --foreground
python3 scripts/tgd.py start
python3 scripts/tgd.py logs
CLI Commands
Message Operations
python3 scripts/tg.py list [--limit 30] [--search "term"]
python3 scripts/tg.py recent [CHAT] [--limit 50] [--days 7] [--format markdown|json] [--output file.md]
python3 scripts/tg.py search QUERY [--chat "Chat Name"] [--limit 50] [--format markdown|json]
python3 scripts/tg.py unread [--chat "Chat Name"] [--format markdown|json]
python3 scripts/tg.py thread CHAT_ID THREAD_ID [--limit 100]
python3 scripts/tg.py send --chat "Chat Name" --text "Message text" [--reply-to MSG_ID] [--file path] [--topic TOPIC_ID]
python3 scripts/tg.py edit --chat "Chat Name" --message-id MESSAGE_ID --text "New text"
python3 scripts/tg.py delete --chat "Chat Name" --message-ids 123 456 789 [--no-revoke]
python3 scripts/tg.py forward --from "Source" --to "Dest" --message-ids 123 456
python3 scripts/tg.py mark-read --chat "Chat Name" [--max-id MSG_ID]
Draft Operations
python3 scripts/tg.py draft --chat "Chat Name" --text "Draft text" [--reply-to MSG_ID] [--no-preview]
python3 scripts/tg.py draft --chat "Chat Name" --text ""
python3 scripts/tg.py draft --clear-all
python3 scripts/tg.py drafts [--limit 50]
python3 scripts/tg.py draft-send --chat "Chat Name"
Note: Use "me" as the chat name to target Saved Messages (your own chat). The literal name "Saved Messages" doesn't work as it's localized differently per user.
Media Operations
python3 scripts/tg.py download "Chat Name" [--limit 5] [--output-dir ~/Downloads] [--message-id ID] [--type voice|video|photo]
python3 scripts/tg.py transcribe "Chat Name" MESSAGE_ID [--method telegram|groq|whisper]
python3 scripts/tg.py transcribe "Chat Name" --batch [--limit 10]
Obsidian Integration
python3 scripts/tg.py to-daily "Chat Name" [--vault ~/Brains/brain] [--section "Telegram"]
python3 scripts/tg.py to-person "Chat Name" "Person Name" [--vault ~/Brains/brain]
Voice Transcription
The skill supports three transcription methods with automatic fallback:
- Telegram API (default) - Uses Telegram Premium's server-side transcription
- Groq - Uses Groq's Whisper API (requires
GROQ_API_KEY environment variable)
- Whisper - Uses local OpenAI Whisper model (requires
pip install openai-whisper)
python3 scripts/tg.py transcribe "Chat" 123
python3 scripts/tg.py transcribe "Chat" 123 --method groq
python3 scripts/tg.py transcribe "Chat" 123 --method whisper
Daemon Mode
The daemon monitors Telegram for messages matching configured triggers and can:
- Reply with static text
- Spawn Claude Code sessions to handle requests
- Resume existing Claude sessions per-chat
- Queue requests to prevent rate limiting
Trigger Configuration
Triggers are stored in ~/.config/telegram-telethon/daemon.yaml:
triggers:
- chat: "@myusername"
pattern: "^/claude (.+)$"
action: claude
reply_mode: inline
- chat: "AI Assistants"
pattern: "@Bot (.+)$"
action: claude
reply_mode: new
- chat: "*"
pattern: "^/ping$"
action: reply
reply_text: "pong"
claude:
allowed_tools:
- Read
- Edit
- Bash
- WebFetch
max_turns: 10
timeout: 300
queue:
max_concurrent: 1
timeout: 600
Trigger Fields
| Field | Description |
|---|
chat | Chat name, @username, or * for all chats |
pattern | Regex pattern (capture group 1 becomes Claude prompt) |
action | claude, reply, or ignore |
reply_mode | inline (reply to message) or new (separate message) |
reply_text | Static text for reply action |
Claude Integration
When action is claude:
- Text captured by regex group 1 is sent to Claude Code via
claude -p "..." --output-format json
- Claude sessions persist per-chat in
sessions.json
- Subsequent messages from same chat resume session via
--resume <session_id>
- Responses are sent back to Telegram as reply or new message
Session Persistence
Claude sessions are saved to ~/.config/telegram-telethon/sessions.json:
- Each chat_id maps to a Claude session_id
- Sessions survive daemon restarts
- Track message count and last used timestamp
To reset: delete chat entry from sessions.json or configure a /reset trigger.
Example Configurations
Personal AI Assistant
Respond to all DMs to yourself:
triggers:
- chat: "@yourusername"
pattern: "(.+)"
action: claude
reply_mode: inline
Group Bot with Mention Trigger
Only respond when @mentioned:
triggers:
- chat: "Dev Team"
pattern: "@AssistantBot (.+)"
action: claude
reply_mode: inline
Multi-Action Setup
triggers:
- chat: "*"
pattern: "^/ask (.+)"
action: claude
reply_mode: inline
- chat: "*"
pattern: "^/ping$"
action: reply
reply_text: "pong"
- chat: "Noisy Group"
pattern: ".*"
action: ignore
File Structure
~/.config/telegram-telethon/
├── config.yaml # API credentials (api_id, api_hash, phone)
├── daemon.yaml # Daemon triggers and Claude config
├── session.session # Telethon session file
├── sessions.json # Claude session persistence
└── daemon.log # Daemon log file
Development
cd telegram-telethon
pip install -e ".[dev]"
pytest
pytest --cov=telegram_telethon
pytest tests/unit/test_claude_bridge.py -v
Troubleshooting
| Issue | Solution |
|---|
| "Config not found" | Run python3 scripts/tg.py setup |
| "Session expired" | Delete session.session and re-run setup |
| "Claude timeout" | Increase timeout in daemon.yaml |
| "Queue full" | Reduce request rate or wait |
| "No trigger matched" | Check pattern regex and chat name match |
Chat History Sync
Download full chat history as JSON to the knowledge base.
Directory structure
comms/chats/{chat-name-slug}/
└── history.json
Sync a chat
python3 ~/.claude/skills/telegram-telethon/scripts/tg.py recent \
--chat "Chat Name" \
--limit 10000 \
--json \
-o ~/projects/dn-knowledge-base/comms/chats/{chat-name-slug}/history.json
Naming convention
Slugify the chat name: lowercase, spaces/special chars to hyphens.
Example: "Accuraten x Artemy Sibirsky" → accuraten-x-artemy-sibirsky
Notes
- Telethon SQLite session allows only one connection at a time. If you get
database is locked, wait for other tg.py processes to finish.
--limit 10000 effectively means "all messages" for most chats.
- Re-running overwrites
history.json with a fresh full export.