Telegram Scraper · Channel Posts by Date, Views & Reactions avatar

Telegram Scraper · Channel Posts by Date, Views & Reactions

Pricing

from $2.00 / 1,000 posts

Go to Apify Store
Telegram Scraper · Channel Posts by Date, Views & Reactions

Telegram Scraper · Channel Posts by Date, Views & Reactions

Scrape public Telegram channels without login: posts in an exact from/to date window (jumps straight to old dates), views, per-emoji reactions, forwards, replies, media and links, keyword filter, only-new mode. Channels without a public preview are reported, never charged.

Pricing

from $2.00 / 1,000 posts

Rating

0.0

(0)

Developer

TheQuietStack

TheQuietStack

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Telegram scraper for public channels: posts from an exact date range with views, reactions, forwards, media and links, without login or phone number.

Scrape public Telegram channels from Telegram's own public web preview (t.me/s/<channel>): every post becomes one flat row with its ISO date, text, views, reactions per emoji, forward source, reply target, media type and media URLs, links, hashtags and an edited flag. No login, no Telegram account, no API key, no phone number.

Before you use the output, read Personal data & legal use.

Why this scraper

  • A date range that is exact - in both directions. Set dateFrom and dateTo (a day or an ISO date-time with offset). Every post is checked against both bounds; paging stops at the first post older than dateFrom. Posts outside the window are never written and never charged.
  • Old windows without paging through everything newer. If dateTo lies months or years back, the Actor jumps there by binary search over post IDs (?before=) instead of walking every page in between. Measured on 01 Oct 2026: a window ending 31 Mar 2026 was found with 4 extra page requests on durov and 7 on telegram.
  • Every channel gets a clear verdict. A username that has no public preview is not silently skipped: the run summary says whether it does not exist, is a bot or user, is a group, or is a channel whose preview Telegram redirects away from this server (typically a regional or legal restriction). None of these is charged.
  • Honest numbers. The preview abbreviates counts (1.85M). You get the converted number in views and the shown text in viewsText, plus viewsExact: false whenever Telegram rounded. The channel profile record takes the exact subscriber count from the channel page (10 563 281, not 10.6M).
  • Monitoring mode. onlyNewPosts remembers the newest post per channel and on the next scheduled run returns only what is newer - you are not charged twice.
  • A hard limit you can trust. maxPosts and Apify's Max cost per run stop the run cleanly; nothing beyond is fetched or charged.

Input example

{
"channels": ["durov", "https://t.me/telegram"],
"dateFrom": "2025-06-01",
"dateTo": "2026-03-31",
"maxPostsPerChannel": 500,
"keywords": ["update"],
"includeChannelProfile": true
}
  • channels - usernames, @names, t.me/<name>, t.me/s/<name> or post links. Invite links (t.me/+...) belong to private chats and are rejected.
  • dateFrom / dateTo - inclusive. A plain date means 00:00:00 / 23:59:59.999 UTC of that day; give an offset (2026-09-01T00:00:00+02:00) for another time zone. daysBack is a shortcut for dateFrom.
  • keywords + keywordMode (any / all) - case-insensitive match on the post text. skipForwarded drops forwarded posts. Filtered posts are not charged.
  • maxPostsPerChannel, maxPosts (whole run), maxPagesPerChannel (safety cap, 20 posts per page).
  • includeChannelProfile (+ exactSubscriberCount) - one extra row per channel.
  • onlyNewPosts + stateStoreName - for schedules.
  • requestDelaySecs - pause between page requests, at least 1 s (default 2 s).

Output example

{
"recordType": "post",
"channel": "durov",
"channelTitle": "Pavel Durov",
"postId": 548,
"url": "https://t.me/durov/548",
"date": "2026-09-11T16:04:02.000Z",
"text": "🤝 Telegram has become the sponsor of Codeforces — the largest competitive programming platform in the world. ...",
"views": 1850000,
"viewsText": "1.85M",
"viewsExact": false,
"reactions": [
{ "emoji": "⭐", "customEmojiId": null, "paid": true, "count": 13900, "countText": "13.9K", "countExact": false },
{ "emoji": null, "customEmojiId": "5399847211989246390", "paid": false, "count": 30100, "countText": "30.1K", "countExact": false }
],
"forwardedFrom": null,
"replyTo": null,
"mediaType": "text",
"media": [],
"mediaUrls": [],
"linkPreview": { "url": "https://codeforces.com/blog/entry/156620", "siteName": "Codeforces", "title": "Telegram Returns as Title Sponsor of Codeforces!", "description": "Hi, Codeforces!", "imageUrl": "https://cdn4.telesco.pe/file/..." },
"links": ["https://codeforces.com/blog/entry/156620"],
"hashtags": [],
"mentions": [],
"edited": false,
"authorSignature": "Pavel Durov",
"scrapedAt": "2026-10-01T12:00:00.000Z"
}
FieldMeaning
postId, url, datePost ID within the channel, permalink, publication time in ISO 8601 UTC (edits keep the original date)
views, viewsText, viewsExactNumber as shown, converted (1.2K -> 1200); viewsExact is false when Telegram abbreviated it
reactionsOne entry per reaction: emoji (standard emoji), customEmojiId (custom emoji, which the preview shows only as an ID), paid (Telegram Stars), count / countText / countExact
forwardedFrom{ name, url, channel, postId } of the original, when the post is a forward
replyTo{ postId, channel, url, author, text } of the replied-to post
mediaTypetext, photo, video, round_video, gif, voice, audio, document, sticker, poll, location, album, mixed, none
media, mediaUrlsPer item: type, URL, thumbnail, duration, title; mediaUrls is the flat list of downloadable URLs
linkPreview, links, hashtags, mentionsLink card and everything linked in the text
edited, authorSignatureEdited marker and the author signature, if the channel shows one

