# Telegram Channel Scraper — Posts, Views & Engagement (`viralanalyzer/telegram-channel-scraper`) Actor

Extract posts, view counts, subscriber numbers, and engagement metrics from public Telegram channels. Pure HTTP via t.me/s/ public preview — no API key, no login. Track competitors, monitor channels, and analyze reach for growth and market research. Clean JSON.

- **URL**: https://apify.com/viralanalyzer/telegram-channel-scraper.md
- **Developed by:** [viralanalyzer](https://apify.com/viralanalyzer) (community)
- **Categories:** Social media
- **Stats:** 166 total users, 45 monthly users, 97.2% runs succeeded, 2 bookmarks
- **User rating**: 4.82 out of 5 stars

## Pricing

from $15.75 / 1,000 post scrapeds

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 — Posts, Views, Subscribers & Engagement Analytics

> **$0.03 per post** · 📡 public channels · ⚡ no API key or bot token needed
> 🔗 [View on Apify Store](https://apify.com/viralanalyzer/telegram-channel-scraper) | 🇺🇸 English | [🇧🇷 Português](#português)

Extract **posts, view counts, subscriber numbers, and engagement metrics** from public Telegram channels. Uses t.me/s/ public preview pages — pure HTTP with Cheerio parsing, no Telegram API key or bot token needed.

**Who it's for:** social-media analysts, crypto & community researchers, OSINT investigators, and growth teams who need public-channel metrics without an API key or bot token.

▶️ Click **Try for free** — your first run returns real data in seconds.

### ✨ Features

- **Multi-channel scraping** — Analyze up to 50 public Telegram channels per run
- **Post extraction** — Full text, views, date, media type, forwarded source
- **Subscriber count** — Channel subscriber/member numbers
- **Channel analytics summary** — Average views, median views, max views, engagement rate, media ratio
- **Media detection** — Classifies photo, video, document, sticker, and poll content
- **Forwarded post attribution** — Identifies the original channel for forwarded posts
- **Pagination** — Automatically loads older posts via before= parameter
- **Flexible input** — Accepts usernames, @handles, or full t.me URLs
- **Anti-placeholder guardrails** — Every result validated against placeholder patterns
- **Pure HTTP** — Uses got-scraping + Cheerio, no browser needed

### 📥 Input

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `channels` | string\[] | Yes | — | Telegram channel usernames or URLs. Accepts "durov", "@durov", "https://t.me/durov", or "https://t.me/s/durov" (1-50 channels) |
| `maxPostsPerChannel` | integer | No | 50 | Maximum number of posts to extract per channel (1-500) |
| `proxyConfiguration` | object | No | — | Proxy settings. May be needed if Telegram blocks your IP |

#### Input Example

```json
{
  "channels": [
    "durov",
    "https://t.me/telegram",
    "@bbcnews"
  ],
  "maxPostsPerChannel": 100
}
```

### 📤 Output

Each run produces two types of results: **channel\_summary** (one per channel) and **post** (one per post).

#### Post Fields

| Field | Type | Description |
|---|---|---|
| `type` | string | Always "post" |
| `postId` | number | Telegram post ID (numeric) |
| `postUrl` | string | Direct link to the post (https://t.me/username/postId) |
| `text` | string | Full post text content |
| `views` | number | View count (parsed from K/M suffixes) |
| `viewsText` | string | Raw view text as displayed (e.g., "12.5K") |
| `mediaType` | string | Content type: none, photo, video, document, sticker, or poll |
| `mediaUrl` | string | Media URL (available for photos) |
| `hasReply` | boolean | Whether the post has a reply |
| `forwardedFrom` | string | Original channel name if forwarded, empty otherwise |
| `publishedAt` | string | Post publication date (ISO 8601) |
| `channelName` | string | Channel display name |
| `channelUsername` | string | Channel username |
| `channelSubscribers` | number | Channel subscriber count |
| `platform` | string | Always "telegram" |
| `scrapedAt` | string | ISO 8601 scrape timestamp |

#### Channel Summary Fields

| Field | Type | Description |
|---|---|---|
| `type` | string | Always "channel\_summary" |
| `channelName` | string | Channel display name |
| `channelUsername` | string | Channel username |
| `channelSubscribers` | number | Total subscriber count |
| `channelDescription` | string | Channel bio/description |
| `channelPhotoUrl` | string | Channel profile photo URL |
| `postCount` | number | Number of posts analyzed |
| `avgViews` | number | Average views per post |
| `medianViews` | number | Median views per post |
| `maxViews` | number | Highest view count among analyzed posts |
| `engagementRate` | number | Average views / subscribers ratio (0-1 scale) |
| `postsWithMedia` | number | Count of posts containing media |
| `postsForwarded` | number | Count of posts forwarded from other channels |
| `topPostText` | string | Text of the most-viewed post (first 200 chars) |
| `topPostViews` | number | View count of the most-viewed post |
| `platform` | string | Always "telegram" |
| `scrapedAt` | string | ISO 8601 scrape timestamp |

#### Output Example

```json
{
  "type": "post",
  "postId": 1042,
  "postUrl": "https://t.me/durov/1042",
  "text": "Telegram now has 950 million monthly active users. We hope to pass the one billion mark soon.",
  "views": 4832100,
  "viewsText": "4.8M",
  "mediaType": "photo",
  "mediaUrl": "https://cdn4.telegram-cdn.org/file/abc123.jpg",
  "hasReply": false,
  "forwardedFrom": "",
  "publishedAt": "2026-02-15T18:30:00+00:00",
  "channelName": "Pavel Durov",
  "channelUsername": "durov",
  "channelSubscribers": 12450000,
  "platform": "telegram",
  "scrapedAt": "2026-03-06T12:00:00.000Z"
}
```

### 📋 Use Cases

- **Channel Analytics** — Measure engagement rates, view trends, and content performance
- **Competitor Monitoring** — Track competitor Telegram channels and their posting strategies
- **Content Research** — Discover viral posts and high-performing content formats
- **Media Monitoring** — Track news channels and detect breaking stories
- **Influencer Analysis** — Evaluate channel reach, engagement, and audience size
- **Market Intelligence** — Monitor industry channels for trends and announcements

### ❓ FAQ

**Q: Can I scrape private Telegram channels?**
A: No. This actor only works with public channels that have a public preview at t.me/s/. Private channels and groups are not accessible without authentication.

**Q: Why are some view counts showing as 0?**
A: View counts are extracted from the HTML and parsed from human-readable formats (e.g., "4.8M", "12.5K"). Very new posts or channels with hidden view counts may return 0. The raw `viewsText` field is also included for reference.

**Q: What is the engagement rate and how is it calculated?**
A: The engagement rate in the channel summary is calculated as average views divided by subscriber count. A rate of 0.3 means posts are seen by 30% of subscribers on average.

**Q: How far back can I scrape posts?**
A: The actor paginates through the public preview pages using the before= parameter. You can go back up to 500 posts per channel. The actual depth depends on the channel's history and Telegram's preview page availability.

**Q: Do I need a Telegram API key or bot token?**
A: No. The actor uses the public t.me/s/ preview pages which are accessible via standard HTTP requests. No API credentials are needed.

### 💰 Pricing

This actor uses **Pay Per Event (PPE)** pricing:

| Metric | Cost |
|--------|------|
| post-scraped | $0.03 per post |

Example: scraping 3 channels x 50 posts each = 153 items (150 posts + 3 summaries) = $4.59

### 🔗 Related Actors

- [YouTube Fast Scraper](https://apify.com/viralanalyzer/youtube-fast-scraper) — YouTube video metrics
- [TikTok Viral Scanner](https://apify.com/viralanalyzer/tiktok-viral-scanner) — TikTok profile data
- [Instagram Reels Scraper](https://apify.com/viralanalyzer/instagram-reels-scraper) — Instagram metrics
- [Twitter/X Scraper](https://apify.com/viralanalyzer/twitter-scraper) — Twitter post extraction

### 📝 Changelog

#### v1.0 (Current)

- Public channel post extraction via t.me/s/ preview pages
- Subscriber count and channel metadata extraction
- Post pagination via before= parameter
- Media type detection (photo, video, document, sticker, poll)
- Forwarded post attribution
- Channel summary with engagement analytics (avg/median/max views, engagement rate)
- Flexible input: accepts usernames, @handles, and full URLs
- Anti-placeholder guardrails for data integrity
- Rate limit handling with automatic retries
- PPE billing integration

***

<a name="português"></a>

## 📡 Telegram Channel Scraper — Posts, Visualizações, Inscritos & Analytics de Engajamento

> **$0.03 por post** · 📡 canais públicos · ⚡ sem chave de API ou bot token
> 🔗 [Ver na Apify Store](https://apify.com/viralanalyzer/telegram-channel-scraper) | [🇺🇸 English](#-telegram-channel-scraper--posts-views-subscribers--engagement-analytics) | 🇧🇷 Português

Extraia **posts, contagem de visualizações, número de inscritos e métricas de engajamento** de canais públicos do Telegram. Usa as páginas de preview públicas t.me/s/ — HTTP puro com parsing Cheerio, sem chave de API ou bot token do Telegram.

**Para quem é:** analistas de mídias sociais, pesquisadores de cripto & comunidades, investigadores OSINT e times de growth que precisam de métricas de canais públicos sem chave de API ou bot token.

▶️ Clique em **Testar grátis** — sua primeira execução retorna dados reais em segundos.

### ✨ Funcionalidades

- **Scraping multi-canal** — Analise até 50 canais públicos do Telegram por execução
- **Extração de posts** — Texto completo, visualizações, data, tipo de mídia, fonte encaminhada
- **Contagem de inscritos** — Número de inscritos/membros do canal
- **Resumo analítico do canal** — Média de views, mediana, máximo, taxa de engajamento, proporção de mídia
- **Detecção de mídia** — Classifica conteúdo de foto, vídeo, documento, sticker e enquete
- **Atribuição de posts encaminhados** — Identifica o canal original para posts encaminhados
- **Paginação** — Carrega posts mais antigos automaticamente via parâmetro before=
- **Entrada flexível** — Aceita usernames, @handles ou URLs completas do t.me
- **Guardrails anti-placeholder** — Todo resultado validado contra padrões falsos
- **HTTP puro** — Usa got-scraping + Cheerio, sem browser

### 📥 Entrada

| Parâmetro | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
| `channels` | string\[] | Sim | — | Usernames ou URLs de canais do Telegram. Aceita "durov", "@durov", "https://t.me/durov" ou "https://t.me/s/durov" (1-50 canais) |
| `maxPostsPerChannel` | inteiro | Não | 50 | Número máximo de posts por canal (1-500) |
| `proxyConfiguration` | objeto | Não | — | Configuração de proxy. Pode ser necessário se o Telegram bloquear seu IP |

#### Exemplo de Entrada

```json
{
  "channels": [
    "durov",
    "https://t.me/telegram",
    "@bbcnews"
  ],
  "maxPostsPerChannel": 100
}
```

### 📤 Saída

Cada execução produz dois tipos de resultado: **channel\_summary** (um por canal) e **post** (um por post).

#### Campos do Post

| Campo | Tipo | Descrição |
|---|---|---|
| `type` | string | Sempre "post" |
| `postId` | número | ID do post no Telegram (numérico) |
| `postUrl` | string | Link direto para o post (https://t.me/username/postId) |
| `text` | string | Conteúdo textual completo do post |
| `views` | número | Contagem de visualizações (parseado de sufixos K/M) |
| `viewsText` | string | Texto bruto de views como exibido (ex: "12.5K") |
| `mediaType` | string | Tipo de conteúdo: none, photo, video, document, sticker ou poll |
| `mediaUrl` | string | URL da mídia (disponível para fotos) |
| `hasReply` | boolean | Se o post tem resposta |
| `forwardedFrom` | string | Nome do canal original se encaminhado, vazio caso contrário |
| `publishedAt` | string | Data de publicação do post (ISO 8601) |
| `channelName` | string | Nome de exibição do canal |
| `channelUsername` | string | Username do canal |
| `channelSubscribers` | número | Contagem de inscritos do canal |
| `platform` | string | Sempre "telegram" |
| `scrapedAt` | string | Timestamp ISO 8601 da coleta |

#### Campos do Resumo do Canal

| Campo | Tipo | Descrição |
|---|---|---|
| `type` | string | Sempre "channel\_summary" |
| `channelName` | string | Nome de exibição do canal |
| `channelUsername` | string | Username do canal |
| `channelSubscribers` | número | Total de inscritos |
| `channelDescription` | string | Bio/descrição do canal |
| `channelPhotoUrl` | string | URL da foto de perfil do canal |
| `postCount` | número | Número de posts analisados |
| `avgViews` | número | Média de visualizações por post |
| `medianViews` | número | Mediana de visualizações por post |
| `maxViews` | número | Maior contagem de views entre os posts analisados |
| `engagementRate` | número | Razão média de views / inscritos (escala 0-1) |
| `postsWithMedia` | número | Quantidade de posts contendo mídia |
| `postsForwarded` | número | Quantidade de posts encaminhados de outros canais |
| `topPostText` | string | Texto do post mais visualizado (primeiros 200 caracteres) |
| `topPostViews` | número | Views do post mais visualizado |
| `platform` | string | Sempre "telegram" |
| `scrapedAt` | string | Timestamp ISO 8601 da coleta |

#### Exemplo de Saída

```json
{
  "type": "post",
  "postId": 1042,
  "postUrl": "https://t.me/durov/1042",
  "text": "Telegram now has 950 million monthly active users. We hope to pass the one billion mark soon.",
  "views": 4832100,
  "viewsText": "4.8M",
  "mediaType": "photo",
  "mediaUrl": "https://cdn4.telegram-cdn.org/file/abc123.jpg",
  "hasReply": false,
  "forwardedFrom": "",
  "publishedAt": "2026-02-15T18:30:00+00:00",
  "channelName": "Pavel Durov",
  "channelUsername": "durov",
  "channelSubscribers": 12450000,
  "platform": "telegram",
  "scrapedAt": "2026-03-06T12:00:00.000Z"
}
```

### 📋 Casos de Uso

- **Analytics de Canal** — Meça taxas de engajamento, tendências de views e performance de conteúdo
- **Monitoramento de Concorrentes** — Acompanhe canais de concorrentes e estratégias de postagem
- **Pesquisa de Conteúdo** — Descubra posts virais e formatos de conteúdo de alta performance
- **Monitoramento de Mídia** — Acompanhe canais de notícias e detecte matérias em destaque
- **Análise de Influenciadores** — Avalie alcance, engajamento e tamanho da audiência
- **Inteligência de Mercado** — Monitore canais do setor para tendências e anúncios

### ❓ Perguntas Frequentes

**P: Posso extrair dados de canais privados do Telegram?**
R: Não. Este actor funciona apenas com canais públicos que possuem preview público em t.me/s/. Canais e grupos privados não são acessíveis sem autenticação.

**P: Por que algumas contagens de visualização aparecem como 0?**
R: As contagens de views são extraídas do HTML e parseadas de formatos legíveis (ex: "4.8M", "12.5K"). Posts muito recentes ou canais com views ocultas podem retornar 0. O campo bruto `viewsText` também é incluído para referência.

**P: O que é a taxa de engajamento e como é calculada?**
R: A taxa de engajamento no resumo do canal é calculada como média de visualizações dividida pela contagem de inscritos. Uma taxa de 0.3 significa que os posts são vistos por 30% dos inscritos em média.

**P: Até onde posso voltar nos posts de um canal?**
R: O actor pagina pelas páginas de preview públicas usando o parâmetro before=. Você pode voltar até 500 posts por canal. A profundidade real depende do histórico do canal e da disponibilidade da página de preview do Telegram.

**P: Preciso de uma chave de API ou bot token do Telegram?**
R: Não. O actor usa as páginas de preview públicas t.me/s/ que são acessíveis via requisições HTTP padrão. Nenhuma credencial de API é necessária.

### 💰 Preços

Este actor usa precificação **Pay Per Event (PPE)**:

| Métrica | Custo |
|---------|-------|
| post-scraped | $0.03 por post |

Exemplo: extrair 3 canais x 50 posts cada = 153 itens (150 posts + 3 resumos) = $4.59

### 🔗 Actors Relacionados

- [YouTube Fast Scraper](https://apify.com/viralanalyzer/youtube-fast-scraper) — Métricas do YouTube
- [TikTok Viral Scanner](https://apify.com/viralanalyzer/tiktok-viral-scanner) — Dados do TikTok
- [Instagram Reels Scraper](https://apify.com/viralanalyzer/instagram-reels-scraper) — Métricas do Instagram
- [Twitter/X Scraper](https://apify.com/viralanalyzer/twitter-scraper) — Extração de posts do Twitter

### 📝 Changelog

#### v1.0 (Atual)

- Extração de posts de canais públicos via preview t.me/s/
- Contagem de inscritos e metadados do canal
- Paginação de posts via parâmetro before=
- Detecção de tipo de mídia (foto, vídeo, documento, sticker, enquete)
- Atribuição de posts encaminhados
- Resumo do canal com analytics de engajamento (média/mediana/max views, taxa de engajamento)
- Entrada flexível: aceita usernames, @handles e URLs completas
- Guardrails anti-placeholder para integridade de dados
- Tratamento de rate limit com retentativas automáticas
- Integração com cobrança PPE

***

💡 **Need AI analysis on top of this data — sentiment, trend detection and a dashboard, with no API keys to manage?**
[ViralAnalyzer](https://viralanalyzer.com.br) runs this actor + 42 more data sources with built-in AI. JSON + insights in one call.

# Actor input Schema

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

Telegram channel usernames (e.g., 'durov') or full URLs (e.g., 'https://t.me/durov'). Only public channels are supported.

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

Maximum number of posts to extract per channel. Uses pagination to load older posts.

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

Proxy settings. May be needed if Telegram blocks your IP.

## Actor input object example

```json
{
  "channels": [
    "durov"
  ],
  "maxPostsPerChannel": 5
}
```

# Actor output Schema

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

Dataset containing all scraped results. Each item follows the dataset schema.

# 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"
    ],
    "maxPostsPerChannel": 5
};

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

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

```

## MCP server setup

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

```

## OpenAPI specification

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