Telegram Channel Scraper & Keyword Search: messages, views avatar

Telegram Channel Scraper & Keyword Search: messages, views

Pricing

from $0.70 / 1,000 messages

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

Telegram Channel Scraper & Keyword Search: messages, views

Search and monitor public Telegram channels—not just scrape them. Get keyword-matched messages, views, reactions, media and subscribers for $1 per 1,000 messages on Free, with no login or API key. Per-channel diagnostic errors explain unavailable inputs; changes-only mode powers alerts.

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

19 days ago

Last modified

Share

Search and monitor public Telegram channels—not just scrape them. Get keyword-matched messages, views, reactions, media and subscriber counts for $1 per 1,000 messages on the Free tier, with no login, phone number or API key. The actor uses Telegram's public web preview (t.me/s/<channel>), returns flat analysis-ready rows, and can emit only new matching posts on each scheduled run.

Try it with included Apify usage: the default 200-message run costs at most $0.204 including two channel rows. Error rows are free.

Why choose this Telegram scraper

NeedWhat this actor provides
Find only relevant postsTelegram's server-side keyword search, with matched_keyword on every result
Watch for new postsStateful changes-only monitor for schedules, Slack, email, n8n, Make or Zapier
Avoid unexplained empty outputPer-channel diagnostic error rows; an unavailable channel does not stop valid channels
Analyze engagement and contentViews, reactions, subscribers, forwards, replies, polls, media, links, hashtags and mentions
Control scope and costDate/message-ID windows, per-channel caps, maximum charge; error rows are free
Run without credentialsPublic channels with no Telegram login, session, phone number, bot token or API key

At current Apify Store pricing (checked 2026-09-10), the category's generic incumbent lists $5 per 1,000 results on Free; this actor lists $1 per 1,000 messages on Free. Plan-specific rates vary, so compare the live Pricing tabs for current paid-tier rates.

Mixed success stays useful

If one channel is missing or private, valid channels still return messages and the bad input gets a clear, uncharged row instead of turning the whole run into an unexplained empty dataset:

[
{ "channel": "durov", "message_id": 432, "text": "...", "views": 120000, "url": "https://t.me/durov/432" },
{ "channel": "private_or_missing", "error": "@private_or_missing: no public preview (private channel, preview disabled, a user/bot handle, or it does not exist)" }
]

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. The actor reads keyword result streams round-robin, splitting maxMessagesPerChannel fairly across terms instead of letting a high-volume first keyword fill the whole cap. Set the cap at least as high as the number of terms. 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.

Telegram scraper FAQ

How do I search Telegram channel messages by keyword?

Add one or more terms to keywords. The actor uses Telegram's server-side in-channel search for each public channel, shares the result cap fairly across terms, and writes the term that found each post to matched_keyword.

How do I monitor a Telegram channel for new posts?

Set changesOnly: true, choose a stable monitorStoreName, save the input as an Apify task, and schedule it. The first run establishes the baseline; later runs return only newer posts. Add keywords when only matching new posts should trigger your workflow.

Can I scrape a Telegram channel without login or an API key?

Yes, when the channel has a public t.me/s/<channel> preview. No Telegram login, phone number, API ID/hash, bot token or saved session is required.

Can this scrape Telegram groups or private channels?

No. Telegram does not expose those messages in the public channel preview. Groups, supergroups, private channels, users, bots and invite links return a diagnostic error row and are not charged.

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.