# Telegram Channel Scraper - Messages & Views (`thirdwatch/telegram-scraper`) Actor

Scrape public Telegram channel messages via the t.me/s/ web preview. Get message text, view counts, timestamps, author/signature, media flags, forwards, and message URLs. Optional keyword filter. No login, API key, or proxy needed.

- **URL**: https://apify.com/thirdwatch/telegram-scraper.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (community)
- **Categories:** Social media
- **Stats:** 12 total users, 0 monthly users, 98.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 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/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

## Telegram Channel Scraper

> **Thirdwatch portfolio:** 5K users across 88 public Actors, 2M+ records delivered, and >99% run success. [Explore all Thirdwatch Actors](https://apify.com/thirdwatch).

Scrape public Telegram channel messages by username, with view counts, timestamps, media flags, and forwards. Use it for OSINT, brand and crypto monitoring, news tracking, market intelligence, research datasets, and trend discovery.

### What you get

Public Telegram channels are a fast-moving source of announcements, news, and community chatter, but Telegram has no official export for non-members. This actor reads any public channel and converts its posts into clean dataset rows with message text, view count, date, author/signature, media flags, forward info, and a direct message URL, so you can schedule monitoring or export history without joining channels or wrangling raw web pages yourself.

Best fit:

- OSINT and research teams tracking public channels.
- Crypto, markets, and news teams watching announcement channels.
- Brand and comms teams monitoring mentions and leaks.
- Analysts building repeatable message datasets.
- Builders feeding Telegram content into alerts, dashboards, or LLM pipelines.

### Output fields

| Field | Description |
|-------|-------------|
| `channel` | Channel username scraped |
| `message_id` | Numeric message id within the channel |
| `text` | Message text (line breaks preserved) |
| `views` | View count as displayed (e.g. `12.3K`) |
| `datetime` | ISO-8601 publish timestamp |
| `author` | Post signature / author name when present |
| `has_photo` | Message contains a photo |
| `has_video` | Message contains a video or round video |
| `has_document` | Message contains a file, voice, or audio |
| `has_poll` | Message is a poll |
| `has_sticker` | Message is a sticker |
| `is_forwarded` | Message is a forward |
| `forwarded_from` | Original source name when forwarded |
| `is_reply` | Message is a reply |
| `url` | Direct link to the message |

### Input parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `channel` | Yes | Public channel username or `t.me` link (e.g. `durov` or `https://t.me/durov`). |
| `keyword` | No | Only return messages containing this text (case-insensitive). |
| `maxMessages` | No | Maximum messages to return, newest first (default 50). Start small to control cost; raise to pull deeper history. |

#### Example inputs

##### Latest 50 messages from a channel

```json
{
  "channel": "durov",
  "maxMessages": 50
}
```

#### Keyword filter across recent history

```json
{
  "channel": "telegram",
  "keyword": "update",
  "maxMessages": 200
}
```

#### Deep history pull

```json
{
  "channel": "durov",
  "maxMessages": 1000
}
```

You can also paste a full URL such as `https://t.me/durov` or `https://t.me/s/durov` for the `channel` field; it is normalized to the username automatically.

### Example output

```json
{
  "channel": "durov",
  "message_id": 351,
  "text": "Telegram now has 900 million monthly active users.",
  "views": "1.2M",
  "datetime": "2026-03-21T14:05:11+00:00",
  "author": "",
  "has_photo": true,
  "has_video": false,
  "has_document": false,
  "has_poll": false,
  "has_sticker": false,
  "is_forwarded": false,
  "forwarded_from": "",
  "is_reply": false,
  "url": "https://t.me/durov/351"
}
```

### Use cases

- **OSINT and monitoring:** Track public channels for announcements, leaks, and activity over time.
- **Crypto and markets:** Watch token, exchange, and project announcement channels.
- **News tracking:** Capture posts from news and aggregator channels by keyword.
- **Brand monitoring:** Detect mentions of a company, product, or person across channels.
- **Research datasets:** Build repeatable message datasets with timestamps and engagement signals.
- **LLM and automation pipelines:** Feed channel content into summarizers, classifiers, or alerts.

### What you need to run it

Only a public channel username (or its `t.me` link). The actor reads Telegram's public channel preview, walking backwards through history until it reaches your `maxMessages` cap or the start of available history. No Telegram account, login, API key, or setup is required, and only **public** channels with web preview enabled can be read.

### Limitations

- Only public channels with web preview enabled can be scraped. Private channels, groups, and DMs are not accessible and return an error record.
- View counts are the display string Telegram renders (for example `12.3K`), not exact integers.
- Reactions, comment counts, and full media files are not returned; media is reported as boolean flags.
- The web preview exposes channel history but not every historical message for very large or old channels.
- Telegram may rate-limit aggressive pagination; the actor backs off and retries.

### Compared to alternatives

Telegram channel scrapers are crowded on the Apify Store. Here is how this actor differs from the most common options:

- **vs. other Apify Telegram channel scrapers (e.g. `pamnard/telegram-channels-scraper`):** Many existing actors bill you for variable platform usage, so a long run costs whatever the underlying compute happens to use. This actor charges a flat, predictable price per message returned, so you know your cost before you start. It is also lightweight and fast (no heavy browser session, no API token needed to drive it), and returns clean boolean media flags plus normalized ISO-8601 timestamps out of the box.
- **vs. the Telegram Bot API:** The Bot API cannot read arbitrary public channel history unless the bot is an admin of that channel. This actor needs no bot and no membership.
- **vs. account-based scrapers (phone number + API credentials):** Those require a logged-in Telegram session and risk account bans. This actor is login-free and read-only against the public channel preview.
- **vs. manual export:** Telegram Desktop export only works for chats you have already joined. This actor works on any public channel without joining.

### FAQ

**Do I need a Telegram account?**
No. The actor only reads the public web preview that Telegram exposes for public channels.

**Can I scrape private channels or groups?**
No. Only public channels with web preview enabled are accessible. Private channels return an error record instead of failing the run.

**Are view counts exact?**
They are the display values Telegram shows, such as `1.2M` or `12.3K`.

**Can I get full media files?**
Not directly. The actor reports media presence as boolean flags (photo, video, document, poll, sticker).

**How far back can I scrape?**
Up to `maxMessages`, paginating backwards until Telegram stops returning older messages.

### Support and custom builds

Need reactions, comment threads, media downloads, multi-channel batches, scheduled alerts, or dashboard-ready exports? Contact Thirdwatch at [thirdwatch.dev](https://thirdwatch.dev) or through the Apify actor support channel.

Last verified: 2026-06

# Actor input Schema

## `channel` (type: `string`):

Public Telegram channel username to scrape (e.g. 'durov'). You can paste a full URL like 'https://t.me/durov' or 't.me/s/durov' -- it will be normalized to the username. The channel must be public and have web preview enabled.

## `keyword` (type: `string`):

Optional. If set, only messages whose text contains this keyword (case-insensitive) are returned. Leave empty to return all messages.

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

Maximum number of messages to return. The actor paginates backwards through channel history until this many messages are collected or the channel history ends.

## Actor input object example

```json
{
  "channel": "durov",
  "keyword": "",
  "maxMessages": 50
}
```

# Actor output Schema

## `results` (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 = {
    "channel": "durov",
    "maxMessages": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/telegram-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 = {
    "channel": "durov",
    "maxMessages": 50,
}

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

```

## MCP server setup

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

```

## OpenAPI specification

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