# Telegram Channel Scraper — posts, views, media (no login) (`arthursbuisness/telegram-public-channel-scraper`) Actor

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

## Pricing

$0.30 / 1,000 telegram 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?

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 — public posts, views, media (no login)

Scrape **any public Telegram channel** into a clean dataset: post text, date, views, author signature, forwarded-from, reply-to, links, hashtags, photos, videos, documents, polls, link previews and reactions — plus the channel's title, description and subscriber count. It reads Telegram's public web preview (`t.me/s/<channel>`), so it needs **no login, no phone number, no API key, no proxies and no browser**. Runs are fast and cheap.

Typical uses: news and crypto-signal monitoring, brand/keyword alerts, competitor and influencer tracking, archiving channels, research datasets, feeding posts into LLM pipelines, Make/Zapier/Sheets automations.

### What you get

One row per post (`type: "post"`):

| field | description |
|---|---|
| `channel`, `post_id`, `url` | Channel handle, numeric message ID, `https://t.me/<channel>/<id>` |
| `date` | ISO 8601 UTC timestamp |
| `text` | Plain text (formatting, emoji and line breaks preserved); `text_html` optional |
| `views` | View counter as a number (e.g. `23M` → 23000000) |
| `author` | Post signature, when the channel signs posts |
| `is_forwarded`, `forwarded_from`, `forwarded_from_url` | Forward source |
| `reply_to_url`, `reply_to_text` | Quoted/replied message |
| `links`, `hashtags` | All hyperlinks in the post; hashtags |
| `media_type` | `text`, `photo`, `album`, `video`, `document`, `poll`, `sticker`, `voice`, `round_video`, `link` |
| `photos`, `videos`, `video_thumbs`, `video_duration` | Direct media URLs (CDN links, may expire after a while) |
| `document_name`, `document_size` | Attached file |
| `poll_question`, `poll_options` | Poll with option percentages |
| `link_preview` | `{url, site_name, title, description, image}` |
| `reactions`, `reactions_total` | `[{emoji, count}]` (custom-emoji reactions have `emoji: null`; Stars shown as ⭐) |
| `comments` | Comment count when the channel has a discussion group and the preview shows it |

With **Include channel info** (default on) you get one `type: "channel"` row per channel: `title, username, description, subscribers, photos, videos, links, files, verified, photo_url, url`.

Channels that cannot be read (private, non-existent, users, bots, groups) produce a `type: "error"` row — free — and the run continues with the next channel.

Export as JSON, CSV or Excel, or push rows to Google Sheets, Make, Zapier, webhooks or your code via the Apify API.

### Input

| field | default | meaning |
|---|---|---|
| `channels` | — | Handles or links: `durov`, `@telegram`, `https://t.me/bloomberg` |
| `maxPostsPerChannel` | 100 | Newest first; stop after this many stored posts |
| `since` | — | Only posts on/after `YYYY-MM-DD` (paging stops at older posts) |
| `keywords` | — | Keep only posts containing one of these words/phrases (case-insensitive) |
| `maxPagesPerChannel` | 50 | Safety cap (~20 posts per page) for how far back to scan |
| `includeChannelInfo` | true | Add one channel-info row per channel |
| `includeHtml` | false | Add `text_html` with the formatted post HTML |

Example — last week's posts mentioning Bitcoin from three channels:

```json
{
  "channels": ["durov", "telegram", "https://t.me/bloomberg"],
  "keywords": ["bitcoin", "BTC"],
  "since": "2026-08-20",
  "maxPostsPerChannel": 200
}
```

Schedule the actor (e.g. hourly) and deduplicate on `channel` + `post_id` to build a continuous monitor.

### Pricing

Pay per event: **$0.0003 per stored row** ($0.30 per 1,000 posts). Each post row and each channel-info row counts as one event. Only rows actually written to the dataset are charged; error rows and filtered-out posts are free. Apify platform usage (a few seconds of compute per run) is billed separately by Apify.

### Limitations — please read

- Works only for channels with a **public web preview** (public channels). Private channels, groups, bots and user profiles are not accessible without login — they return an error row.
- Telegram's preview does not expose the forward count or comment threads; `comments` is only filled when the preview shows a count.
- Media URLs point to Telegram's CDN and can expire; download them soon after the run if you need the files.
- Very old history: each page is ~20 posts, so 10,000 posts = 500 requests (about 5 minutes at the polite rate this actor uses).
- Reactions with custom emoji have no text representation in the preview (`emoji: null`, count still included).

Not affiliated with Telegram. Uses only publicly accessible pages.

# Actor input Schema

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

Public channel handles or links, e.g. 'durov', '@telegram', 'https://t.me/bloomberg' or 'https://t.me/s/bloomberg'. Private channels, users, bots and groups without a public preview yield an error row (free).

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

Newest posts first. Stops after this many stored posts per channel (after keyword/date filtering).

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

Skip posts older than this date and stop paging once older posts are reached.

## `keywords` (type: `array`):

Only keep posts whose text contains at least one of these words/phrases (case-insensitive). Paging continues until 'Max posts' matches or 'Max pages' is reached.

## `maxPagesPerChannel` (type: `integer`):

Each page holds ~20 posts. Limits how far back the actor scans, especially with keyword filters.

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

Add one 'channel' row per channel: title, username, description, subscriber count, photo/video/link counts, verified flag, avatar URL.

## `includeHtml` (type: `boolean`):

Also store the raw formatted HTML of each post (text\_html) next to the plain text.

## Actor input object example

```json
{
  "channels": [
    "telegram",
    "durov"
  ],
  "maxPostsPerChannel": 100,
  "maxPagesPerChannel": 50,
  "includeChannelInfo": true,
  "includeHtml": false
}
```

# Actor output Schema

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

All items as JSON

## `resultsCsv` (type: `string`):

Same dataset as CSV — open in Excel/Sheets

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arthursbuisness/telegram-public-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": [
        "telegram",
        "durov",
    ] }

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

```

## MCP server setup

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