# Telegram Channel Scraper: Public Posts, Media, Views, Reactions (`everyotherfriday/telegram-channels`) Actor

Monitor public channels of organisations and public figures: message text, dates, views, reactions, media and channel info. No login or API key. Author names off by default. Output must not be used to train AI models. $0.0008 per message.

- **URL**: https://apify.com/everyotherfriday/telegram-channels.md
- **Developed by:** [Paul Vasquez](https://apify.com/everyotherfriday) (community)
- **Categories:** Social media, News, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.80 / 1,000 message scrapeds

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: Messages, Views & Reactions

Export messages from public Telegram channels without a Telegram account, API ID or bot token. Each row has the text, date, view count, links, hashtags, mentions and media URLs, and reaction counts when you switch reactions on. About $0.80 per 1,000 messages. Author names are off by default, and Telegram's terms forbid using the output to train AI models.

The actor reads the public web preview that Telegram shows for every public channel at `t.me/s/<channel>`. It does not log in and does not download media files.

### What data you get

One row per message, newest first within each channel.

| Field | What it holds |
|---|---|
| `channel`, `channelTitle` | The channel username and its display title |
| `messageId`, `url` | The message number and its permalink, for example `https://t.me/telegram/460` |
| `date` | When it was posted (ISO 8601, UTC) |
| `text`, `textHtml` | The message text, as plain text and as the original HTML |
| `views` | View count. Telegram shows rounded numbers, so "1.2K" becomes about 1,200 |
| `forwards`, `replies` | Counters when the public preview shows them; usually empty (null) |
| `reactions` | A list of `{emoji, count}` when **Include reactions** is on (off by default) |
| `media` | Photos, videos and documents: type, URL, thumbnail URL, duration, file name, size |
| `links`, `mentions`, `hashtags` | Links, @mentions and #hashtags found in the message |
| `isForwarded`, `forwardedFrom`, `replyToMessageId` | Forward and reply details when shown |
| `edited`, `isPinned` | Flags shown on the message |
| `author` | The post signature, only when **Include author names** is on (off by default) |

**Channel information** (title, description, approximate subscriber count and photo URL) is saved once per channel in the run's key-value store, under the key `CHANNEL-<name>`, for example `CHANNEL-telegram`. A per-channel summary (messages collected, errors, requests) is saved under `SUMMARY`.

You can download the messages as JSON, CSV, Excel or other formats from the run's Storage tab or through the API.

### How much does it cost?

You pay per message saved: **$0.0008 per message, which is $0.80 per 1,000 messages.**

| Messages | Price |
|---:|---:|
| 100 | $0.08 |
| 1,000 | $0.80 |
| 10,000 | $8.00 |

**Worked example.** A run on 2026-09-30 collected 50 messages from each of 3 channels (`telegram`, `durov`, `bloomberg`): 150 messages, so **$0.12**. The prefilled example below (2 channels, 10 messages each) costs at most $0.016.

**What is free:**

- Error rows, for example for a private, invalid or unavailable channel.
- The row that says a channel had no messages after your `since` date.
- The channel information and summary records in the key-value store.

**Keep costs under control:** set **Messages per channel** to what you need, and set a maximum charge per run in the run options. The actor stops saving messages when that limit is reached.

### How to use it

1. Add one or more channels under **Public channels**. You can type `telegram`, `@telegram`, `https://t.me/telegram` or `https://t.me/s/telegram`.
2. Set **Messages per channel**. If you call the actor through the API and leave it out, the default is 200 per channel.
3. Optional: set **Since** to a date such as `2026-09-01` to collect only newer messages. The date is inclusive and read as UTC.
4. Optional: switch on **includeReactions**, or **Include author names** if you have a lawful reason to process them. Then click **Start** and download the results.

### Input example

This is the prefilled input on the actor's page:

```json
{
  "channels": ["telegram", "durov"],
  "maxMessages": 10,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output example

Real rows from a run on 2026-09-30 (3 channels, 50 messages each, reactions switched on). The text is cut short here.

| channel | messageId | date | views | reactions | text (start) |
|---|---:|---|---:|---|---|
| telegram | 460 | 2026-08-26 | 1,550,000 | none shown | For all the info from today's update and a look back at 13 years of Telegram features… |
| telegram | 459 | 2026-08-26 | 1,360,000 | none shown | Signed Gifts. You can now add your signature and a comment to gifts… |
| durov | 548 | 2026-09-11 | 1,790,000 | 4 types | 🤝 Telegram has become the sponsor of Codeforces… |
| bloomberg | 3225 | 2026-09-22 | 36,100 | 9 types | Alibaba unveils new AI chip it says is China's most powerful… |

One full row from the same run. The media URLs are shortened here; in your results they are complete.

```json
{
  "channel": "bloomberg",
  "channelTitle": "Bloomberg",
  "messageId": 3225,
  "url": "https://t.me/bloomberg/3225",
  "date": "2026-09-22T03:26:17+00:00",
  "text": "Alibaba unveils new AI chip it says is China's most powerful and targets 20 gigawatts of data center capacity by 2032. https://bloom.bg/4ydroys\n\n📷: Qilai Shen/Bloomberg",
  "author": null,
  "views": 36100,
  "forwards": null,
  "replies": null,
  "reactions": [
    { "emoji": "🔥", "count": 91 },
    { "emoji": "❤", "count": 83 },
    { "emoji": "👍", "count": 54 }
  ],
  "media": [
    {
      "type": "photo",
      "url": "https://cdn5.telesco.pe/file/YgESn-qF7dE6…jpg",
      "thumbUrl": "https://cdn5.telesco.pe/file/YgESn-qF7dE6…jpg",
      "duration": null,
      "fileName": null,
      "size": null
    }
  ],
  "links": ["https://bloom.bg/4ydroys"],
  "mentions": [],
  "hashtags": [],
  "isForwarded": false,
  "forwardedFrom": null,
  "replyToMessageId": null,
  "edited": false,
  "isPinned": false,
  "source": "https://t.me/s/bloomberg"
}
```

(The `reactions` list is shortened to 3 of its 9 entries, and `textHtml` is left out.)

### FAQ

**Do I need a Telegram account, API ID or bot token?**
No. The actor reads the public web preview, which anyone can open in a browser.

**Can it read private channels or groups?**
No. Only public channels that have a web preview. Private, invite-only and restricted channels return a free error row.

**Why are forwards and replies often empty?**
Telegram's public preview usually doesn't show those counters. Empty (null) means "not shown", not zero.

**Are view counts exact?**
No. Telegram shows rounded numbers such as "1.2K" or "9.47M", and the actor turns them into approximate whole numbers.

**Why do some reactions look like `custom:5399847211989246390`?**
Custom emoji reactions have only an ID in the preview, not a character. Paid star reactions are shown as ⭐.

**Can I download the media?**
You get the media URLs, not the files. Telegram's media links can expire, so download what you need soon after the run. Some videos and documents have no public URL.

**How far back can it go?**
It pages back through the channel until it reaches your message limit, your `since` date or the oldest message the preview shows.

**Author names?**
Off by default. Switch on **Include author names** to get post signatures and forwarded-from names where Telegram shows them. Names that appear inside message text are not removed.

**Can I train an AI model on the output?**
No. Telegram's terms forbid it.

### Limitations

- The public web preview is only part of Telegram. Private or restricted channels, deleted messages, hidden details and expired media links can't be recovered.
- Counters are rounded, so they don't suit exact engagement accounting.
- Telegram doesn't always tell an empty channel apart from a restricted one, so the error row says it could be either.
- Service messages (such as "channel created") and deleted messages are skipped, so gaps in message numbers are normal.
- If you collect the same channel repeatedly, remove duplicates by `channel` and `messageId`.

### Responsible use

This actor reads only the public web preview of public channels. It is meant for channels run by organisations, publishers and public figures: news monitoring, announcements, brand and market research. Names of post authors and forwarded-from people are left out unless you turn on **Include author names**. Don't use the output to train AI models; Telegram's terms prohibit that. You are responsible for having a lawful reason to process any personal data in the messages you collect.

Independent tool, not affiliated with or endorsed by Telegram. Data comes from Telegram's public channel web previews at t.me.

# Actor input Schema

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

Usernames or t.me/name and t.me/s/name URLs.

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

Maximum unique message rows per channel.

## `since` (type: `string`):

ISO date or timestamp; dates use UTC. Stop paging after older messages.

## `timeoutSecs` (type: `integer`):

Timeout per network operation.

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

Try direct first; retry refused or empty previews through this proxy. Hosted Apify Proxy requires platform configuration.

## `includeMedia` (type: `boolean`):

Include public media metadata and URLs without downloading.

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

Include visible reaction counts; custom emoji without a glyph use custom:ID.

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

Write channel metadata to CHANNEL-name in the key-value store.

## `includeAuthorNames` (type: `boolean`):

Include public author signatures and forwarded-from display names. When disabled, these names are null; channel titles and forwarded-from URLs are retained.

## Actor input object example

```json
{
  "channels": [
    "telegram",
    "durov"
  ],
  "maxMessages": 10,
  "timeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "includeMedia": true,
  "includeReactions": false,
  "includeChannelInfo": true,
  "includeAuthorNames": false
}
```

# Actor output Schema

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

No description

## `messagesCsv` (type: `string`):

No description

## `metadata` (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": [
        "telegram",
        "durov"
    ],
    "maxMessages": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("everyotherfriday/telegram-channels").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": [
        "telegram",
        "durov",
    ],
    "maxMessages": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("everyotherfriday/telegram-channels").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": [
    "telegram",
    "durov"
  ],
  "maxMessages": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call everyotherfriday/telegram-channels --silent --output-dataset

```

## MCP server setup

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

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/KOVfAfvaLVYe5MoNs/builds/5SuLORdevFbFyzuuK/openapi.json
