Jump to related tools in the same category or review the original source on GitHub.

DevOps & Cloud @axisrow Updated 6/28/2026 499 downloads 0 stars Security: Pass

📡 Tg Channel Manager OpenClaw Plugin & Skill | ClawHub

Looking to integrate Tg Channel Manager into your AI workflows? This free OpenClaw plugin from ClawHub helps you automate devops & cloud tasks instantly, without having to write custom tools from scratch.

What this skill does

Universal config-driven content pipeline engine for any Telegram channel: news search via SearXNG, drafts, scheduled publishing, deduplication. All channel specifics are defined in config — one skill for any channel.

Install

ClawHub CLI
openclaw skills install @axisrow/tg-channel-manager
Node.js (npx)
npx clawhub@latest install tg-channel-manager

Full SKILL.md

Open original
Metadata table.
namedescription
tg-channel-managerUniversal config-driven content pipeline engine for any Telegram channel: news search via SearXNG, drafts, scheduled publishing, deduplication. All channel specifics are defined in config — one skill for any channel.

SKILL.md content below is scrollable.

TG Channel Manager

Pipeline: scout → draft → human approves → publisher.

Execution

python3 and curl are available in your environment (declared in requires.bins). Run all commands yourself using exec/bash tool. NEVER ask the user to run commands for you.

Startup

When you load this skill, run the preflight check FIRST:

python3 {baseDir}/scripts/tgcm.py --workspace {workspace} check

After check — act on results, don't ask:

  • All [ok] → proceed with the user's task silently
  • [fail] Bot token → ask the user for the token, then save it: tgcm.py config set bot-token <token>. Do NOT ask where the token is or offer choices
  • [warn] SEARXNG_URL → ask the user for the URL, then save it: tgcm.py config set searxng-url <url>. Proceed without it — scout won't work but other commands will
  • [fail] Channel → report which channel failed and why, include the fix from the output
  • [warn] No channels → mention it, but proceed — the user may want to init one

Settings saved via config set persist in tgcm/.config.json and are used by all subsequent commands.

NEVER ask follow-up questions about check results. Report what's wrong and the fix from the output. If the user hasn't specified a task — just report the check status, nothing else.

CLI Reference (FULL list — NO other commands exist)

All commands: python3 {baseDir}/scripts/tgcm.py --workspace {workspace} <cmd>

Command What it does
init <name> Create a channel
list Show all channels
bind <name> --channel-id ID Bind channel to Telegram
info <name> [--chat] [--subscribers] [--permissions] [--admins] [--all] Channel status
get-id <@username|ID> Resolve @username or numeric ID → full channel info (id, type, title)
check Preflight: verify bot token, channels, env vars
config set <key> <value> Save setting locally (keys: bot-token, searxng-url)
config get <key> Read a saved setting
config list Show all saved settings
fetch-posts <name> [--limit N] [--dry-run] Load channel posts into dedup index (requires public channel with @username)
connect --channel-id ID [--channel-title T] Handle #tgcm connect event

Bot token is auto-resolved: --bot-token arg → $BOT_TOKEN env → openclaw.json (auto-search) → tgcm/.config.json. Just call tgcm.py get-id @username without --bot-token — the script finds the token itself. If auto-detection fails, save it once: tgcm.py config set bot-token <token>.

Channel name validation: ^[a-z0-9][a-z0-9_-]{0,62}$.

Quick Reference

User says Do this
«узнай/определи channel-id» tgcm.py get-id @username
«подключи канал» Recipe: Connect a channel (ниже)
«какие каналы / список» tgcm.py list
«статус канала X» tgcm.py info X
«что в очереди» cat tgcm/<name>/content-queue.md
«загрузи посты / rebuild index» tgcm.py fetch-posts <name>

Recipes

Look up channel ID

python3 {baseDir}/scripts/tgcm.py get-id @username

Token is found automatically. Returns channel id, type, and title.

Connect a channel

  1. Get ID: python3 {baseDir}/scripts/tgcm.py get-id @username
  2. python3 {baseDir}/scripts/tgcm.py --workspace {workspace} init <name>
  3. python3 {baseDir}/scripts/tgcm.py --workspace {workspace} bind <name> --channel-id <id>
  4. Configure skills.entries["tg-channel-manager"].config in openclaw.json
  5. Add crons (see {baseDir}/references/cron-setup.md)

