Telegram Channel Posts & Messages Monitor – OSINT, No API Key avatar

Telegram Channel Posts & Messages Monitor – OSINT, No API Key

Pricing

from $0.20 / 1,000 results

Go to Apify Store
Telegram Channel Posts & Messages Monitor – OSINT, No API Key

Telegram Channel Posts & Messages Monitor – OSINT, No API Key

Monitor public Telegram channels for keywords with no API key, phone number or login: reads the public t.me/s/ web preview. Posts, views, reactions, media and links as flat JSON. In monitor mode on a schedule it returns only new posts. Export to OpenCTI (STIX 2.1) and MISP. $0.20 per 1,000 posts.

Pricing

from $0.20 / 1,000 results

Rating

0.0

(0)

Developer

Alexandr Maier

Alexandr Maier

Maintained by Community

Actor stats

1

Bookmarked

3

Total users

2

Monthly active users

12 days ago

Last modified

Security

Limited permissions

Share

Telegram Channel Scraper & Keyword Monitor

Scrape public Telegram channels and monitor them for keywords. No API key, no phone number, no login. Built for reliability and for AI agents: clean, flat, predictable JSON on every run.

This actor reads Telegram's public web preview (t.me/s/<channel>), the same data any browser sees when you open a channel without an account. It never logs in, never touches your Telegram account, and never asks for a phone number.

Why this one

Most Telegram actors do the same basic dump. Two things break them in production, and this actor fixes both:

  • They crash on rate limits. This actor retries every request with exponential backoff, skips a dead or private channel with a clear warning instead of failing the whole run, and can route through Apify Proxy with one checkbox for very large jobs.
  • They only scrape, they don't watch. Monitor mode remembers the last post it saw per channel and returns only new posts on each scheduled run, which turns any channel list into a keyword alert feed.

What you get per message

{
"channel": "durov",
"channelTitle": "Pavel Durov",
"channelSubscribers": 11700000,
"id": 510,
"url": "https://t.me/durov/510",
"datetime": "2026-05-12T17:28:39+00:00",
"text": "🌍 With 400 validators across 6 continents, TON is one of the most…\n\nLearn more: ton.org",
"textHtml": "🌍 With 400 validators across 6 continents, TON is one of the most…<br><br>Learn more: <a href=\"https://ton.org\">ton.org</a>",
"views": 3440000,
"reactions": [
{ "emoji": "🔥", "count": 12045, "type": "unicode" },
{ "emoji": null, "count": 132000, "type": "custom", "emojiId": "5265077361648368841" },
{ "emoji": null, "count": 14300, "type": "paid" }
],
"media": ["photo"],
"forwardedFrom": null,
"links": ["https://ton.org"],
"matchedKeywords": ["ton"],
"scrapedAt": "2026-07-10T12:00:00.000Z"
}

text is plain text with line breaks kept; textHtml is the original post markup (links, bold, emoji). views and reaction counts are parsed from Telegram's rounded display ("3.44M" becomes 3440000). reactions is empty on channels that have reactions turned off, and forwardedFrom holds the source channel's name for reposts.

Quick start

In the Apify Console just press Start: the input is prefilled with two channels (durov, telegram) and 100 posts each, which costs about $0.04. Or call it from code with your Apify API token:

curl -s -X POST "https://api.apify.com/v2/acts/ax_dev~telegram-channel-monitor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"channels": ["durov"], "keywords": ["ton"], "maxPostsPerChannel": 50}' > posts.json
from apify_client import ApifyClient # pip install "apify-client>=3"
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("ax_dev/telegram-channel-monitor").call(
run_input={"channels": ["durov", "telegram"], "maxPostsPerChannel": 20}
)
for post in client.dataset(run.default_dataset_id).iterate_items():
print(post["datetime"], post["url"], post["views"])

Input

