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

Archive messages, media, reactions, and metadata from any public Telegram channel - 35 fields per message, no phone or API key required.

- **URL**: https://apify.com/parseforge/telegram-channel-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** Social media, News
- **Stats:** 23 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $11.25 / 1,000 result items

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

![ParseForge Banner](https://raw.githubusercontent.com/ParseForge/apify-assets/main/banner.jpg)

## 📨 Telegram Channel Scraper

> 🚀 **Archive entire Telegram channels in seconds.** Pull messages, photos, videos, link previews, reactions, view counts, and channel stats from any public channel. No login, no MTProto, no API key.

Telegram is one of the largest open broadcast networks on the internet, with public channels covering crypto markets, breaking news, government communications, fan communities, and developer announcements. The platform's web preview at `t.me/s/{channel}` exposes a full archive of any channel that has enabled public preview, but it is paginated, HTML-rendered, and rate-sensitive. Pulling a clean dataset out of it by hand means stitching dozens of pages, parsing fragile DOM, and handling every media type Telegram supports.

This actor handles all of that. Point it at one channel or a hundred, set a maximum, and it walks the public preview newest-first, parses every supported message type (text, photo, video, voice, document, sticker, poll, location, forwarded, reply, service), normalizes view counts and reaction tallies, and ships **35 structured fields** per message. Every record includes the source channel's title, description, subscriber count, and verified status, so single records stand on their own without needing a join. Channels that do not expose a public preview are flagged with an `error` record rather than failing the whole run.

| 👥 Target Audience | 🎯 Primary Use Cases |
| --- | --- |
| Crypto researchers tracking project announcements | Build longitudinal datasets of token launch posts and community sentiment |
| Compliance and risk teams archiving public chatter | Snapshot regulated entities' public messaging for retention requirements |
| Investigative journalists documenting sources | Capture an immutable copy of public channel posts before they are edited |
| OSINT and threat-intel analysts | Monitor activity, view counts, and reaction signals at scale |
| Academic researchers studying online communities | Collect reproducible corpora of public channel discourse |

### 📋 What the Telegram Channel Scraper does

- 📡 **Multi-channel input.** Accepts channel usernames, `@handles`, or full `https://t.me/...` URLs. Each channel is paginated independently with its own per-channel cap.
- 🧾 **Full message body.** Returns both plain text and Telegram's original HTML, including emoji, formatting, and outbound `<a>` links.
- 🖼️ **Every media type.** Photos, videos (including round videos), voice notes, documents, stickers, polls, locations, plus link preview cards.
- 🔁 **Forwards and replies.** Captures the original channel name and link for forwards, the parent message for replies, and the snippet of the message being replied to.
- 📈 **Engagement signals.** View counts and full reaction tallies (including paid Star reactions) parsed into clean integers (no `1.2K` strings).
- 🗓️ **Date-bounded archival.** Optional `fromDate` / `toDate` filters stop pagination at the right point so you do not pay to scrape outside the window.

Each record carries `channelTitle`, `channelDescription`, `channelSubscribers`, and `channelVerified` from the channel's profile page so a single message can be analyzed without joining a separate channels table. Reaction blocks include both the unicode emoji (when standard) and the Telegram custom-emoji ID for branded reactions, and paid Star reactions are flagged with `isPaid: true`.

> 💡 **Why it matters:** Telegram's MTProto API requires a registered application, a phone number, and a session that can be flagged or banned. The public preview is anonymous and rate-friendly. This actor turns it into a clean dataset without any of that overhead.

### 📊 Data fields

Each record includes: `author`, `channel`, `channelSubscribers`, `channelTitle`, `date`, `edited`, `forwardedFrom`, `imageUrl`, `messageId`, `replyTo`, `text`, `totalReactions`, `type`, `url`, `views`. These field names come straight from the actor's dataset schema, so what you see here is what lands in your dataset.

### 🚀 How to use

1. ✨ **Sign up.** Create an Apify account at [console.apify.com/sign-up](https://console.apify.com/sign-up?fpr=vmoqkp). Free tier covers 10 messages so you can preview the output before upgrading.
2. 📋 **Open the actor.** Find Telegram Channel Scraper in the [ParseForge collection](https://apify.com/parseforge) and click Try for free.
3. 🎯 **Pick channels.** Paste channel usernames or `t.me/...` URLs into the Telegram Channels field. Add as many as you like.
4. 🎚️ **Tune limits and filters.** Set `maxItems`, `maxItemsPerChannel`, optional date window, and message types. Defaults pull the latest 10 messages per channel.
5. 💾 **Run and download.** Click Start. Stream results to JSON, CSV, Excel, RSS, or pipe directly into Google Sheets, S3, or your warehouse via Apify integrations.

> ⏱️ **Total time:** under 60 seconds from sign-up to first dataset row.

### 🔗 Recommended Actors

- [**📨 Reddit Posts Scraper**](https://apify.com/parseforge/reddit-posts-scraper) - companion archive tool for Reddit communities.
- [**🐦 X.com (Twitter) Post Scraper**](https://apify.com/parseforge/x-com-scraper) - the Twitter equivalent of this actor, no auth required.
- [**📸 Instagram Posts Scraper**](https://apify.com/parseforge/instagram-posts-scraper) - structured Instagram post archives.
- [**🎬 YouTube Scraper**](https://apify.com/parseforge/youtube-scraper) - channel and video metadata at scale.
- [**💬 Youtube Comments Scraper**](https://apify.com/parseforge/youtube-comments-scraper) - comment threads with replies and AI sentiment.

> 💡 **Pro Tip:** browse the complete [ParseForge collection](https://apify.com/parseforge) for more social, marketplace, and public-records scrapers.

[**Open our contact form**](https://tally.so/r/BzdKgA) and we will respond within one business day.

> ⚖️ **Disclaimer:** This actor only accesses public Telegram channel previews exposed by Telegram itself. It does not authenticate, impersonate users, or access private chats, groups, or content. Users are responsible for compliance with Telegram's terms of service and applicable law in their jurisdiction.

### 🆘 Need Help?

If you hit a bug, have questions about setup, or need a scraper we haven't built yet, open our [contact form](https://tally.so/r/BzdKgA) or write to parseforge@protonmail.com. We also take on paid custom data projects.

For faster answers, join our [Discord](https://parseforge.co/discord). It's the best place to get support and suggest new actors.

# Actor input Schema

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

List of public Telegram channels to scrape. Accepts channel usernames (e.g. `durov`), `@usernames`, or full URLs (`https://t.me/durov` or `https://t.me/s/durov`). The channel must have a public preview enabled.

## `maxItems` (type: `integer`):

How many messages to collect per run.

## `maxItemsPerChannel` (type: `integer`):

Cap on messages scraped from any single channel. Useful when scraping many channels but you only want recent messages from each. Leave empty for no per-channel cap.

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

Only return messages posted on or after this date (ISO 8601, e.g. `2025-01-01`). Leave empty to include the oldest available messages.

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

Only return messages posted on or before this date (ISO 8601, e.g. `2026-12-31`). Leave empty to include up to the most recent message.

## `messageTypes` (type: `array`):

Restrict to specific message types. Leave empty to include all types.

## `onlyWithMedia` (type: `boolean`):

Skip text-only messages. Returns only messages that include at least one photo, video, voice note, document, sticker, or animated GIF.

## `includeChannelMetadata` (type: `boolean`):

Include channel title, description, subscriber count, and verified flag on every message record. Adds one extra request per channel.

## `includeReactions` (type: `boolean`):

Include the reactions array (emoji and counts) on each message. Disable to keep records lighter.

## `includeLinkPreview` (type: `boolean`):

Include link preview metadata (URL, site name, title, description, image) when a message contains a preview card.

## `outputFormat` (type: `string`):

How to render the message body. `text` strips formatting; `html` keeps Telegram's HTML; `both` returns both fields.

## Actor input object example

```json
{
  "channels": [
    "durov",
    "telegram"
  ],
  "maxItems": 10,
  "onlyWithMedia": false,
  "includeChannelMetadata": true,
  "includeReactions": true,
  "includeLinkPreview": true,
  "outputFormat": "both"
}
```

# Actor output Schema

## `overview` (type: `string`):

Table view with the most useful message fields (channel, message ID, date, text, type, views, reactions).

## `fullData` (type: `string`):

Complete dataset with every field, including media arrays and reactions.

# 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"
    ],
    "maxItems": 10
};

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

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

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/d8j7pX3djK6PZZkJ4/builds/Ke56tfutvrxmTxlX5/openapi.json