Load channel posts (rebuild dedup index)

python3 {baseDir}/scripts/tgcm.py --workspace {workspace} fetch-posts <name>

Fetches posts from the channel's public page (t.me/s/) and adds them to content-index.json. Options: --limit N (max pages, default 5), --dry-run (preview only). Requires: channel must be public (have a @username).

View channels / status

  • tgcm.py list
  • tgcm.py info <name>
  • Queue: cat tgcm/<name>/content-queue.md

Do NOT

  • Invent commands — the table above is the FULL list
  • Publish posts directly — only cron Publisher does this
  • Change draft → pending — only the human does this
  • Skip dedup-check before drafting
  • Ask the user to run commands — python3 and curl are available, use exec/bash yourself
  • Ask the user for bot token or env vars — token is auto-resolved, check shows what's wrong
  • Ask the user follow-up questions after check — report errors and the fix commands, don't offer choices
  • Ask whether it's a channel or group — get-id returns the type field, this skill is for channels only

Data Layout

tgcm/
  channels.json            <- [{"name", "channelId", "status", "createdAt"}, ...]
  {channel-name}/
    channel.json           <- per-channel metadata
    content-index.json     <- dedup index
    content-queue.md       <- post queue

A channel is bound when channelId is set and status is "connected".

Configuration

Parameters are read from openclaw.jsonskills.entries["tg-channel-manager"]:

Telegram

Parameter Type Description
config.channelId string Telegram channel ID for publishing
config.chatId string Channel community chat ID (optional)

Limits & Schedule

Parameter Type Description
config.maxPostsPerDay number Maximum posts per day
config.maxDraftsPerRun number Maximum drafts per scout run
config.timezone string Schedule timezone (IANA format)
config.language string Post language (ru, en, ...)
config.cronScoutTimes string[] Scout schedules (cron format)
config.cronPublisherTimes string[] Publisher schedules (cron format)

Content

Parameter Type Description
config.rubrics array Rubrics: [{id, emoji, name}, ...]
config.searchQueries string[] Search queries for SearXNG
config.searchInclude string What to look for (filter description)
config.searchExclude string What to discard (filter description)
config.evergreen string[] Topics for articles when there are no news

Post Style

Parameter Type Description
config.postStyle.minChars number Minimum characters per post
config.postStyle.maxChars number Maximum characters per post
config.postStyle.emojiTitle boolean Emoji before the title
config.postStyle.boldTitle boolean Bold title
config.postStyle.signature string Post signature
config.postStyle.newsFooter string Extra text for news posts (empty = none)
config.postStyle.articleFooter string Extra text for articles (empty = none)

Environment

Parameter Type Description
env.SEARXNG_URL string SearXNG instance URL

Path Resolution

Variable How to resolve
{workspace} Your CWD. Run pwd or use --workspace .
{baseDir} {workspace}/skills/tg-channel-manager

In sandbox mode (workspaceAccess: "none"), the workspace is under ~/.openclaw/sandboxes, not ~/.openclaw/workspace. Always use CWD-relative paths.

Cron setup: see {baseDir}/references/cron-setup.md.

Queue Format

Entry Format in content-queue.md

### <number>
- **Status:** draft | pending
- **Rubric:** <emoji> <name> (from config.rubrics)
- **Topic:** <topic>
- **Source:** <url> (for news)
- **Text:**

<post text>

Statuses:

  • draft — awaiting approval
  • pending — approved, ready for publishing

After publishing, the entry is removed from content-queue.md.

Deduplication

Before every draft — mandatory check:

python3 {baseDir}/scripts/dedup-check.py --base-dir <workspace> --topic "topic" --links "url1" "url2"

After publishing — add to index:

python3 {baseDir}/scripts/dedup-check.py --base-dir <workspace> --add <msgId> --topic "topic" --links "url"

Rebuild index (via Telegram search):

python3 {baseDir}/scripts/dedup-check.py --base-dir <workspace> --rebuild --channel-id <config.channelId>

Index is stored in <workspace>/content-index.json (or per-channel: tgcm/<name>/content-index.json).

ClawHub Registry URL: https://clawhub.ai/axisrow/skills/tg-channel-manager

Related skills

If this matches your use case, these are close alternatives in the same category.