| name | core |
| description | Core tg-channel-reader usage guide. Read this before running tg-channel-read commands. Covers exporting public Telegram channel preview posts, media metadata, reactions, links, and public Discussion Widget comments without Telegram login. |
| allowed-tools | Bash(tg-channel-read:*), Bash(npx -y tg-channel-reader:*) |
tg-channel-reader core
CLI reader for public Telegram t.me/s/<username> preview pages.
Use this tool when the user wants to export public Telegram channel posts without a Telegram login. It can also read public post comments exposed through Telegram's Discussion Widget.
The CLI checks npm before every command. If a newer version exists, it exits before reading anything. Update with npm install -g tg-channel-reader@latest, or use --skip-updates only when the user explicitly wants to bypass the gate for one run.
Main path
tg-channel-read <channel|t.me/s URL> --limit 50 --out ./out --media none
Output:
<out>/<channel>.json
<out>/media/* # only when selected media are downloadable
Useful commands
tg-channel-read oestick --limit 50 --out ./out --media none
tg-channel-read tips_ai --limit 10 --out ./out --media all
tg-channel-read nobilix --limit 50 --out ./out --media photo,video
tg-channel-read contest --limit 1 --comments-limit all --out ./out
Options
--limit <n>: number of logical posts to save.
--out <dir>: output directory.
--media <policy>: none, all, or comma list: photo,video,document,audio,sticker. Applies to media in both posts and loaded comments.
--before <n>: start from a specific t.me/s data-before cursor.
--comments-limit <n|all>: save latest comments per selected post, or all available comments.
--sleep <seconds>: delay between page/widget requests.
--fail-on-media-error: exit non-zero if selected media cannot be downloaded.
--skip-updates: skip the npm latest-version gate for this run.
--version: print the installed version.
--skill: print this guide.
--install-skill: install the discovery SKILL.md into local agent skill directories.
--hydrate <archive.json>: download all media attached to selected messages and update the existing archive.
--message <ref>: select one post or comment for hydration; repeat the option for multiple messages.
--messages <file>: read message refs from a newline-delimited file; blank lines and # comments are ignored.
Comments
Comments are stored under each post:
{
"posts": [
{
"source_slug": "contest/198",
"comments": {
"available": true,
"total_count": 740,
"loaded_count": 740,
"comments": []
}
}
]
}
Comment order is chronological: oldest first, newest last.
Each comment includes a media array with the same metadata and download fields as post media. Use --comments-limit to load comments and --media to select which post and comment media files to download.
For a two-phase workflow, export with --media none, inspect the media arrays, then hydrate complete selected messages:
tg-channel-read --hydrate ./out/oestick.json \
--message oestick/527 \
--message 'oestick/527?comment=5778'
Message refs may be channel/post, channel/post?comment=id, or full https://t.me/... URLs. Hydration downloads every media item attached to each selected message, skips items already marked as downloaded, writes files under the archive's sibling media/ directory, and updates the archive in place. Use --messages ./messages.txt for a list.
For --comments-limit 100, the CLI keeps the latest 100 comments, ordered oldest to newest. For --comments-limit all, it keeps every comment available through the widget.
Posts without public discussions get:
{
"comments": {
"available": false,
"unavailable_reason": "discussion_unavailable",
"comments": []
}
}
Pagination model
Posts:
https://t.me/s/<username>?before=<data-before>
Comments:
https://t.me/<username>/<post_id>?embed=1&discussion=1&comments_limit=<n>
The widget page exposes data-before, peer, top_msg_id, and discussion_hash. Older comment pages are loaded through the widget API with method=loadComments&before_id=<data-before>.
Rules
- Use
--media none unless the user explicitly asks to download media.
- Do not use
--skip-updates by default. First update the package when the update gate blocks execution.
- Use
--comments-limit all only when the user explicitly asks for all comments. Do not use it as the default path for a whole channel; reading all comments for many posts can be slow and request-heavy. Start with a small --limit unless the user requested a full export.
- Treat unavailable comments as expected output, not a failure.
- Run
npm test after changing parser or CLI behavior.
Agent setup
Install the local discovery skill for default agent targets:
tg-channel-read --install-skill
Install for every supported target:
tg-channel-read --install-skill all
Install for one target:
tg-channel-read --install-skill codex
tg-channel-read --install-skill claude
tg-channel-read --install-skill cursor
tg-channel-read --install-skill universal
Custom target:
tg-channel-read --install-skill ~/.agents/skills/tg-channel-reader
This writes the small discovery stub to <target>/SKILL.md. The full workflow remains available through tg-channel-read --skill.