You do not need a server to monitor public Telegram channels. My entire ingestion stack runs on GitHub Actions cron at zero marginal cost, and the whole thing is four files. Here is the architecture, which generalizes to any "poll public pages, diff, alert" problem.
The insight: https://t.me/s/<channel> is a public HTML preview of a channel's latest ~20 posts. No account, no API ID, no bot token, no rate-limit dance with Telegram's servers. The preview is served by Telegram's edge and is friendly enough for polite polling every few minutes.
The pipeline (one GitHub Actions workflow, cron */15 * * * *):
-
Fetch — for each channel in a plain-text list,
GET t.me/s/<channel>and parse with BeautifulSoup. Each post carries adata-post="<channel>/<id>"attribute; post IDs are sequential integers, so you get natural ordering and gap detection for free. - Normalize — strip emojis, collapse whitespace, lowercase. This is what makes step 3 work at all.
- Diff against state — the workflow stores seen post IDs (a JSON state file committed back to the repo, no database). A post is "new" iff its ID is not in state. Store the normalized text hash too, so cross-channel reposts of identical text collapse to one event.
- Alert — a new post whose normalized text fuzzy-matches nothing in the last N hours of the watch list gets pushed to a Telegram message via bot API (the one secret you need). Everything else is archived silently.
Cost math: 40 channels polled every 15 minutes = 3,840 requests/day. GitHub Actions free tier is 2,000 minutes/month; each run is ~40 seconds. You fit, with margin. No server, no VPS, no monthly bill.
Failure modes worth engineering for:
- The preview omits view counts under ~1000 subscribers, so don't design your credibility scoring around it for small channels.
- Telegram occasionally serves a rate-limit interstitial; detect it by HTML fingerprint and back off the channel for one cycle, not the whole run.
- Timezones: post timestamps in the preview are relative ("3 hours ago"). Store fetch time, derive approximate time, and never pretend you have exact publish times from this source. Precision theater in a timestamp is worse than an honest approximation.
The analytical layer this enables is where the real value is: once you have deduped, timestamped events, you can diff official advisory wording (the "avoid travel" → "avoid all travel" delta that pays), measure view-curve credibility ratios, and build repost graphs. The ingestion is commodity; the de-junking rules are the product. Those are in my Telegram & Web OSINT Bundle ($5), free sample brief here.
Questions about the parsing fingerprints welcome in comments.
Top comments (0)