FieldTypeDescription
channelsarray (required)@name, name, or https://t.me/name
keywordsarraySave only posts containing a keyword (case-insensitive). Empty = save all
keywordMatchsubstring | wordSubstring (default) or whole-word matching
modescrape | monitorscrape = history; monitor = only new posts since last run
maxPostsPerChannelintegerCap on posts scanned per channel (default 100)
postsNewerThanISO dateStop paging once older posts are reached
minViews / minReactionsintegerSkip low-engagement posts
useProxybooleanRoute via Apify Proxy (only needed for large jobs)

Example: monitor three news channels for a brand

{
"channels": ["telegram", "durov", "bloomberg"],
"keywords": ["bitcoin", "regulation", "SEC"],
"keywordMatch": "word",
"mode": "monitor"
}

Save it as a task and add a schedule (for example every 15 minutes): each run's dataset then holds only new, on-topic posts. Connect the task to Slack, email, a webhook or Make in its Integrations tab to get the alerts pushed to you.

How monitor mode remembers: the id of the last seen post per channel is stored in the named key-value store telegram-monitor-state in your own Apify account. The first monitor run returns recent history (up to maxPostsPerChannel), later runs return only newer posts. All monitor runs in your account share that store per channel name, so to monitor the same channel with two different keyword sets, run one task on a schedule and filter its output downstream.

Use cases

  • Brand & crypto monitoring: alert when your project, ticker, or competitor is mentioned across channels.
  • OSINT & threat intel: track public channels into a structured feed and import it into OpenCTI (STIX 2.1) or MISP with the ready converter below.
  • AI agents (MCP): flat JSON output plugs straight into a RAG pipeline or an MCP tool call ("what did channel X post about Y this week?").
  • Research & analytics: export engagement (views, reactions) over a channel's history.

Real example: 15 threat-intel channels, one week

A real run on 2026-09-30 over 15 public English-language security channels, input "postsNewerThan": "2026-09-23T00:00:00Z", "maxPostsPerChannel": 2000:

vxunderground, thehackernews, bleepingcomputer, cibsecurity, androidMalware, cveNotify, malwr, DarkfeedNews, cyber_security_channel, ctinow, anyrun_app, cyberSecurityPulse, secharvester, RansomLook, cyberscoop (464,141 subscribers combined).

WhatResult
Posts saved3,181 (2026-09-23 00:54 to 2026-09-30 14:36 UTC)
Busiest channelscveNotify 2,000, ctinow 448, RansomLook 309, secharvester 136
Run time151 s, SUCCEEDED, 15 of 15 channels
STIX 2.1 bundle1 report, 15 channel, 3,181 note, 2,210 unique url observables from 384 domains
MISP event3,196 objects, 25,192 attributes
CVE IDs mentioned in post text1,467 unique
Cost at this actor's price3,181 x $0.0002 = $0.64, plus $0.025 of measured platform usage

Honest notes on this run: cveNotify is a firehose (about 2,000 CVE posts a day), so it hit the 2,000-post cap after 20 hours instead of covering the full week; the other 14 channels cover all 7 days. The url observables are every link found in the posts (news articles, GitHub, vendor advisories, ransomware leak trackers), so treat them as indicators to triage, not a blocklist. The CVE count is a plain regex over the text field, not something the converter does.

One post from that run, as the actor saved it and as it lands in OpenCTI:

