# Telegram Channel Scraper - Posts, Views, Reactions & Stats (`vladimir_trifonov/telegram-channel-scraper`) Actor

Scrape public Telegram channels: message text, views, reactions, media links, forwards and subscriber counts. No API key, no phone number, no login.

- **URL**: https://apify.com/vladimir\_trifonov/telegram-channel-scraper.md
- **Developed by:** [Vladimir Trifonov](https://apify.com/vladimir_trifonov) (community)
- **Categories:** Social media, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Telegram Channel Scraper

Extract posts and statistics from **public Telegram channels** — text, view counts, reactions, media links, forwards and subscriber numbers.

No API key. No phone number. No Telegram account. No `api_id` / `api_hash`. The Actor reads the same public preview pages that anyone can open in a browser, so there is nothing to register and nothing to get banned.

### What you get

For every channel:

- **Channel statistics** — title, description, subscriber count, photo/video/link totals, verified badge
- **Messages** — full text with line breaks, publication time, permanent link, author signature
- **Reach** — view count per post, both as displayed (`1.48M`) and as a number (`1480000`) you can sort by
- **Engagement** — reactions per emoji with counts, plus a total
- **Media** — direct URLs for photos, videos, thumbnails and video duration
- **Context** — forwards with their source, replies, link previews, hashtags, mentions and outbound links

### Example input

```json
{
  "channels": ["durov", "telegram"],
  "maxMessages": 100,
  "includeChannelInfo": true
}
```

Search inside a channel and limit the period:

```json
{
  "channels": ["durov"],
  "searchQuery": "privacy",
  "fromDate": "30 days",
  "maxMessages": 500
}
```

`fromDate` and `toDate` accept both calendar dates (`2026-01-31`) and relative values (`7 days`, `3 months`).

### Example output

A message row:

```json
{
  "type": "message",
  "channel": "durov",
  "channelTitle": "Pavel Durov",
  "messageId": 538,
  "url": "https://t.me/durov/538",
  "date": "2026-08-04T15:20:04+00:00",
  "timestamp": 1785856804,
  "text": "Last night, Apple briefly removed Telegram from the App Store...",
  "textLength": 812,
  "views": "1.48M",
  "viewsCount": 1480000,
  "author": "Pavel Durov",
  "isForwarded": false,
  "hasMedia": true,
  "mediaTypes": ["photo"],
  "photoUrls": ["https://cdn4.telesco.pe/file/..."],
  "reactions": [{ "emoji": "🔥", "count": 25000 }],
  "reactionsTotal": 37300,
  "hashtags": [],
  "mentions": [],
  "links": ["https://telegram.org"],
  "isEdited": true
}
```

A channel row:

```json
{
  "type": "channel",
  "channel": "durov",
  "channelTitle": "Pavel Durov",
  "description": "Founder of Telegram.",
  "subscribers": "11.3M",
  "subscribersCount": 11300000,
  "photosCount": 101,
  "videosCount": 45,
  "linksCount": 194,
  "isVerified": true
}
```

Results are also available as ready-made views — **Messages**, **Engagement**, **Media** and **Channel stats** — so you can export just the columns you need.

### What people use it for

- **Competitor and market tracking** — watch what channels in your niche publish and which posts actually travel
- **Content research** — find the highest-view posts in a channel and see the pattern behind them
- **Influencer vetting** — compare subscriber counts against real per-post views before you pay for placement
- **News and OSINT monitoring** — collect messages from a set of channels on a schedule, filtered by keyword
- **Dataset building** — assemble text corpora with engagement labels for analysis or model training
- **Brand monitoring** — search your brand name across channels and catch mentions as they appear

### Fields worth knowing about

**`viewsCount` vs `views`.** Telegram displays `1.48M`; the Actor also gives you `1480000` so you can sort, filter and compute averages without parsing strings.

**`reactions`.** Custom emoji have no unicode character, so they appear as `custom:<id>`. Paid star reactions appear as `⭐`. `reactionsTotal` sums everything, which is usually the number you want for engagement scoring.

**`isForwarded` and `forwardedFrom`.** Lets you separate a channel's own writing from reposted material — often the fastest way to tell an original source from an aggregator.

### Honest limits

- **Public channels only.** Private channels, invite-only channels and group chats require an account and are out of reach. The Actor reports them as failures with a clear message instead of returning empty rows.
- **Reactions are not always exposed.** Telegram shows them in the public preview for some channels and not others. When they are absent, `reactions` is an empty array — that is Telegram's choice, not a parsing failure.
- **Comments are not included.** Discussion-group replies live in a linked group, which is a separate surface.
- **View counts are approximate** — they are whatever Telegram displays publicly, rounded the same way.

### Pricing

Pay per result. You are charged for the rows you actually receive, so a channel that turns out to be private or empty costs you nothing beyond the lookup.

### Speed and cost

Telegram returns roughly 20 messages per page, and the Actor pages backwards from the newest post. 100 messages from one channel is about 5 requests and a few seconds. Runs are sequential across channels on purpose: parallel bursts hit rate limits far sooner than they save time.

### Tips

- Start with `maxMessages: 20` to confirm a channel is public and returns what you expect, then raise it.
- Use `fromDate` for recurring runs — it stops paging as soon as it reaches messages you already have.
- Combine `searchQuery` with several channels to sweep a whole topic in one run.
- Schedule the Actor and point it at the same channel list to build a time series of views and reactions.

### Integrations

Results are available through the Apify API, and can be exported as JSON, CSV, Excel or XML, or pushed onward with the standard Apify integrations — Google Sheets, Slack, Zapier, Make, Airtable and webhooks.

### Is scraping Telegram legal?

The Actor reads only pages that Telegram publishes openly, with no login and no circumvention of access controls — the same content any visitor sees. It collects no private messages and no personal contact data. As with any scraping, you are responsible for how you use the data, particularly where it concerns individuals; check the rules that apply to you before collecting personal information at scale.

# Actor input Schema

## `channels` (type: `array`):

Public channels to scrape. Accepts a username (durov), a handle (@durov) or a link (https://t.me/durov). Private channels and groups cannot be read without an account and will be reported as failures.

## `maxMessages` (type: `integer`):

How many of the most recent messages to collect from each channel. Telegram returns about 20 per page, so higher values simply mean more pages.

## `searchQuery` (type: `string`):

Optional. Return only messages containing this phrase. Leave empty to get the full feed.

## `fromDate` (type: `string`):

Optional lower bound. Accepts a date (2026-01-31) or a relative value (7 days, 3 months). Paging stops once older messages are reached.

## `toDate` (type: `string`):

Optional upper bound. Accepts a date (2026-06-30) or a relative value (1 day).

## `includeChannelInfo` (type: `boolean`):

Add one extra row per channel with subscriber count, description, media counts and verification status.

## `proxyConfiguration` (type: `object`):

Telegram serves public channel pages without login, so datacenter proxies are enough. Residential proxies help only if you scrape many channels in one run.

## Actor input object example

```json
{
  "channels": [
    "durov",
    "telegram"
  ],
  "maxMessages": 100,
  "searchQuery": "bitcoin",
  "fromDate": "7 days",
  "toDate": "2026-06-30",
  "includeChannelInfo": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Every row from the run: channel statistics and messages.

## `messages` (type: `string`):

Post text, author, publication time, views and forwarding source.

## `engagement` (type: `string`):

Views, reaction totals and the per-emoji breakdown for each post.

## `media` (type: `string`):

Direct links to photos and videos attached to the posts.

## `channels` (type: `string`):

Subscriber counts, descriptions and media totals for each channel.

## `summary` (type: `string`):

Per-run statistics: channels requested, succeeded and failed, success rate, message totals and failure reasons.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "channels": [
        "durov",
        "telegram"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vladimir_trifonov/telegram-channel-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "channels": [
        "durov",
        "telegram",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("vladimir_trifonov/telegram-channel-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "channels": [
    "durov",
    "telegram"
  ]
}' |
apify call vladimir_trifonov/telegram-channel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=vladimir_trifonov/telegram-channel-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/cOl8iJZGZipsoCArW/builds/B4bfLIyieNtZ7UIn6/openapi.json
