SuperAPI AI Directory

telegram-channel-parser

Data & analytics

View repository

Updated 10-15 19:57

About this skill

telegram-channel-parser

Parsing public Telegram channels via the web preview (t.me/s/). No API keys, no MTProto, zero config.

Before launching

Before running any scripts, create a working copy of the skill in /home/claude/telegram-channel-parser and work from it:

bash scripts/prepare_runtime.sh
cd /home/claude/telegram-channel-parser

prepare_runtime.sh copies the skill and, if there is config/.env, normalizes it via sed -i: unquoted values with spaces or Cyrillic are wrapped in quotes in the working copy.

Config

No tokens are required. For digests — copy .env.example:

cp config/.env.example config/.env

Without .env: the skill works, but channels must be passed explicitly via --channel / --channels.

С .env: the AI channels digest is ready out of the box. The user can add their own categories.

Structure of .env (digest categories):

TG_CATEGORIES=ai,crypto         # реестр доступных категорий
TG_DEFAULT_CATEGORY=ai           # дефолтная при запросе "дайджест"

TG_CHANNELS_AI_LABEL="AI и технологии"
TG_CHANNELS_AI=countwithsasha,evilfreelancer,...

TG_CHANNELS_CRYPTO_LABEL="Криптовалюты"
TG_CHANNELS_CRYPTO=channel1,channel2

Agent algorithm when a digest is requested:

  1. Read config/.env (if present)
  2. Parse TG_CATEGORIES — get the list of available categories
  3. For each category: TG_CHANNELS_<ID> = channels, TG_CHANNELS_<ID>_LABEL = name
  4. Determine the needed category:
    • The user named a topic → match it with _LABEL
    • Did not specify → use TG_DEFAULT_CATEGORY
    • Several categories fit → offer a choice
  5. Pass the channels of the needed category via --channels

If .env is absent → ask which channels to parse, suggest cp config/.env.example config/.env.

Priority: --channels explicit > category from .env > agent asks.

Details: config/README.md.

Philosophy

  1. Always fresh — data is requested in real time on every call. You will never miss a fresh post.
  2. Context window hygiene — stdout is limited to 30 lines. Full data in TSV/CSV. The LLM works with a compact format, not with raw HTML.
  3. Rate limit — there is a 1.5s pause between requests to t.me. We don't get greedy.
  4. Pure POSIX sh — no dependencies other than curl, sed, awk, grep.

In the JSON digest and channel comparison, the last page is used both for posts and for channel information, without re-loading. On each run it is loaded anew; history pages are also requested anew as needed.

Workflow

Parsing a single channel

  1. Get posts:

    bash scripts/fetch_posts.sh --channel countwithsasha --limit 50
    

    Outputs the latest 50 posts in TSV (id, date, views, reactions, fwd_from, fwd_link, text, media_url).

  2. Channel info:

    bash scripts/channel_info.sh --channel countwithsasha
    
  3. Search posts:

    bash scripts/search_posts.sh --channel countwithsasha --query "скилл"
    
  4. Top posts (share parade):

    bash scripts/top_posts.sh --channel countwithsasha --limit 50 --sort reactions
    
  5. Posting schedule:

    bash scripts/posting_schedule.sh --channel countwithsasha --limit 100
    
  6. Export:

    bash scripts/export_csv.sh --channel countwithsasha --limit 100 --csv cache/export.csv
    

Digest for multiple channels

# Явный список каналов
bash scripts/digest.sh --channels "countwithsasha,evilfreelancer,aostrikov_ai_agents" --period today

# Дефолтный набор (без --channels)
bash scripts/digest.sh --period today

Periods: today, yesterday, week, N (last N days).

Channel comparison

bash scripts/compare_channels.sh --channels "channel1,channel2,channel3" --limit 30

Table: subscribers, average views, posting frequency, engagement.

React artifact for the digest

When a digest is requested — render the results as a React artifact (a feed of cards).

Algorithm (4 steps):

  1. Run digest_json.sh — it writes JSON to a file (not stdout!) and returns the path:
    bash scripts/digest_json.sh --period today
    # → prints: cache/digest_today.json
    
  2. Read the JSON file at the output path
  3. Read the template assets/digest-feed.tsx
  4. Replace __DIGEST_DATA__ in the template with the JSON contents, render as a React artifact

Important: the script writes to a file rather than stdout in order to bypass the sandbox buffer limit (~200KB). For a 30-day digest of 15 channels, the JSON can be 500KB+.

Posts are automatically sorted by date (newest on top), interleaved between channels. The user filters by period and channel via the UI.

Scripts

General invocation pattern:

bash scripts/<script>.sh --channel <username> [--limit N] [--before <post_id>] [--csv path]
Script Description Special params
fetch_posts.sh Channel posts → TSV --limit, --before, --after-date YYYY-MM-DD
channel_info.sh Name, description, subscribers —
search_posts.sh Full-text search --query "text"
top_posts.sh Post ranking --sort views|reactions, --limit
posting_schedule.sh Posting time analysis --limit
export_csv.sh Export to CSV --csv path
digest.sh Digest of multiple channels --channels "a,b,c", --period today|yesterday|week|N
digest_json.sh Digest → JSON file (for a React artifact) --channels "a,b,c", --period today|yesterday|week|N
compare_channels.sh Comparison table --channels "a,b,c", --limit N (positive integer)

General parameters

Param Required Default Description
--channel yes* — Channel username (without @)
--channels no from .env Multiple channels separated by commas
--limit no 20 How many posts to load
--before no — Post ID for pagination
--after-date no — Do not load posts older than the date (YYYY-MM-DD)
--csv no — Path for export

*--channel for a single channel, --channels for multi-channel commands.

Channel input

The skill accepts a channel in any format:

  • countwithsasha — just a username
  • @countwithsasha — with an @
  • https://t.me/countwithsasha — a direct link
  • https://t.me/s/countwithsasha — a web preview link
  • t.me/countwithsasha?before=500 — with parameters

Everything is automatically normalized to a bare username.

Limitations

  • Only public channels (those that have a t.me/s/ preview)
  • Telegram does not serve some posts via the web preview. If instead of text you get a suggestion to open Telegram, the text field in TSV/JSON contains [Текст недоступен в веб-превью Telegram: https://t.me/<channel>/<id>]. This is a skill marker, not the author's text: report the skip and give the link, do not retell such a post. Media without a caption remains with empty text if Telegram has not marked it as unsupported.
  • The share counter (shares) is unavailable — t.me/s/ does not provide it, only the MTProto API
  • However, where the post was forwarded from is parsed (fwd_from + link to the original)
  • Reactions are parsed in aggregate (total count across all emojis)
  • Pagination: ~20 posts per page, for 100 posts = 5 requests
  • Rate limit: 1.5s between requests to t.me