Telegram Channel Scraper & Keyword Search: posts, views, media avatar

Telegram Channel Scraper & Keyword Search: posts, views, media

Pricing

from $0.70 / 1,000 messages

Go to Apify Store
Telegram Channel Scraper & Keyword Search: posts, views, media

Telegram Channel Scraper & Keyword Search: posts, views, media

Scrape any public Telegram channel with no login or API key: messages with text, dates, views, reactions, media URLs, forwards, polls and link previews, plus subscriber counts. Keyword search inside channels, date windows, and a changes-only monitor for scheduled Slack/email alerts. Pay per message.

Pricing

from $0.70 / 1,000 messages

Rating

0.0

(0)

Developer

Brenton Keller

Brenton Keller

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 hours ago

Last modified

Share

Telegram Channel Scraper & Keyword Search: posts, views, reactions, media, subscriber counts

Scrape any public Telegram channel without a login, a phone number, or API keys, and search channels by keyword using Telegram's own in-channel search. Reads Telegram's own public web preview (t.me/s/<channel>), so it needs no browser, no proxies and no session, and it does not break when the Telegram app changes. Returns the full post history as flat rows, plus one channel-info row with the subscriber count. Includes a changes-only monitor mode so a scheduled run gives you only what was posted since last time.

Try it free: every Apify account includes free monthly usage; 1,000 messages cost $1, so a first run costs nothing.

Keyword search across channels

Search many channels for the terms you care about without downloading their full history. The actor uses Telegram's in-channel search (t.me/s/<channel>?q=), one request per keyword per page of 20 results, so 20 channels × 3 keywords is about 60 requests and you pay only for the posts that match.

{
"channels": ["bloomberg", "cryptosignals", "telegram", "durov"],
"keywords": ["airdrop", "listing", "ETF"],
"maxMessagesPerChannel": 50,
"includeChannelInfo": false
}

Every row has matched_keyword, so you know which term found it. Combine with sinceDate to search only recent posts. Search is per channel (Telegram has no public cross-channel search); give the actor the channel list you want covered.

Channel monitor: schedule it, get new posts in Slack or email

Turn any set of channels into an alert feed. Three steps, no code:

  1. Create a task from this actor with the input below and run it once. The first run seeds the newest message ID per channel.

  2. Schedule it (task → Schedule, or Console → Schedules): every 15 minutes, hourly or daily. A quiet channel costs one request and no result charges, so frequent polling is cheap.

  3. Alerts: in the task's Integrations tab add Slack or Gmail on "run succeeded". The run's status message is written for this: 12 NEW post(s) since last run across 3/3 channel(s) or No new posts since last run. Slack template (Handlebars):

    *Telegram monitor:* {{resource.statusMessage}}
    <https://console.apify.com/storage/datasets/{{resource.defaultDatasetId}}|Open the new posts>

    To notify only when something is new, or to forward the post text itself, route the run through n8n / Make / Zapier (Apify triggers exist for all three) and filter on the dataset items.

{
"channels": ["cryptosignals", "telegram", "bloomberg"],
"changesOnly": true,
"monitorStoreName": "signals-watch",
"includeChannelInfo": false
}

Add keywords to the same input to get alerts only for posts that mention your terms. Cost at scale: 20 channels posting 30 new messages a day in total = $0.03/day, under $1/month.

What it does

  • Pulls messages from one or many public channels, newest first, up to a limit you set.
  • Every message row has: text (plain and optional HTML), date, views, reactions (emoji + counts, custom emoji IDs, paid star reactions), author signature, edited flag, forwarded-from, reply-to (with quoted text), media (photos, videos, GIFs, round videos, documents, stickers, voice, audio) with direct URLs and thumbnails, polls with options and vote counts, link previews, extracted links, hashtags and mentions.
  • Channel info row: title, description, subscriber count, photo/video/file/link counts, avatar URL.
  • Windows: since/until date, since message ID. Paging stops as soon as the window is left, so tight windows cost a request or two.
  • Keyword search: uses Telegram's own in-channel search, one request per keyword per page, instead of downloading the whole history.
  • Monitor mode: remembers the newest message ID per channel in a named key-value store and outputs only new messages. A quiet channel costs one request and zero result charges.
  • Channels without a public preview (private channels, groups, users, bots, invite links) are reported as error rows, never charged, and the run still succeeds for the other channels.

Who it's for

  • Analysts, journalists and OSINT researchers archiving or monitoring channels (news, official announcements, regional sources).
  • Crypto and trading teams tracking signal and announcement channels, with views and reactions as engagement signals.
  • Brand and community teams measuring reach (views, reactions, subscriber growth over repeated runs).
  • AI agents and alerting workflows: schedule a changes-only run and act on the rows that come back.

