sergei-mikhailov-tg-channel-reader

GitHub 作者 LeoYeAI/openclaw-master-skills

Read posts and comments from Telegram channels via MTProto (Pyrogram or Telethon). Fetch recent messages and discussion replies from public or private channels by time window.

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install github:LeoYeAI~openclaw-master-skills~sergei-mikhailov-tg-channel-reader
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/github%3ALeoYeAI~openclaw-master-skills~sergei-mikhailov-tg-channel-reader/file -o sergei-mikhailov-tg-channel-reader.md
# tg-channel-reader

Read posts and comments from Telegram channels using MTProto (Pyrogram or Telethon).
Works with any public channel and private channels the user is subscribed to.
Supports fetching discussion replies (comments) for individual posts.

> **Security notice:** This skill requires `TG_API_ID` and `TG_API_HASH` from [my.telegram.org](https://my.telegram.org). The session file grants full Telegram account access — store it securely and never share it.

---

## Exec Approvals

> **Just installed via `clawhub install`?** Complete Setup & Installation (below) first — the skill needs `pip install`, credentials, and a session file before exec approvals matter.

OpenClaw blocks unknown CLI commands by default. The user must approve `tg-reader` commands before they can run. If the command hangs or the user says nothing is happening — exec approval is likely pending.

### Quick setup (recommended)

Run from the skill directory — checks prerequisites, installs pip packages if needed, and prints the approval commands to run:

```bash
cd ~/.openclaw/workspace/skills/sergei-mikhailov-tg-channel-reader
bash setup-tg-reader.sh
```

### Manual CLI approval

```bash
openclaw approvals allowlist add --gateway "$(which tg-reader)"
openclaw approvals allowlist add --gateway "$(which tg-reader-check)"
openclaw approvals allowlist add --gateway "$(which tg-reader-telethon)"
```

### Alternative: approve on first use

1. **Control UI** — open `http://localhost:18789/`, find the pending approval for `tg-reader`, click **"Always allow"**. [Docs](https://docs.openclaw.ai/web/control-ui)
2. **Messenger** (Telegram, Slack, Discord) — the bot sends an approval request with an `<id>`. Reply: `/approve <id> allow-always`. Other options: `allow-once`, `deny`.

The approval prompt appears in the **Control UI or as a bot message** — not in the agent's conversation. This is a common source of confusion.

---

## When to Use

- User asks to "check", "read", or "monitor" a Telegram channel
- Wants a digest or summary of recent posts
- Asks "what's new in @channel" or "summarize last 24h from @channel"
- Wants to track or compare multiple channels
- Wants channel info (title, description, subscribers) — use `tg-reader info`

---

## Quick Start

```bash
# 1. Run pre-flight diagnostic (fast, no Telegram connection)
tg-reader-check

# 2. Get channel info
tg-reader info @channel_name

# 3. Fetch recent posts
tg-reader fetch @channel_name --since 24h
```

> **`tg-reader: command not found`?** Run `bash setup-tg-reader.sh` from the skill directory (it will install the package), or manually: `cd ~/.openclaw/workspace/skills/sergei-mikhailov-tg-channel-reader && pip install .`

---

## Commands

### `tg-reader-check` — Pre-flight Diagnostic

**Always run before fetching.** Fast offline check — no Telegram connection needed.

```bash
tg-reader-check
tg-reader-check --config-file /path/to/config.json
tg-reader-check --session-file /path/to/session
```

Returns JSON with `"status": "ok"` or `"status": "error"` plus a `problems` array.

Verifies:
- Credentials available (env vars or `~/.tg-reader.json`)
- Session file exists on disk (with size, modification date)
- At least one MTProto backend installed (Pyrogram or Telethon)
- Detects stale sessions (config points to older file while a newer one exists)

### `tg-reader info` — Channel Info

```bash
tg-reader info @channel_name
```

Returns title, description, subscriber count, and link.

### `tg-reader fetch` — Read Posts

```bash
# Last 24 hours (default)
tg-reader fetch @channel_name --since 24h

# Last 7 days, up to 200 posts
tg-reader fetch @channel_name --since 7d --limit 200

# Multiple channels (fetched sequentially with 10s delay between each)
tg-reader fetch @channel1 @channel2 @channel3 --since 24h

# Custom delay between channels (seconds)
tg-reader fetch @channel1 @channel2 @channel3 --since 24h --delay 5

# Fetch posts with comments (single channel only, limit auto-drops to 30)
tg-reader fetch @channel_name --since 7d --comments

# More comments per post, custom delay between posts
tg-reader fetch @channel_name --since 24h --comments --comment-limit 20 --comment-delay 5

# Skip posts without text (media-only, no caption)
tg-reader fetch @channel_name --since 24h --text-only

# Human-readable output
tg-reader fetch @channel_name --since 24h --format text

# Write output to file instead of stdout (saves tokens)
tg-reader fetch @channel_name --since 24h --output
tg-reader fetch @channel_name --since 24h --comments --output comments.json

# Use Telethon instead of Pyrogram (one-time)
tg-reader fetch @channel_name --since 24h --telethon

# Read unread mode — only fetch new (unread) posts, no --since needed
# Requires "read_unread": true in ~/.tg-reader.json
tg-reader fetch @channel_name

# Override read_unread mode (fetch everything, don't update state)
tg-reader fetch @channel_name --since 7d --all

# Custom state file location
tg-reader fetch @channel_name --since 24h --state-file /path/to/state.json
```

### `tg-reader auth` — First-time Authentication

```bash
tg-reader auth
```

Creates a session file. Only needed once.

---

## Read Unread Mode

Only return new (unread) posts — the skill remembers what you've already seen. Useful for daily digests and monitoring workflows.

### Setup

**Option A — config file** (`~/.tg-reader.json`):

```json
{
  "api_id": 12345,
  "api_hash": "...",
  "read_unread": true
}
```

**Option B — env var** (works with `~/.openclaw/openclaw.json`):

```bash
export TG_READ_UNREAD=true
```

Env vars take priority over the config file. This lets you enable read_unread via `openclaw.json` Docker `env` alongside `TG_API_ID`/`TG_API_HASH`.

State is stored in `~/.tg-reader-state.json` (configurable via `"state_file"` in config, `TG_STATE_FILE` env var, or `--state-file` flag).

### Behavior

- **`--since` is not needed** when `read_unread` is enabled — the skill automatically returns all unread posts regardless of time
- **First run** (no prior state for channel): `--since` applies as usual (default 24h); state file created
- **Subsequent runs:** only posts newer than the last read are returned; `--since` is ignored
- **`--all` flag:** bypasses read_unread mode — fetches everything by `--since` without updating state (preserves your position)
- **New channel:** behaves like a first run (no prior state)
- **No new posts:** state unchanged, `count: 0` returned

### Examples

```bash
# With read_unread enabled — just fetch, no --since needed
tg-reader fetch @channel_name

# First run for a new channel — --since determines initial window
tg-reader fetch @new_channel --since 7d

# Override: fetch everything, don't update tracking state
tg-reader fetch @channel_name --since 7d --all
```

### Output

When read_unread mode is active, the JSON output includes a `read_unread` field:

```json
{
  "channel": "@channel_name",
  "read_unread": {"enabled": true},
  "count": 5,
  "messages": [...]
}
```

With `--all`: `"read_unread": {"enabled": true, "overridden": true}`

### Limitations

- Tracking is **post-level only** — new comments on already-read posts are not caught
- If a channel changes its username, tracking resets (state is keyed by username)
- Concurrent runs for the same channel are safe but last writer wins

### Diagnostic

`tg-reader-check` reports tracking status:

```json
{
  "tracking": {
    "read_unread": true,
    "state_file": "~/.tg-reader-state.json",
    "state_file_exists": true,
    "tracked_channels": 3
  }
}
```

---

## Output Format

### `info`

```json
{
  "id": -1001234567890,
  "title": "Channel Name",
  "username": "channel_name",
  "description": "About this channel...",
  "members_count": 42000,
  "link": "https://t.me/channel_name"
}
```

### `fetch`

```json
{
  "channel": "@channel_name",
  "fetched_at": "2026-02-22T10:00:00Z",
  "since": "2026-02-21T10:00:00Z",
  "count": 12,
  "messages": [
    {
      "id": 1234,
      "date": "2026-02-22T09:30:00Z",
      "text": "Po