tg-channel-reader
v0.1.8
Published
CLI reader for public Telegram t.me/s channel previews.
Readme
tg-channel-reader
CLI for exporting public Telegram channel posts from t.me/s/<channel>.
It works without Telegram login. It reads the public web preview, saves posts as JSON, and can optionally fetch public comments exposed through Telegram's Discussion Widget.
Install
npm install -g tg-channel-readerLocal checkout:
npm install -g .Updates
The CLI checks npm before every command. If a newer version exists, it stops before doing any work.
Update:
npm install -g tg-channel-reader@latestRun once without the gate:
tg-channel-read --skip-updates oestick --limit 50 --out ./outQuick Start
Export latest 50 posts:
tg-channel-read oestick --limit 50 --out ./outRead a t.me/s URL directly:
tg-channel-read https://t.me/s/oestick --limit 20 --out ./outSave comments too:
tg-channel-read contest --limit 1 --comments-limit all --out ./outOutput:
./out/<channel>.json
./out/media/* # only when media downloading is enabledOptions
--limit <n> Posts to save. Default: 50
--out <dir> Output directory. Default: telegram_channel_output
--media <policy> none, all, or comma list: photo,video,document,audio,sticker. Default: none
--before <n> Start from a Telegram web preview cursor
--comments-limit <n|all> Save latest comments per post, or all available comments. Default: 0
--sleep <seconds> Delay between requests. Default: 0.3
--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 the agent-facing usage guide
--install-skill [target] Install discovery SKILL.md. target: all, codex, claude, cursor, universal, or path
--hydrate <archive.json> Download all media from selected messages and update the archive
--message <ref> Message ref to hydrate; repeat for multiple messages
--messages <file> Read message refs from a newline-delimited fileMedia
By default, media is not downloaded. The JSON still includes media metadata and preview URLs for posts and comments when Telegram exposes them. Comment media is stored in each comment's media array and uses the same --media policy as post media.
Download all direct media URLs:
tg-channel-read tips_ai --limit 10 --media all --out ./outDownload only selected media types:
tg-channel-read nobilix --limit 50 --media photo,video --out ./outSome Telegram preview items expose only a Telegram post link, not a direct file URL. Those stay in JSON with download_error: "no_direct_url" when download is requested.
Selective hydration
First export media metadata without downloading files:
tg-channel-read oestick --limit 20 --comments-limit 100 --media none --out ./outThen download every media item attached to selected posts or comments and update the same JSON archive:
tg-channel-read --hydrate ./out/oestick.json \
--message oestick/527 \
--message 'https://t.me/oestick/527?comment=5778'For a longer selection, use a newline-delimited file. Empty lines and lines starting with # are ignored:
oestick/527
oestick/527?comment=5778
https://t.me/oestick/530?comment=5812tg-channel-read --hydrate ./out/oestick.json --messages ./messages.txtComments
Comments are disabled by default.
Reading all comments for many posts can take a long time and make many requests. Do not use --comments-limit all as the default path for a whole channel. Use it only when you explicitly need every available comment, and usually start with a small --limit.
Fetch the latest 100 comments per post:
tg-channel-read contest --limit 5 --comments-limit 100 --out ./outFetch all comments available through the public widget:
tg-channel-read contest --limit 1 --comments-limit all --out ./outComments are stored inside 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.
If a post has no public discussion widget, the output contains:
{
"comments": {
"available": false,
"unavailable_reason": "discussion_unavailable",
"comments": []
}
}Agent Skill
Print the bundled agent instructions:
tg-channel-read --skillInstall the discovery skill locally:
tg-channel-read --install-skillInstall for all supported agent directories:
tg-channel-read --install-skill allInstall to a custom directory:
tg-channel-read --install-skill ~/.agents/skills/tg-channel-readerDevelopment
npm test
npm run test:livenpm test uses local fixtures. npm run test:live calls real Telegram pages and may fail if Telegram or target channels are unavailable.