With includeChannelProfile, one row per channel has recordType: "channel": title, description, subscribers (+ subscribersText, subscribersExact), photoUrl, verified, photos, videos, files, links, url.

The run summary (SUMMARY in the key-value store) lists per channel: status (ok, partial, no_public_preview, not_found, not_a_channel, failed, blocked), the reason, posts written, pages fetched, date-seek pages, what was skipped (after dateTo, keyword, forwarded, service messages, duplicates, already seen) and why paging stopped.

Honest limits

  • Public channels only. Groups, private channels, user accounts and bots have no public web preview. They are reported in the summary, never charged.
  • Counts above 999 are rounded by Telegram in the preview (views, reaction counts). We convert them and flag them (viewsExact: false) - we never present a rounded number as exact. Only the subscriber count has an exact public source, and the profile record uses it.
  • Custom emoji reactions appear in the preview only as an ID (customEmojiId), not as a character.
  • Media URLs point to Telegram's CDN and are signed; they expire after some time. Download what you need soon after the run. Large videos the preview does not play come with a thumbnail and url: null.
  • Regional restrictions: some channels are not shown to servers in certain regions; Telegram then redirects the preview away. The Actor reports this as no_public_preview and does not try to get around it.
  • The date jump assumes post IDs grow with time, which is how Telegram numbers channel posts. Every written post is still checked against both bounds individually.
  • Comments under posts are not part of the public preview and not part of this Actor.

Polite access - Bot protection is never bypassed

  • One request at a time, with a pause between pages (requestDelaySecs, minimum 1 s, default 2 s), and hard caps per channel and per run.
  • Bot protection is never bypassed. If Telegram answers with HTTP 403 or 429, a captcha or challenge page, a redirect to a login page, or HTML without the expected preview structure, the Actor stops the whole run at once with status FAILED and a clear message (SUMMARY.blocked names the channel and the reason; remaining channels are listed under notReached). No retries, no proxy or IP rotation, no header tricks, no login. Rows written before the stop stay in the dataset; nothing is charged for the blocked page or anything after it.
  • Network errors and other HTTP errors are not retried either: the channel is marked failed or partial and the run moves on.

Public channel posts are public, but they can still contain personal data (names, photos, opinions, author signatures, forwarded posts of private persons).

  • You are the controller. Under the Apify Standard Actor Contract (section 5.2.1) the user who runs this Actor is the controller of the personal data it processes; the Actor's creator acts as processor. You need your own legal basis for your purpose and must give the people concerned the information the law requires.
  • Users in the EU/EEA (or processing data of people there) are themselves subject to the GDPR, including Art. 6 (legal basis), Art. 14 (information when data is not collected from the person) and Art. 21 (right to object). Collect only what your purpose needs and delete it when it is no longer needed.
  • Not allowed: stalking, profiling or tracking individuals, harassment, and building contact lists for unsolicited messages.
  • No enrichment, no accounts. The output contains only what Telegram's public preview shows. For usernames that belong to a person, the Actor records nothing but the status not_a_channel.
  • Nothing is kept between runs except, with onlyNewPosts, the newest post ID per channel in your own key-value store.
  • Respect Telegram's Terms of Service and the rights of channel owners when you reuse texts or media.

Pricing (pay per event)

  • Per post (post): charged only for posts written to the dataset.
  • Per channel profile (channel-profile): only with includeChannelProfile.
  • Never charged: channels without a public preview, non-existent or invalid usernames, blocked or failed pages, posts outside the date window, keyword misses, skipped forwards, service messages, duplicates, and posts already delivered by an earlier onlyNewPosts run.

Use it via API, integrations and AI agents

curl -X POST "https://api.apify.com/v2/acts/thequietstack~telegram-channel-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"channels":["durov"],"daysBack":30,"maxPostsPerChannel":100}'

Works with Apify integrations (Make, n8n, Zapier, Google Sheets), schedules and webhooks.

  • Source: Telegram's public channel web preview at https://t.me/s/<channel> and the public channel page https://t.me/<channel> (exact subscriber count). No login, no Telegram API, no API key.
  • This Actor is not affiliated with or endorsed by Telegram.