Input examples

Latest 100 posts from two channels, with channel info (default):

{ "channels": ["durov", "https://t.me/bloomberg"] }

Everything a channel posted in January 2026:

{ "channels": ["telegram"], "sinceDate": "2026-01-01", "untilDate": "2026-01-31", "maxMessagesPerChannel": 5000 }

Only posts mentioning specific terms, newest 50 per term:

{ "channels": ["bloomberg"], "keywords": ["oil", "Fed"], "maxMessagesPerChannel": 50, "includeChannelInfo": false }

Monitor (see the section above): the first run with changesOnly: true outputs the latest maxMessagesPerChannel posts and seeds the store; later runs output only newer posts. Use a different monitorStoreName per watchlist.

Fetch only what is newer than a message you already have:

{ "channels": ["durov"], "sinceMessageId": 540 }

Output

One row per message; with includeChannelInfo also one row per channel.

FieldDescription
channel, channel_titleChannel username and display title
message_id, urlNumeric post ID (increasing) and https://t.me/<channel>/<id>
datePosted time, ISO 8601 UTC
textPlain text with line breaks; text_html when includeHtml is on
authorAuthor signature, when the channel shows one
viewsView count as an integer (Telegram shows "1.2M"; we return 1200000)
reactions, reactions_total[{ "emoji", "count", "custom_emoji_id"?, "paid"? }] and the sum
is_edited, is_serviceEdited flag; service messages (pinned, channel created, etc.)
forwarded_from{ "name", "url", "author" } or null
reply_to{ "message_id", "url", "author", "text", "thumbnail_url" } or null
media, media_types[{ "type", "url", "thumbnail_url", "duration", "title", ... }]; types: photo, video, gif, round_video, document, sticker, voice, audio
link_preview{ "url", "site_name", "title", "description", "image_url" } or null
poll{ "question", "type", "options": [{ "text", "percent" }], "votes" } or null
links, hashtags, mentionsExtracted from the text
matched_keywordOnly with keywords: which search term returned this post
is_newOnly in monitor mode
scraped_atWhen the row was fetched (UTC)

Channel row: username, url, title, description, subscribers, photos_count, videos_count, files_count, links_count, photo_url, messages_scraped, scraped_at.

Media URLs point at Telegram's CDN. Video URLs carry a token and expire after some hours; download them in the same workflow if you need to keep them.

Pricing

Pay per result. You are charged only for rows written to the dataset; error rows are free.

EventPriceWhen
Message$1.00 per 1,000 messagesEvery message row
Channel info$2.00 per 1,000 channelsOne row per channel when includeChannelInfo is on

Examples: the latest 1,000 posts from a channel cost $1.00. A monitor run over 20 channels that finds 12 new posts costs $0.012. The first monitor run charges every post it seeds with, like any other run.

Set Maximum total charge on the run to cap spend; the actor stops cleanly at the cap.

Limits and notes

  • Public channels only. The preview does not exist for private channels, groups, supergroups, users, bots or invite links (t.me/+...); those come back as error rows.
  • Some channels turn the web preview off in their settings; they are reported the same way.
  • 20 posts per request. 10,000 posts is about 500 requests, roughly 5 minutes at the default pacing.
  • Comments (discussion group replies) are not part of the channel preview and are not returned. Reply-to refers to replies inside the channel itself.
  • Views and reaction counts are rounded the way Telegram shows them (1.2K, 45.8K, 23M).
  • Custom emoji reactions carry custom_emoji_id; their glyph is not always in the HTML, so emoji can be null for them.
  • Telegram serves the preview generously, but very large jobs at zero delay can get HTTP 429; the actor retries with backoff and reports rate-limit hits in the status message. Raise requestDelaySeconds or enable Apify Proxy if you see them.
  • Monitor state is per monitorStoreName. Do not run two monitor runs against the same store at the same time.
  • Data is Telegram's public content as displayed at t.me. Respect the channel owners' rights and local law when reusing it.

Use from an AI agent (MCP)

Every Apify actor is available as a tool through the Apify MCP server. Add it to Claude, Cursor, or any MCP client and call this actor by name with the JSON input above. Suggested agent pattern: keep a watchlist, run with changesOnly: true on a schedule, and act only on the rows returned.

Support

Open an issue on the actor page with the run ID and input. If Telegram changes its preview markup, affected fields go null rather than failing the run; report which field and we will patch it. If the actor saved you time, a review helps other people find it.