{
"channel": "bleepingcomputer",
"id": 25690,
"url": "https://t.me/BleepingComputer/25690",
"datetime": "2026-09-30T13:28:05+00:00",
"text": "TeamViewer urges users to patch severe flaws “as soon as possible”\n\nRemote access software company TeamViewer warned customers on Tuesday to immediately patch a set of high-severity vulnerabilities affecting its client and host software. [...]\n\nhttps://www.bleepingcomputer.com/news/security/teamviewer-urges-users-to-patch-severe-flaws-as-soon-as-possible/",
"views": 167,
"links": ["https://www.bleepingcomputer.com/news/security/teamviewer-urges-users-to-patch-severe-flaws-as-soon-as-possible/"],
"media": []
}
{
"type": "note",
"spec_version": "2.1",
"id": "note--e307eae7-43f7-5ccf-8e6e-140cbccdce1a",
"created": "2026-09-30T13:28:05.000Z",
"abstract": "TeamViewer urges users to patch severe flaws “as soon as possible” ...",
"authors": ["@bleepingcomputer"],
"object_refs": [
"channel--86501c42-abe3-50a1-acf7-b6e22f45313d",
"url--bed9c00d-beae-583a-a985-e236921e52b1"
],
"external_references": [{ "source_name": "telegram", "url": "https://t.me/BleepingComputer/25690" }]
}

Export to OpenCTI (STIX 2.1) and MISP

Copy the script below (Python 3, standard library only, save it as to_stix_misp.py) and turn a run's dataset into a file your threat-intel platform imports directly. <DATASET_ID> is the run's defaultDatasetId, shown in the run's Storage tab in the Console:

curl -s "https://api.apify.com/v2/datasets/<DATASET_ID>/items?format=json&clean=1&token=$APIFY_TOKEN" > posts.json
python3 to_stix_misp.py stix posts.json > bundle.json # OpenCTI: Data > Import
python3 to_stix_misp.py misp posts.json > event.json # MISP: Events > Import from > MISP JSON
Actor outputSTIX 2.1 (OpenCTI)MISP
channelOpenCTI Channel (custom SDO channel, type Telegram) with t.me linktelegram-account object
postnote: text, author, t.me link; matched keywords and #hashtags as labelsmicroblog object: post, link, creation-date, hashtags
links in posturl observables referenced by the noteembedded-link attributes
the runone report containing everythingone event, tagged tlp:clear and osint:source-type="microblog-post"

IDs are deterministic (derived from the post URL), so importing every scheduled monitor run updates known posts instead of duplicating them. Checked on live posts from durov and bloomberg: the bundle parses with the official stix2 library (URL ids match its own), the channel validates against pycti's CustomObjectChannel, and every MISP object passes PyMISP's strict template check.

Pricing (pay-per-event)

EventPrice
Actor start$0.00001
Message saved$0.0002

$0.20 per 1,000 saved messages. You pay only for messages that pass your filters: posts that are scanned but filtered out by keywords or view thresholds cost nothing. The start fee is one thousandth of a cent, so a scheduled monitor run that finds nothing new costs practically nothing.

Apify platform usage (compute + storage) is billed to your own account on top. It is small and measured, not guessed: three real runs on 2026-09-21 scraped 200, 273 and 300 posts and used $0.0096 to $0.0099 of platform usage per 1,000 posts, under 5% of the price above. Scraping 1,000 posts therefore costs about $0.21 all-in. The monthly credit of the Apify free plan covers testing and small monitors (tens of thousands of posts), no card needed to try it.

Limits & honest notes

  • Works only with public channels that have web preview enabled. Private channels, groups, and comments are not accessible (and scraping them would require an account, which is out of scope by design).
  • t.me/s/ serves ~20 posts per page; the actor paginates backward through history up to your limit. A few thousand posts per channel take a few minutes; the default run timeout is 300 s, so raise it in Run options for deep history.
  • Counts come from the web preview, so views and reactions are rounded the way Telegram displays them (e.g. 3.44M). Comments and the full member list are not in the preview.
  • A private, deleted or mistyped channel is skipped with a warning in the log and in the run's status message; the other channels still run.
  • Reads public preview data only. This actor does not use MTProto, does not collect member lists, and does not require your credentials.
  • You are responsible for complying with Telegram's Terms and applicable law in your use of the data.

Feedback

Found a bug or need a feature? Open an issue in the Issues tab of this page, I reply within a day. If the actor saved you time, a short review on the store helps a lot.