# Telegram Channel Scraper (`maged120/telegram-channel-scraper`) Actor

Scrape posts from public Telegram channels: full text, views, reactions, photos, videos, links and dates, plus each channel's subscriber count and profile.

- **URL**: https://apify.com/maged120/telegram-channel-scraper.md
- **Developed by:** [Maged](https://apify.com/maged120) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 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/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** extracts **posts from public Telegram channels**: full text, **views**, **reactions**, **photos, videos and links**, and the **publish date** of every post. It also returns each channel's **subscriber count** and profile. Point it at any public channel and get a clean, export-ready dataset in seconds.

### What does Telegram Channel Scraper do?

This Actor collects the recent post history of any public [Telegram](https://telegram.org) channel. For each post you get the text, the date, the view count, the reaction breakdown, media URLs, outbound links and forward info. For each channel you get its title, description, verification status, subscriber count and media counts. You choose how far back to go: the latest 100 posts, everything since a date, or the full history available.

On the Apify platform you also get API access, scheduling, integrations (Google Sheets, Zapier, Make, webhooks), proxy rotation and run monitoring, so a daily channel feed can run on autopilot.

### Why scrape Telegram channels?

- **Crypto & trading signals**: monitor announcement and signal channels and feed new posts into your own tools.
- **News & media monitoring**: track what news, brand or competitor channels publish, and how much reach each post gets.
- **Marketing & influencer research**: compare channels by subscribers, views per post and engagement before buying promotions.
- **OSINT & research**: archive public channel content with timestamps for analysis.
- **Content analytics**: find a channel's best-performing posts by views and reactions.

### How to scrape a Telegram channel

1. Open the Actor and go to the **Input** tab.
2. Add channels to **Channels**. `durov`, `@durov` and `https://t.me/durov` all work.
3. Set **Max posts per channel**, or pick a date in **Only posts newer than**.
4. Click **Start**.
5. Open the **Output** tab and switch between the **Posts** and **Channels** views, or download everything as JSON, CSV, Excel or HTML.

### Input

| Field | Type | Description |
|---|---|---|
| `channels` | array | Public channel usernames or links. **Required.** |
| `maxPostsPerChannel` | integer | Most recent posts to collect per channel. `0` = all available. Default `100`. |
| `postsNewerThan` | string | Optional date (e.g. `2026-01-31`). Only newer posts are collected. |
| `includeChannelInfo` | boolean | Add one profile row per channel. Default `true`. |
| `proxyConfiguration` | object | Optional. Not needed for normal use. |

```json
{
    "channels": ["durov", "https://t.me/telegram"],
    "maxPostsPerChannel": 100,
    "postsNewerThan": "2026-01-01",
    "includeChannelInfo": true
}
```

### Output

You get two kinds of rows, marked by `entityType`: one **channel** row per channel and one **post** row per post. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

**Post**

```json
{
    "entityType": "post",
    "channel": "durov",
    "channelUrl": "https://t.me/durov",
    "postId": 548,
    "postUrl": "https://t.me/durov/548",
    "date": "2026-09-11T16:04:02+00:00",
    "text": "🤝 Telegram has become the sponsor of Codeforces — the largest competitive programming platform in the world. ...",
    "views": 1580000,
    "reactionsTotal": 56370,
    "reactions": [
        { "reaction": "paid_star", "count": 13400 },
        { "reaction": "custom", "count": 27600 }
    ],
    "photoUrls": [],
    "videoUrls": [],
    "hasDocument": false,
    "hasPoll": false,
    "links": ["https://codeforces.com/blog/entry/156620"],
    "linkPreviewUrl": "https://codeforces.com/blog/entry/156620",
    "forwardedFrom": null,
    "isEdited": false,
    "scrapedAt": "2026-09-25T15:11:26+00:00"
}
```

**Channel**

```json
{
    "entityType": "channel",
    "channel": "durov",
    "channelUrl": "https://t.me/durov",
    "title": "Pavel Durov",
    "description": "Founder of Telegram.",
    "isVerified": true,
    "subscribers": 10600000,
    "photos": 102,
    "videos": 46,
    "links": 200,
    "files": null,
    "avatarUrl": "https://…/avatar.jpg",
    "scrapedAt": "2026-09-25T15:11:26+00:00"
}
```

#### Dataset views

- **Posts**: date, text, views, reactions, media and links for every post.
- **Channels**: title, subscribers, verification and media counts for every channel, plus any channel that couldn't be read.

### Output data fields

| Field | Description |
|---|---|
| `postUrl` | Direct link to the post. |
| `date` | Publish time (ISO 8601, UTC). |
| `text` | Full post text with line breaks kept. |
| `views` | View count (Telegram rounds large numbers, e.g. 1.58M). |
| `reactionsTotal` / `reactions` | Total reactions and the per-reaction breakdown. |
| `photoUrls` / `videoUrls` | Media attached to the post. |
| `links` / `linkPreviewUrl` | Links in the post text and the previewed link. |
| `forwardedFrom` | Source channel or user if the post was forwarded. |
| `hasDocument` / `hasPoll` | Whether the post contains a file or a poll. |
| `isEdited` | Whether the post was edited after publishing. |
| `subscribers` | Channel subscriber count (channel rows). |

### How many results will I get?

One row per post, plus one row per channel if **Include channel profile row** is on. Scraping 5 channels with **Max posts per channel** at 100 gives up to 505 rows. To keep result counts down:

- Lower **Max posts per channel**.
- Use **Only posts newer than** on scheduled runs, so each run only collects what's new.
- Turn off **Include channel profile row** if you only need posts.

### Tips

- **Daily feeds**: schedule the Actor with **Only posts newer than** set to yesterday's date, and connect a webhook, Slack or Google Sheets integration.
- **Full history**: set **Max posts per channel** to `0`. Very large channels take longer, so start with a cap to preview the data.
- **Many channels**: add them all to one run. They're processed one after another automatically.

### FAQ

**Which channels work?** Any **public** channel with a username. Private channels, invite-only links, groups and bots can't be scraped. They return a row explaining why.

**Why are view counts rounded?** Telegram shows large numbers in rounded form (e.g. 10.6M), and the Actor converts them to plain numbers.

**Can I get comments?** Not at the moment. Open an issue if you need them.

**Is scraping Telegram legal?** The Actor only collects publicly available content. You're responsible for how you use the data, especially any personal data, under laws like GDPR. When in doubt, consult a lawyer.

**Found a bug or need a custom feature?** Open an issue in the **Issues** tab. Custom solutions are available on request.

# Actor input Schema

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

Public Telegram channels to scrape. Use the username (durov), @username, or a link (https://t.me/durov).

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

How many of the most recent posts to collect from each channel. 0 = all available posts.

## `postsNewerThan` (type: `string`):

Optional. Only collect posts published after this date (e.g. 2026-01-31). Great for scheduled runs that only need what's new.

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

Add one row per channel with its title, description, subscriber count and media counts.

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

Optional. Not needed for normal use — enable for very large or frequent runs.

## Actor input object example

```json
{
  "channels": [
    "durov",
    "telegram"
  ],
  "maxPostsPerChannel": 100,
  "includeChannelInfo": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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": 100
};

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

# Run the Actor and wait for it to finish
run = client.actor("maged120/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": 100
}' |
apify call maged120/telegram-channel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maged120/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/apaSbEdtbrFWd6XnY/builds/LbmVhxx12eyXGab88/openapi.json
