Telegram Compose
Format and deliver rich Telegram messages with HTML formatting via direct Telegram API. Auto-invoked by the main session for substantive Telegram output — no other skills need to call it. Decision rul
Format and deliver rich Telegram messages with HTML formatting via direct Telegram API. Auto-invoked by the main session for substantive Telegram output — no other skills need to call it. Decision rul
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Format and deliver rich, scannable Telegram messages via direct API with HTML formatting.
This skill is auto-invoked by the main session agent. No other skills need to know about it.
Before sending a message to Telegram, check:
message tool. Done.The main session agent calls
sessions_spawn with:
sessions_spawn( model: "claude-haiku-4-5", task: "<task content — see template below>" )
Task template:
Read the telegram-compose skill at {baseDir}/SKILL.md for formatting rules, then format and send this content to Telegram.Bot account: <account_name> (e.g., "main" — must match a key in channels.telegram.accounts) Chat ID: <chat_id> Thread ID: <thread_id> (omit this line if not a forum/topic chat)
Content to format:
<raw content here>
After sending, reply with the message_id on success or the error on failure. Do NOT include the formatted message in your reply — it's already been sent to Telegram.
IMPORTANT: The caller MUST specify which bot account to use. The sub-agent must NOT auto-select or iterate accounts.
CRITICAL: The sub-agent announcement routes back to the main session, NOT to Telegram. So the main session should reply
NO_REPLY after spawning to avoid double-messaging. The sub-agent's curl call is what delivers to Telegram.
Bot token: Stored in the OpenClaw config file under
channels.telegram.accounts.<name>.botToken.
The account name is always provided by the caller. Never auto-select or iterate accounts.
# Auto-detect config path CONFIG=$([ -f ~/.openclaw/openclaw.json ] && echo ~/.openclaw/openclaw.json || echo ~/.openclaw/clawdbot.json)ACCOUNT is provided by the caller (e.g., "main")
Validate the account exists before extracting the token
ACCOUNT="<provided_account_name>" BOT_TOKEN=$(jq -r ".channels.telegram.accounts.$ACCOUNT.botToken" "$CONFIG")
if [ "$BOT_TOKEN" = "null" ] || [ -z "$BOT_TOKEN" ]; then echo "ERROR: Account '$ACCOUNT' not found in config or has no botToken" exit 1 fi
CONFIG=$([ -f ~/.openclaw/openclaw.json ] && echo ~/.openclaw/openclaw.json || echo ~/.openclaw/clawdbot.json) # ACCOUNT provided by caller — never auto-select BOT_TOKEN=$(jq -r ".channels.telegram.accounts.$ACCOUNT.botToken" "$CONFIG")Without topic thread
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage"
-H "Content-Type: application/json"
-d "$(jq -n
--arg chat "$CHAT_ID"
--arg text "$MESSAGE"
'{ chat_id: $chat, text: $text, parse_mode: "HTML", link_preview_options: { is_disabled: true } }')"With topic thread
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage"
-H "Content-Type: application/json"
-d "$(jq -n
--arg chat "$CHAT_ID"
--arg text "$MESSAGE"
--argjson thread $THREAD_ID
'{ chat_id: $chat, text: $text, parse_mode: "HTML", message_thread_id: $thread, link_preview_options: { is_disabled: true } }')"
<b>bold</b> <i>italic</i> <u>underline</u> <s>strike</s> <code>mono</code> <pre>code block</pre> <tg-spoiler>hidden until tapped</tg-spoiler> <blockquote>quote</blockquote> <blockquote expandable>collapsed by default</blockquote> <a href="url">link</a> <a href="tg://user?id=123">mention by ID</a>
Escape these characters in text content only (not in your HTML tags):
& → & (do this FIRST to avoid double-escaping)< → <> → >Common gotcha: content containing
& (e.g., "R&D", "Q&A") will break HTML parsing if not escaped.
EMOJI <b>HEADING IN CAPS</b><b>Label:</b> Value <b>Label:</b> Value
<b>SECTION</b>
• Bullet point • Another point
<blockquote>Key quote or summary</blockquote>
<blockquote expandable><b>Details</b>
Hidden content here... Long details go in expandable blocks.</blockquote>
<a href="https://...">Action Link →</a>
EMOJI <b>CAPS TITLE</b> with blank line after<blockquote expandable>Link Text →Status update:
📋 <b>TASK COMPLETE</b><b>Task:</b> Deploy v2.3 <b>Status:</b> ✅ Done <b>Duration:</b> 12 min
<blockquote>All health checks passing.</blockquote>
Alert:
⚠️ <b>ATTENTION NEEDED</b><b>Issue:</b> API rate limit at 90% <b>Action:</b> Review usage
<a href="https://dashboard.example.com">View Dashboard →</a>
List:
✅ <b>PRIORITIES</b>• <s>Review PR #234</s> — done • <b>Finish docs</b> — in progress • Deploy staging
<i>2 of 3 complete</i>
Never use
for stats, summaries, or visual layouts. <pre>
<pre> uses monospace font and wraps badly on mobile, breaking alignment and tree characters. Reserve <pre> for actual code/commands only.
For structured data, use emoji + bold + separators:
❌ BAD (wraps on mobile): <pre> ├─ 🟠 Reddit 32 threads │ 1,658 pts └─ 🌐 Web 8 pages </pre>✅ GOOD (flows naturally): 🟠 <b>Reddit:</b> 32 threads · 1,658 pts · 625 comments 🔵 <b>X:</b> 22 posts · 10,695 likes · 1,137 reposts 🌐 <b>Web:</b> 8 pages (supplementary) 🗣️ <b>Top voices:</b> @handle1 · @handle2 · r/subreddit
Other patterns:
Record cards:
<b>Ruby</b> Birthday: Jun 16 · Age: 11<b>Rhodes</b> Birthday: Oct 1 · Age: 8
Bullet lists:
• <b>hzl-cli:</b> 1.12.0 • <b>skill:</b> 1.0.6
If formatted message exceeds 4,096 chars:
<b>HEADING</b> blocks)<i>(continued)</i>If Telegram API returns an error:
| Error | Action |
|---|---|
| HTML is malformed. Strip all HTML tags and resend as plain text. |
| Split per the rules above and retry. |
| Retry without (sends to General). |
| Wait X seconds, then retry once. |
| Any other error | Report the error back; don't retry. |
Fallback rule: If HTML formatting fails twice, send as plain text rather than not sending at all. Delivery matters more than formatting.
When running as a sub-agent, follow this sequence:
& then < then > in text content only (not in your HTML tags)"ok": trueNo automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.