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

Scrape public Telegram channels: posts with text, views, reactions, photos, videos, link previews, forwards, search inside a channel, date range, and channel subscriber stats. No account or API key.

- **URL**: https://apify.com/v1tal615/telegram-channel-scraper.md
- **Developed by:** [bình minh trần](https://apify.com/v1tal615) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 channel posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Telegram Channel Scraper: posts, views, reactions, media and channel stats

Scrape any **public Telegram channel**: every post with text, views, reactions, photos, videos, link previews, forwards and replies, plus the channel's subscriber count and profile. You don't need a Telegram account, phone number or API key.

Use it to:

- **Monitor crypto, news and trading channels**: track announcements the moment they are posted, with view and reaction counts.
- **Research audiences and influencers**: compare channels by subscribers, post frequency and engagement.
- **Collect datasets**: build text and media datasets for sentiment analysis, LLM training or archiving.
- **Track mentions**: search inside channels for a keyword, brand or ticker.

### What you get

| Input | Output |
| --- | --- |
| **Channels** (username, `@name` or `t.me` link) | Posts, newest first, as many as you ask for. The scraper pages back through the whole history. |
| **Search inside channels** | Only the posts that match your keyword, using Telegram's own in-channel search |
| **Date range** | Only the posts between two dates; paging stops at the start date |
| **Channel info** | Title, description, subscribers, verified badge, photo, video and link counts |

### Why this scraper

- **About 40% cheaper** than the most-used Telegram channel scraper on the Store (see Pricing).
- **Full post data**: text, views, every reaction with its count (including paid Star reactions), photos, videos, link preview cards, forwarded-from, reply-to, polls, documents, hashtags and links.
- **No login, no phone number, no ban risk.** It only reads Telegram's public `t.me/s/` channel pages.
- **Fast and light**: plain HTTP requests, 20 posts per request, no browser.
- **Clean numbers**: "10.5M" becomes `10500000`, and all times are in UTC.

### How to use it

1. Add one or more public channels, for example `durov`, `@binance_announcements` or `https://t.me/s/nytimes`.
2. Set how many posts you want per channel. Optionally add a search term or a date range.
3. Click **Start**. Download the results from the **Output** tab, or read them through the API. You can also schedule it hourly to monitor channels.

#### Input example

```json
{
    "channels": ["durov", "binance_announcements", "https://t.me/s/nytimes"],
    "maxPostsPerChannel": 500,
    "searchQuery": "",
    "dateFrom": "2026-09-01",
    "includeChannelInfo": true
}
```

### Output

Every record has a `type` field: `post` or `channel`.

#### Post

```json
{
    "type": "post",
    "channel": "binance_announcements",
    "channelTitle": "Binance Announcements",
    "postId": 9001,
    "url": "https://t.me/binance_announcements/9001",
    "date": "2026-09-28T07:01:40Z",
    "edited": false,
    "text": "Binance Will List ...",
    "views": 42200,
    "reactions": [
        { "emoji": "❤", "customEmojiId": null, "count": 66, "paid": false },
        { "emoji": "👏", "customEmojiId": null, "count": 24, "paid": false }
    ],
    "reactionsTotal": 90,
    "author": null,
    "forwardedFrom": null,
    "forwardedFromUrl": null,
    "replyToPostId": null,
    "photos": ["https://cdn5.telesco.pe/file/....jpg"],
    "videos": [],
    "document": null,
    "documentInfo": null,
    "poll": null,
    "pollOptions": [],
    "linkPreview": null,
    "links": ["https://www.binance.com/en/support/announcement/..."],
    "hashtags": [],
    "isServiceMessage": false,
    "position": 1,
    "scrapedAt": "2026-10-04T18:31:27Z"
}
```

`customEmojiId` is set for premium custom-emoji reactions, which Telegram's public page shows only as an id. Paid reactions (Telegram Stars) are reported as `"emoji": "⭐", "paid": true`.

#### Channel

```json
{
    "type": "channel",
    "channel": "durov",
    "url": "https://t.me/durov",
    "title": "Pavel Durov",
    "description": "Founder of Telegram.",
    "verified": true,
    "subscribers": 10500000,
    "photosCount": 102,
    "videosCount": 46,
    "filesCount": null,
    "linksCount": 200,
    "avatarUrl": "https://cdn4.telesco.pe/file/....jpg",
    "scrapedAt": "2026-10-04T18:31:27Z"
}
```

### Pricing

Pay per result, with no subscription and no start fee. You are only charged for records that land in your dataset.

| Record | Event | Price |
| --- | --- | --- |
| Post | `post` | $1.20 per 1,000 |
| Channel info | `channel` | $1.20 per 1,000 |

The exact current prices are always shown on the **Pricing** tab. Set *Maximum cost per run* in the run options and the scraper stops cleanly when it is reached. 1,000 posts from one channel cost about $1.20.

### FAQ

**Can it scrape private channels or groups?**
No. It reads only what Telegram shows publicly at `t.me/s/<channel>`. Private channels, groups, and channels that turned off the public preview are not available. They are reported in the run log and skipped.

**How far back can it go?**
As far as the channel's public history goes. Set *Max posts per channel* high, or use *Posts from* to stop at a date.

**Why does a search return only a few dozen posts?**
Telegram's public in-channel search returns only the most recent matches. For a channel's full history, leave *Search* empty, scrape all posts and filter the `text` field yourself.

**Why do some reactions have no emoji?**
Premium custom emoji are shown on Telegram's public page as an id, not a character. You get that id in `customEmojiId`.

**Do I need a proxy?**
No. The scraper paces itself. On the Apify platform it switches to Apify Proxy on its own if Telegram rate-limits it.

**Is scraping Telegram legal?**
This Actor reads only publicly published channel posts, the same pages anyone can open in a browser without logging in. You are responsible for how you use the data under Telegram's terms and the laws that apply to you.

### Feedback

Found a bug or need another field? Open an issue on the **Issues** tab. Issues are usually fixed within a few days.

# Actor input Schema

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

Public channel usernames or links: durov, @durov, https://t.me/durov, https://t.me/s/durov. Private channels and groups are not available.

## `maxPostsPerChannel` (type: `integer`):

Newest posts first. Telegram serves 20 posts per page, so the scraper keeps paging back until it has this many or reaches the date limit.

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

Only posts that match this word or phrase, using Telegram's own in-channel search. Telegram returns only the most recent matches this way (often a few dozen per channel); for full history leave this empty and filter the text yourself.

## `dateFrom` (type: `string`):

Oldest post date to include, e.g. 2026-09-01. Paging stops once older posts are reached.

## `dateTo` (type: `string`):

Newest post date to include, e.g. 2026-09-30.

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

Add one record per channel with title, description, subscriber count, verified badge and media counts.

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

Not needed in most cases: the scraper switches to Apify Proxy on its own if Telegram rate-limits it.

## Actor input object example

```json
{
  "channels": [
    "durov",
    "telegram"
  ],
  "maxPostsPerChannel": 20,
  "searchQuery": "",
  "dateFrom": "",
  "dateTo": "",
  "includeChannelInfo": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `posts` (type: `string`):

No description

## `allResults` (type: `string`):

No description

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

No description

# 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"
    ],
    "maxPostsPerChannel": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("v1tal615/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",
    ],
    "maxPostsPerChannel": 20,
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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"
  ],
  "maxPostsPerChannel": 20
}' |
apify call v1tal615/telegram-channel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,v1tal615/telegram-channel-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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