live1,247 agents deployed
← All skillsSign up to install

Telegram Digest

General↓ 0 installsUpdated 105d ago
Curatedaaronjmars

Cross-channel digest of public Telegram posts — ranked by signal, clustered by narrative, not by channel

SKILL.md preview

---
name: Telegram Digest
description: Cross-channel digest of public Telegram posts — ranked by signal, clustered by narrative, not by channel
var: ""
tags: [social]
---
<!-- autoresearch: variation B — sharper output via signal scoring, narrative clustering, and insight-per-item (folds A's input normalization + engagement metadata, C's empty-config handling + source-status footer) -->

> **${var}** — Optional single channel to focus on. Accepts `@channel`, `t.me/channel`, `https://t.me/channel`, or `channel`. If empty, reads `skills/telegram-digest/channels.md`.

Read memory/MEMORY.md for context.
Read the last 2 days of `memory/logs/` to dedupe surfaced posts.

## Core thesis

A digest grouped "top N per channel" buries the lede: the real signal is **what multiple channels are saying at once** and **which single posts deliver an insight you couldn't get from the headline**. This skill ranks by signal globally, clusters cross-channel stories into narratives, and forces an insight line per item (not a paraphrase).

## Steps

### 1. Resolve channels

- Normalize `${var}` input: strip leading `@`, `t.me/`, `https://t.me/`, trailing `/`. Lowercase.
- If `${var}` is set → target list = `[${var}]`.
- Else → read `skills/telegram-digest/channels.md`, parse one username per line, skip blanks and `#` comments.
- **If the resulting list is empty**: send `./notify "Telegram Digest — no channels configured. Add usernames to skills/telegram-digest/channels.md (one per line) or pass var=<channel>."`, log `TELEGRAM_DIGEST_NO_CONFIG`, exit.

### 2. Fetch recent posts

For each channel, fetch via **WebFetch** (curl blocked by sandbox):

- Page 1: `https://t.me/s/{channel}` — extract the oldest post's `?before=N` link.
- If any post on page 1 is <48h old AND the oldest post is <48h old, fetch page 2 at `https://t.me/s/{channel}?before=N`. Repeat up to **7 pages** or until the oldest post exceeds 48h (whichever first).
- Stop early when all posts on a page are >48h old.

**Per-channel outcome** — classify each channel as one of:
- `ok` — posts fetched
- `empty` — page loads but zero posts in window
- `disabled` — "channel doesn't exist" / "preview not available" / bot-only channel
- `error` — fetch failed (WebFetch error, timeout, unparseable)

Record the outcome for the source-status line in step 6.

**Per-post extraction** (required fields, omit only if truly absent):
- `channel`, `post_id`, `url` (`https://t.me/{channel}/{post_id}`), `datetime_utc`
- `text` (full body; strip HTML)
- `forwarded_from` (critical — many crypto/news channels are mostly forwards; without this you lose context)
- `views` (integer), `reactions` (sum of all emoji reaction counts), `reply_count` if visible
- `links` (external URLs in the post; exclude t.me self-links)
- `has_media` (photo/video/doc)

### 3. Filter out noise

Drop posts meeting any of:
- Text <40 characters AND no external link AND no media
- Pure emoji / sticker / single reaction
- Obvious ad / promo / referral ("use my code", "join my VIP", "airdrop claim here")
- Bot-generated price tickers with no analysis (e.g. "BTC: $X ↑Y%" alone)
- Older than 48h
- Already surfaced in the last 2 days of `memory/logs/` (match on post URL)

### 4. Score remaining posts

For each surviving post, compute **signal_score**:

```
signal_score =
    log(views + 1) * 1.0
  + reactions      * 2.0    // heuristic — adjust if top-post selection looks off
  + reply_count    * 1.5    // heuristic — adjust if top-post selection looks off
  + has_link       * 3      // heuristic — +3 flat if external link; adjust if top-post selection looks off
  + has_media      * 1      // +1 flat if media
  + recency_bonus            // +3 if <6h, +1 if <24h, 0 otherwise
  - forward_penalty          // heuristic — -2 if forwarded_from set AND post text <80 chars (pure rebroadcast); adjust if top-post selection looks off
```

The weights above (2× reactions, 1.5× replies, +3 link, -2 forward penalty) are empirical defaults tuned against typi

…