# Telegram Channels Scraper (`maximedupre/telegram-channels-scraper`) Actor

Find public Telegram channels by keyword or enrich known @handles and t.me links. Export titles, usernames, descriptions, member counts, visible flags, profile photos, and optional recent message previews.

- **URL**: https://apify.com/maximedupre/telegram-channels-scraper.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Stats:** 82 total users, 35 monthly users, 98.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.90 / 1,000 channels

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/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

### 🔎 Find public Telegram channels for research

Researchers, marketers, and community teams can use Telegram Channels Scraper to find public [Telegram](https://telegram.org/) channels from search terms or enrich known `@handles`, usernames, and `t.me` links. It returns channel titles, usernames, public URLs, descriptions, member or subscriber counts, visible flags, profile photos, discovery evidence, and optional recent message previews in clean dataset rows.

- Find public channels for topics such as AI, crypto, marketing, news, or sports with **[Telegram channels search](https://apify.com/maximedupre/telegram-channels-scraper/examples/telegram-channels-search)**.
- Build a research or outreach list with **[Telegram channels list](https://apify.com/maximedupre/telegram-channels-scraper/examples/telegram-channels-list)** and public channel details.
- Enrich known public handles or links with **[Telegram handles enrichment](https://apify.com/maximedupre/telegram-channels-scraper/examples/telegram-handles-enrichment)**.
- Compare fields across markets, communities, creators, competitors, or news sources with **[Telegram channel metadata](https://apify.com/maximedupre/telegram-channels-scraper/examples/telegram-channel-metadata)**.
- Add a small public post sample without collecting a full message history with **[Telegram recent-message preview](https://apify.com/maximedupre/telegram-channels-scraper/examples/telegram-recent-message-preview)**.

#### 📦 Public Telegram channel rows

**Returned data**

Each saved row is the first eligible public match from a search term or known target. The row keeps the source context for that first match. Depending on what Telegram and the discovery source show, it can include channel identity, public counts and flags, a profile photo URL, keyword directory evidence, and up to five recent public messages.

#### ▶️ Search or enrich known targets

**Run steps**

1. Add search terms, known public channels, or both.
2. Set the saved-row and per-term limits, or leave either limit empty to return all available results until its public source is exhausted.
3. Turn on **Recent message preview** only when you need a small sample of recent public posts.
4. Start the Actor and open the dataset.

**First-match rule**

When the same channel appears again through another keyword, URL, handle, or similar submitted value, the Actor keeps the first eligible saved row and ignores the later match. The saved row shows only the first match's search term or known-target position.

#### ⚙️ Input

Use search terms, known channels, or both in one run. The two limits can be left empty to return all available results until the public source is exhausted.

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `searchTerms` | array of strings | Searches for public Telegram channels by words or topics. Up to 50 non-empty values. |
| `channelTargets` | array of strings | Enriches public Telegram usernames, `@handles`, `t.me` links, or `telegram.me` links. Up to 1,000 non-empty values. |
| `maxChannels` | integer | Maximum saved channel rows across search results and known targets. Leave it empty to return all available results until the public sources are exhausted. |
| `maxChannelsPerSearchTerm` | integer | Maximum channels to consider for each search term. Leave it empty to return all available results for each term until that public source is exhausted. |
| `includeRecentMessagesPreview` | boolean | Adds a small sample of recent public messages to each saved row. It is off by default. |
| `maxPreviewMessagesPerChannel` | integer | Sets the preview size when previews are on. Use 1 to 5, or leave it at 0 when previews are off. |

**Example input**

This is the public input from a successful current-beta default-input run:

```json
{
  "searchTerms": [
    "ai"
  ],
  "channelTargets": [
    "@telegram"
  ],
  "maxChannels": 10,
  "maxChannelsPerSearchTerm": 10,
  "includeRecentMessagesPreview": false,
  "maxPreviewMessagesPerChannel": 0
}
```

**Public scope**

Only public Telegram pages are supported. Private `/c/` links, invite-only chats, hidden member lists, Telegram login, cookies, phone numbers, and Telegram API keys are not supported.

#### 🧾 Output

Each saved row follows one public dataset shape. The output schema exposes `results` as a link to the default dataset. Values that Telegram or the discovery source does not show can be `null`, and `recentMessages` is an array that can be empty.

**Output link**

| Field | Type | What it does |
| --- | --- | --- |
| `results` | string | Links to the saved rows in the default dataset. |

**Dataset row fields**

| Field | Type | What it does |
| --- | --- | --- |
| `resultPosition` | integer | Number of this row in the saved results. |
| `matchedSearchTerm` | string or null | Search term that first found the row; `null` for a known target. |
| `inputIndex` | integer or null | Zero-based position of the known target; `null` for a keyword result. |
| `username` | string | Public Telegram username without the `@` sign. |
| `channelUrl` | string | Canonical public Telegram URL. |
| `channelTitle` | string or null | Public channel or group title, when shown. |
| `description` | string or null | Public channel or group description, when shown. |
| `entityKind` | string or null | Public Telegram entity type, such as `channel`, `group`, `bot`, `user`, or `unknown`. |
| `memberCount` | integer or null | Public member or subscriber count, when shown. |
| `isVerified` | boolean or null | Says whether Telegram shows the entity as verified. |
| `isScam` | boolean or null | Says whether Telegram marks the entity as a scam. |
| `isFake` | boolean or null | Says whether Telegram marks the entity as fake. |
| `isRestricted` | boolean or null | Says whether Telegram marks the entity as restricted. |
| `isBot` | boolean or null | Says whether Telegram identifies the entity as a bot. |
| `profilePhotoUrl` | string or null | Public profile photo URL, when shown. |
| `directory` | object or null | Public directory evidence for a keyword match; `null` for a known target. |
| `directory.title` | string or null | Title shown by the public directory. |
| `directory.description` | string or null | Description shown by the public directory. |
| `directory.memberCount` | integer or null | Member count shown by the public directory. |
| `directory.url` | string or null | Public directory URL used to find the channel. |
| `recentMessages` | array of objects | Up to five recent public messages when the preview is on. |
| `recentMessages[].messageId` | string | Telegram message ID in the channel. |
| `recentMessages[].date` | string or null | Message date and time, when shown. |
| `recentMessages[].text` | string or null | Visible message text or caption, when present. |
| `recentMessages[].views` | integer or null | Visible view count, when present. |

**Keyword-search row**

This is a complete row from a successful current-beta keyword run:

```json
{
  "matchedSearchTerm": "telegram",
  "inputIndex": null,
  "username": "hasbunallohi_va_nemal_vakii",
  "channelUrl": "https://t.me/hasbunallohi_va_nemal_vakii",
  "channelTitle": "Telegram",
  "description": "You can view and join @hasbunallohi_va_nemal_vakii right away.",
  "entityKind": "group",
  "memberCount": 19,
  "isVerified": false,
  "isScam": false,
  "isFake": false,
  "isRestricted": false,
  "isBot": false,
  "profilePhotoUrl": "https://cdn4.telesco.pe/file/On14fWeRpkRD4mvrpEVmMpgzbLjkabmjubpHyFFASrifvkgrQFYoT1c7HfbL4OXoO17ofKYvGBoiX49RFFKDIdVTcl4_nvzwHmA51WRroejG_ACMPtYB5fyw1JDIbTAvhHM0r8a5roHvMfQptknyCtOSNalwvb_ELLGnraqFhAtj-GhPoVPv06guiAt60Tv0Nn6tw_Tsg7ts4vKenJZzCPscznjjIdtm1ARAp6vn_NJboVoJdUjksdd3SdMYYjnf3-d8lLXV_lLZM1TfWL9x6p9yyKrywLf-K5gBiavnxpOvMvIe9ulCqvYjam1h2B9RlW6yGbosqbdhDTb0OlhfzA.jpg",
  "directory": {
    "title": "Telegram",
    "description": null,
    "memberCount": null,
    "url": "https://lyzem.com/search?q=telegram&f=channels"
  },
  "recentMessages": [],
  "resultPosition": 1
}
```

**Known-target row with a preview**

This is a complete row from a successful current-beta run with one recent public message preview:

```json
{
  "matchedSearchTerm": null,
  "inputIndex": 0,
  "username": "telegram",
  "channelUrl": "https://t.me/telegram",
  "channelTitle": "Telegram News",
  "description": "The official Telegram on Telegram. Much recursion. Very Telegram. Wow.",
  "entityKind": "channel",
  "memberCount": 9916916,
  "isVerified": true,
  "isScam": false,
  "isFake": false,
  "isRestricted": false,
  "isBot": false,
  "profilePhotoUrl": "https://cdn1.telesco.pe/file/p3pErmy-bGr0R07jl-Jy_EJ_3ZsthT0VjKSUY8IrImZ8Clyo0bO_9bHryNzQbN_Ok1wfKhfk-9A8Zv3T09upqHm33pOwnCowWNod3lUl-rVTzs7xp8_JUquGVrrVVVV0dcBnKC5gTGZvhfrwI-8k4ehIzjaSb97DgTYHzXck4ID8jTQfP7ttLrAetoIqP41-2kot9mwBZp_DVSHVT2Wp4LTFggHU2AOiUinPlSDsUvW5qKpWcwAtTCPAPZmN3uN6RICabnEDoGW_XkdeLarVudWjMbMThSxYgBaGbIbZSD1gYIt8zlKAFmy5MeTdr_oPp542KJJJnzu23ID0dLF7kQ.jpg",
  "directory": null,
  "recentMessages": [
    {
      "messageId": "435",
      "date": null,
      "text": "AI Text Editor. The message bar now has a built-in editor that can instantly fix grammar, translate your text or rewrite it in several styles:🤝 Formal🎯 Short🍖 Tribal🗿 Zen🕯 Biblical💼 CorpTelegram AI features are 100% private and optional – powered by the Cocoon AI Network.March Features1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • More",
      "views": 1500000
    }
  ],
  "resultPosition": 1
}
```

**Exports**

You can export the dataset as JSON, CSV, Excel, XML, RSS, or HTML, or read it through the Apify API.

#### 💳 Pricing

**Pay-per-event**

This Actor uses pay-per-event pricing. The charged event is one saved public Telegram channel row. Apify shows the current price before you start a paid run.

#### 🔌 Integrations

**Apify access**

Run the Actor from the Apify API and move the default dataset into your own script, sheet, dashboard, CRM, or data workflow. Dataset exports are available as JSON, CSV, Excel, XML, RSS, or HTML.

**Video guide**

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens when the same channel matches more than once?

The first eligible match is saved at once. Later matches from another keyword, URL, handle, or similar submitted value are ignored, so the row keeps only the first match's source context.

##### What happens when I leave a channel limit empty?

`maxChannels` returns all available results until the public sources are exhausted. `maxChannelsPerSearchTerm` does the same for each search term when it is empty.

##### Can I search for public Telegram channels?

Yes. Add one or more topics or keywords to **Search terms**, such as markets, products, regions, creators, or communities. The saved rows include the first matching search term when the source provides it.

##### Can I enrich a channel I already know?

Yes. Add a public username, `@handle`, `t.me` link, or `telegram.me` link to **Known channels**. You can use known targets alone or with search terms.

##### Can I add recent Telegram messages?

Yes. Turn on **Recent message preview** and set `maxPreviewMessagesPerChannel` from 1 to 5. The row can then include a small sample of recent public messages when they are visible.

##### Does it need a Telegram account or API key?

No. It uses public Telegram pages and does not need a Telegram login, cookies, phone number, or API key.

##### Can it scrape Telegram members or private channels?

No. It can return a public member or subscriber count when shown, but it does not collect member lists or private content.

##### Does it export full Telegram message history?

No. It adds only a small recent-message preview. Use a dedicated Telegram channel messages scraper when you need more than a small preview.

##### Can it return every channel that matches a keyword?

No exhaustive match set is promised. Available source results, your limits, and first-match deduplication affect which rows are saved.

##### Why use this instead of the Telegram API?

The Telegram API can fit an authenticated app workflow. This Actor is for public channel discovery and known-target enrichment without Telegram credentials.

### 📝 Changelog

**1.0: More reliable channel results and clearer output**

- Return completed public channel rows during larger runs, even when some individual lookups are unavailable.
- Provide focused channel rows with canonical URLs, search or target context, public details, and optional recent-message previews.

**0.0: Initial release**

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~telegram-channels-scraper/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Telegram Info Scraper](https://apify.com/maximedupre/telegram-info-scraper) — Enrich public Telegram usernames, channels, groups, bots, and profiles.
- [Telegram Channel Messages Scraper](https://apify.com/maximedupre/telegram-channel-messages-scraper) — Collect public posts when a recent preview is not enough.
- [Telegram Media Downloader](https://apify.com/maximedupre/telegram-media-downloader) — Get public photo and video links from posts after you find the right channels.
- [YouTube Channel Search Scraper](https://apify.com/maximedupre/youtube-channel-search-scraper) — Find public YouTube channels when your research spans another platform.
- [BORG Telegram channel scraper](https://apify.com/acid-base/borg-telegram-scraper) — Export public channel posts and history for deeper message research.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `searchTerms` (type: `array`):

Words or topics for finding public Telegram channels.

## `channelTargets` (type: `array`):

Add a public Telegram username, @handle, t.me link, or telegram.me link to get channel details.

## `maxChannels` (type: `integer`):

Maximum channel rows to save across search results and known channels. Leave it empty to return all available results until the public sources are exhausted.

## `maxChannelsPerSearchTerm` (type: `integer`):

Maximum channels to consider for each search term. Leave it empty to return all available results for each term until that public source is exhausted.

## `includeRecentMessagesPreview` (type: `boolean`):

Add a small sample of recent public messages to each saved channel row.

## `maxPreviewMessagesPerChannel` (type: `integer`):

Set how many recent public messages to include per channel when the preview is on. Use 1 to 5, or leave it at 0 when previews are off.

## Actor input object example

```json
{
  "searchTerms": [
    "ai"
  ],
  "channelTargets": [
    "@telegram"
  ],
  "maxChannels": 10,
  "maxChannelsPerSearchTerm": 10,
  "includeRecentMessagesPreview": false,
  "maxPreviewMessagesPerChannel": 0
}
```

# Actor output Schema

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

Links to saved rows with public channel details and their first search or target source.

# 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 = {
    "searchTerms": [
        "ai"
    ],
    "channelTargets": [
        "@telegram"
    ],
    "maxChannels": 10,
    "maxChannelsPerSearchTerm": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/telegram-channels-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 = {
    "searchTerms": ["ai"],
    "channelTargets": ["@telegram"],
    "maxChannels": 10,
    "maxChannelsPerSearchTerm": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/telegram-channels-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 '{
  "searchTerms": [
    "ai"
  ],
  "channelTargets": [
    "@telegram"
  ],
  "maxChannels": 10,
  "maxChannelsPerSearchTerm": 10
}' |
apify call maximedupre/telegram-channels-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/XLZrXJRQuXWu19mKy/builds/hwJwgeVfCjWO9xhJc/openapi.json
