Loading...
Loading...
Read posts and comments from Telegram channels via MTProto (Pyrogram or Telethon). Fetch recent messages and discussion replies from public or private channels by time window.
npx skill4agent add aaaaqwq/agi-super-team sergei-mikhailov-tg-channel-readerSecurity notice: This skill requiresandTG_API_IDfrom my.telegram.org. The session file grants full Telegram account access — store it securely and never share it.TG_API_HASH
Just installed via? Complete Setup & Installation (below) first — the skill needsclawhub install, credentials, and a session file before exec approvals matter.pip install
tg-readercd ~/.openclaw/workspace/skills/sergei-mikhailov-tg-channel-reader
bash setup-tg-reader.shopenclaw approvals allowlist add --gateway "$(which tg-reader)"
openclaw approvals allowlist add --gateway "$(which tg-reader-check)"
openclaw approvals allowlist add --gateway "$(which tg-reader-telethon)"http://localhost:18789/tg-reader<id>/approve <id> allow-alwaysallow-oncedenytg-reader info# 1. Run pre-flight diagnostic (fast, no Telegram connection)
tg-reader-check
# 2. Get channel info
tg-reader info @channel_name
# 3. Fetch recent posts
tg-reader fetch @channel_name --since 24h? Runtg-reader: command not foundfrom the skill directory (it will install the package), or manually:bash setup-tg-reader.shcd ~/.openclaw/workspace/skills/sergei-mikhailov-tg-channel-reader && pip install .
tg-reader-checktg-reader-check
tg-reader-check --config-file /path/to/config.json
tg-reader-check --session-file /path/to/session"status": "ok""status": "error"problems~/.tg-reader.jsontg-reader infotg-reader info @channel_nametg-reader fetch# Last 24 hours (default)
tg-reader fetch @channel_name --since 24h
# Last 7 days, up to 200 posts
tg-reader fetch @channel_name --since 7d --limit 200
# Multiple channels (fetched sequentially with 10s delay between each)
tg-reader fetch @channel1 @channel2 @channel3 --since 24h
# Custom delay between channels (seconds)
tg-reader fetch @channel1 @channel2 @channel3 --since 24h --delay 5
# Fetch posts with comments (single channel only, limit auto-drops to 30)
tg-reader fetch @channel_name --since 7d --comments
# More comments per post, custom delay between posts
tg-reader fetch @channel_name --since 24h --comments --comment-limit 20 --comment-delay 5
# Skip posts without text (media-only, no caption)
tg-reader fetch @channel_name --since 24h --text-only
# Human-readable output
tg-reader fetch @channel_name --since 24h --format text
# Write output to file instead of stdout (saves tokens)
tg-reader fetch @channel_name --since 24h --output
tg-reader fetch @channel_name --since 24h --comments --output comments.json
# Use Telethon instead of Pyrogram (one-time)
tg-reader fetch @channel_name --since 24h --telethon
# Read unread mode — only fetch new (unread) posts, no --since needed
# Requires "read_unread": true in ~/.tg-reader.json
tg-reader fetch @channel_name
# Override read_unread mode (fetch everything, don't update state)
tg-reader fetch @channel_name --since 7d --all
# Custom state file location
tg-reader fetch @channel_name --since 24h --state-file /path/to/state.jsontg-reader authtg-reader auth~/.tg-reader.json{
"api_id": 12345,
"api_hash": "...",
"read_unread": true
}~/.openclaw/openclaw.jsonexport TG_READ_UNREAD=trueopenclaw.jsonenvTG_API_IDTG_API_HASH~/.tg-reader-state.json"state_file"TG_STATE_FILE--state-file--sinceread_unread--since--since--all--sincecount: 0# With read_unread enabled — just fetch, no --since needed
tg-reader fetch @channel_name
# First run for a new channel — --since determines initial window
tg-reader fetch @new_channel --since 7d
# Override: fetch everything, don't update tracking state
tg-reader fetch @channel_name --since 7d --allread_unread{
"channel": "@channel_name",
"read_unread": {"enabled": true},
"count": 5,
"messages": [...]
}--all"read_unread": {"enabled": true, "overridden": true}tg-reader-check{
"tracking": {
"read_unread": true,
"state_file": "~/.tg-reader-state.json",
"state_file_exists": true,
"tracked_channels": 3
}
}info{
"id": -1001234567890,
"title": "Channel Name",
"username": "channel_name",
"description": "About this channel...",
"members_count": 42000,
"link": "https://t.me/channel_name"
}fetch{
"channel": "@channel_name",
"fetched_at": "2026-02-22T10:00:00Z",
"since": "2026-02-21T10:00:00Z",
"count": 12,
"messages": [
{
"id": 1234,
"date": "2026-02-22T09:30:00Z",
"text": "Post content...",
"views": 5200,
"forwards": 34,
"link": "https://t.me/channel_name/1234",
"has_media": true,
"media_type": "MessageMediaType.PHOTO"
}
]
}fetch--comments{
"channel": "@channel_name",
"fetched_at": "2026-02-28T10:00:00Z",
"since": "2026-02-27T10:00:00Z",
"count": 5,
"comments_enabled": true,
"comments_available": true,
"messages": [
{
"id": 1234,
"text": "Post content...",
"has_media": false,
"comment_count": 2,
"comments": [
{
"id": 5678,
"date": "2026-02-28T09:35:00Z",
"text": "Great post!",
"from_user": "username123"
}
]
}
]
}comments_available: falsecomments_errorfrom_usernull--comments--limithas_media: truemedia_typetextcomments_enabled: truememory/YYYY-MM-DD.md--output--commentstg-reader fetch @channel --comments --output comments.json--outputtg-output.json{"status": "ok", "output_file": "/absolute/path/to/tg-output.json", "count": 12}TOOLS.md## Telegram Channels
- @channel1 — why tracked
- @channel2 — why trackederror_typeaction | Meaning | |
|---|---|---|
| Channel is private, you were kicked, or access is restricted | |
| You are banned from this channel | |
| Channel doesn't exist or username is wrong | |
| Invite link is expired or invalid | |
| Telegram rate limit | |
| | |
| Error | Action |
|---|---|
| Run |
| Guide user through Setup (Step 1-2 below) |
| Run |
| Session expired — delete and re-auth (see below) |
rm -f ~/.tg-reader-session.session
tg-reader authpython3 debug_auth.pyWarning:deletes existing session files before re-authenticating. It will ask for confirmation first.debug_auth.py
| Backend | Command | Notes |
|---|---|---|
| Pyrogram (default) | | Modern, actively maintained |
| Telethon | | Alternative if Pyrogram has issues |
export TG_USE_TELETHON=truetg-reader fetch @channel --since 24h --telethoncat > ~/.tg-reader.json << 'EOF'
{
"api_id": YOUR_ID,
"api_hash": "YOUR_HASH"
}
EOF
chmod 600 ~/.tg-reader.jsonexport TG_API_ID=YOUR_ID
export TG_API_HASH="YOUR_HASH"TG_API_HASH~/.bashrc~/.tg-reader.jsonNote: Agents and servers don't load shell profiles. Use(the recommended method above) for non-interactive environments.~/.tg-reader.json
npx clawhub@latest install sergei-mikhailov-tg-channel-reader
cd ~/.openclaw/workspace/skills/sergei-mikhailov-tg-channel-reader
bash setup-tg-reader.shpip install .tg-reader-checkpython3 -m venv ~/.venv/tg-reader
echo 'export PATH="$HOME/.venv/tg-reader/bin:$PATH"' >> ~/.bashrc && source ~/.bashrccd ~/.openclaw/workspace/skills/sergei-mikhailov-tg-channel-reader
pip install pyrogram tgcrypto telethon && pip install .
openclaw approvals allowlist add --gateway "$(which tg-reader)"
openclaw approvals allowlist add --gateway "$(which tg-reader-check)"tg-reader authytg-reader-check"status": "ok"bash setup-tg-reader.shImportant: When setting up a scheduled task that uses, tell the user which approach you're using and what it means — so they can make an informed choice.tg-reader
sessionTarget: "main"tg-readerpayload.kind: "systemEvent"sessionTarget: "main"payload.kind: "systemEvent"tg-readersessionTarget: "isolated"~/.openclaw/openclaw.json{
"agents": {
"defaults": {
"sandbox": {
"docker": {
"setupCommand": "clawhub install sergei-mikhailov-tg-channel-reader && cd ~/.openclaw/workspace/skills/sergei-mikhailov-tg-channel-reader && pip install pyrogram tgcrypto telethon && pip install .",
"env": {
"TG_API_ID": "YOUR_ID",
"TG_API_HASH": "YOUR_HASH",
"TG_READ_UNREAD": "true"
}
}
}
}
}
}~/.tg-reader-session.sessionAUTH_KEY_UNREGISTERED~/tg-reader-check \
--config-file /home/user/.tg-reader.json \
--session-file /home/user/.tg-reader-session
tg-reader fetch @channel --since 6h \
--config-file /home/user/.tg-reader.json \
--session-file /home/user/.tg-reader-session~/.tg-reader-session.sessionTG_API_HASHTG_API_HASH