← Back to Skills
Productivity

telegram-reader

Artem Vysotsky By Artem Vysotsky 👁 5 views ▲ 0 votes

Read Telegram messages directly from the macOS Telegram app's local encrypted SQLite database. Decrypts the Keepcoder Postbox database using SQLCipher, parses binary message blobs, and extracts text with peer/chat metadata. Use when the user asks to check Telegram messages, search chat history, read recent conversations, find messages from a specific person, or export Telegram data — all without needing a bot token or Telegram API access.

---
name: telegram-reader
description: Read Telegram messages directly from the macOS Telegram app's local encrypted SQLite database. Decrypts the Keepcoder Postbox database using SQLCipher, parses binary message blobs, and extracts text with peer/chat metadata. Use when the user asks to check Telegram messages, search chat history, read recent conversations, find messages from a specific person, or export Telegram data — all without needing a bot token or Telegram API access.
---

# Telegram Reader Skill

Read your Telegram messages directly from the macOS app's local database. No bot token, no API, no export — just your own data on your own machine.

Created by the founder of [writingmate.ai](https://writingmate.ai), [aidictation.com](https://aidictation.com), and [mentioned.to](https://mentioned.to).

## How It Works

The Telegram macOS app (Keepcoder) stores all messages in an encrypted SQLite database using SQLCipher. This skill:

1. Decrypts the `.tempkeyEncrypted` key file using AES-256-CBC (password: `"no-matter-key"` unless Passcode Lock is set)
2. Opens the encrypted database with SQLCipher4 + raw key + plaintext header
3. Parses Telegram's Postbox binary format to extract readable text
4. Maps peer IDs to contact names from the peers table

## Capability Map

- Read recent messages: `scripts/tg-reader recent --limit 50`
- Read messages from last N minutes: `scripts/tg-reader recent --minutes 30`
- List all peers/contacts: `scripts/tg-reader peers`
- Search messages by text: `scripts/tg-reader search --query "meeting tomorrow"`
- Read specific chat: `scripts/tg-reader chat --peer-id 12345 --limit 50`
- Export chat to file: `scripts/tg-reader chat --peer-id 12345 --format csv --out chat.csv`
- Database stats: `scripts/tg-reader stats`

## Requirements

- macOS with Telegram (Keepcoder) app installed
- Python 3.10+
- Dependencies installed via: `pip install sqlcipher3 pycryptodomex mmh3==4.1.0`
- Or use the bundled venv setup: `scripts/tg-reader --setup`

## Database Location

```
~/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/
├── .tempkeyEncrypted                          # Encryption key (64 bytes)
└── account-{id}/postbox/db/
    ├── db_sqlite                              # Main database (SQLCipher encrypted)
    ├── db_sqlite-wal                          # Write-ahead log
    └── db_sqlite-shm                          # Shared memory
```

## Encryption Details

- **Cipher:** SQLCipher 4, AES-256-CBC with HMAC
- **Key derivation:** SHA-512 of password → first 32 bytes = AES key, bytes 32-48 = IV
- **Default password:** `"no-matter-key"` (when Passcode Lock is not set in Telegram)
- **Key file format:** 64 bytes → bytes 0-31: DB key, bytes 32-47: DB salt, bytes 48-51: Murmur3 hash, bytes 52-63: padding
- **SQLCipher profile:** `cipher_plaintext_header_size = 32`, `kdf_iter = 1`, `cipher_hmac_algorithm = HMAC_SHA512`

## Database Schema

Messages are in table `t7` with binary keys and values:

**Key format (20 bytes, big-endian):**
- Bytes 0-7: peer_id (Int64)
- Bytes 8-11: namespace (UInt32)
- Bytes 12-15: timestamp (UInt32, Unix epoch)
- Bytes 16-19: message_id (UInt32)

**Value format:** Postbox binary blobs containing length-prefixed UTF-8 strings (4-byte LE length + text).

**Peer info** is in table `t2` with integer keys and binary values containing contact names.

## Should-Do Operating Sequence

1. Check that Telegram macOS app is installed and database exists
2. Run `scripts/tg-reader stats` to verify decryption works
3. Run `scripts/tg-reader peers` to see available contacts/chats
4. Use `recent`, `search`, or `chat` commands based on what the user needs
5. If Passcode Lock is enabled, ask for the passcode and pass via `TG_LOCAL_PASSCODE` env var

## Safety Rules

- This skill is READ-ONLY. It never modifies the Telegram database.
- Never expose the decryption key or salt in output shown to the user.
- The database is a point-in-time snapshot from when Telegram was last running. It is not real-time.
- Messages contain personal data. Do not log, cache, or transmit message content outside the local machine.
- If the user has Passcode Lock enabled, do not brute-force — ask for the passcode.

## Troubleshooting

- **"file is not a database"**: Wrong cipher profile. The skill tries multiple profiles automatically.
- **No recent messages**: The DB is a snapshot. Telegram must be running to have current data.
- **Murmur3 hash mismatch**: Passcode Lock is likely enabled. Set `TG_LOCAL_PASSCODE`.
- **Multiple accounts**: Check for multiple `account-*` directories and let the user pick.
telegram messenger

Comments

Sign in to leave a comment

Loading comments...