OA0 = Omni AI 0
OA0 是一个探索 AI 的论坛
现在注册
已注册用户请  登录
OA0  ›  技能包  ›  telegram-compose:使用 HTML 编写内容丰富、排版精美的 Telegram 消息

telegram-compose:使用 HTML 编写内容丰富、排版精美的 Telegram 消息

 
  malware ·  2026-02-05 18:51:43 · 3 次点击  · 0 条评论  

名称: telegram-compose
描述: |
通过 Telegram 官方 API,使用 HTML 格式发送结构清晰、视觉层次丰富的 Telegram 消息。
此技能由主会话代理自动调用,用于处理实质性的 Telegram 输出——其他技能无需调用。
决策规则:如果你的 Telegram 回复超过 3 行或包含结构化数据(列表、统计数据、章节、报告),则生成此技能作为 Haiku 子代理进行格式化和发送。简短回复(少于 3 行)直接通过 OpenClaw 的 message 工具发送。
处理范围:研究摘要、警报、状态更新、报告、简报、通知——任何需要视觉层次的内容。
元数据: |
{"openclaw":{
"os": ["darwin", "linux"],
"requires": {
"binaries": ["jq", "curl"],
"config": ["channels.telegram.accounts..botToken"]
},
"credentials": "从 OpenClaw 配置文件(~/.openclaw/openclaw.json 或 ~/.openclaw/clawdbot.json)中读取 Telegram 机器人令牌。具体的账户名必须由调用者提供——此技能不会自动选择账户。",
"network": ["api.telegram.org"]
}}
model-preference: claude-haiku-4-5
subagent: true
允许工具: exec, Read


Telegram 消息编排

通过 Telegram 官方 API 和 HTML 格式,编排并发送结构清晰、易于浏览的富文本消息。

此技能的使用方式

此技能由主会话代理自动调用。 其他技能无需知晓其存在。

决策规则(供主会话代理使用)

在向 Telegram 发送消息前,请检查:

  • 简短回复(少于 3 行,无结构): 直接通过 OpenClaw 的 message 工具发送。完成。
  • 实质性内容(超过 3 行,或包含列表/统计数据/章节/报告): 将此技能生成为子代理。

生成子代理

主会话代理调用 sessions_spawn,参数如下:

sessions_spawn(
  model: "claude-haiku-4-5",
  task: "<任务内容——请见下方模板>"
)

任务模板:

读取位于 {baseDir}/SKILL.md 的 telegram-compose 技能以了解格式化规则,然后将此内容格式化并发送到 Telegram。

机器人账户:<account_name> (例如:"main" —— 必须与 channels.telegram.accounts 中的一个键名匹配)
聊天 ID:<chat_id>
主题 ID:<thread_id> (如果不是论坛/话题聊天,则省略此行)

待格式化的内容:
---
<原始内容在此>
---

发送后,成功则回复消息 ID,失败则回复错误信息。请勿在你的回复中包含格式化后的消息——它已经发送到 Telegram。

重要: 调用者必须指定使用哪个机器人账户。子代理不得自动选择或遍历账户。

关键: 子代理的公告会返回给主会话,而不是发送到 Telegram。因此,主会话在生成子代理后应回复 NO_REPLY 以避免重复发送消息。子代理的 curl 调用才是实际向 Telegram 发送消息的操作。

子代理接收到的信息

  1. 技能路径 —— 以便读取格式化规则
  2. 机器人账户名 —— 使用哪个 Telegram 机器人账户(必须指定,永不自动选择)
  3. 聊天 ID —— 发送目标
  4. 主题 ID —— 如果适用,指定话题主题
  5. 原始内容 —— 需要转换为富文本消息的未格式化文本/数据

凭证

机器人令牌: 存储在 OpenClaw 配置文件的 channels.telegram.accounts.<name>.botToken 路径下。

账户名始终由调用者提供。 切勿自动选择或遍历账户。

# 自动检测配置文件路径
CONFIG=$([ -f ~/.openclaw/openclaw.json ] && echo ~/.openclaw/openclaw.json || echo ~/.openclaw/clawdbot.json)

# ACCOUNT 由调用者提供(例如:"main")
# 提取令牌前,先验证账户是否存在
ACCOUNT="<provided_account_name>"
BOT_TOKEN=$(jq -r ".channels.telegram.accounts.$ACCOUNT.botToken" "$CONFIG")

if [ "$BOT_TOKEN" = "null" ] || [ -z "$BOT_TOKEN" ]; then
  echo "错误:配置中未找到账户 '$ACCOUNT' 或其缺少 botToken"
  exit 1
fi

发送消息

CONFIG=$([ -f ~/.openclaw/openclaw.json ] && echo ~/.openclaw/openclaw.json || echo ~/.openclaw/clawdbot.json)
# ACCOUNT 由调用者提供——永不自动选择
BOT_TOKEN=$(jq -r ".channels.telegram.accounts.$ACCOUNT.botToken" "$CONFIG")

# 无主题线程
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 }
    }')"

# 有主题线程
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 }
    }')"

格式化规则

HTML 标签

<b>粗体</b>  <i>斜体</i>  <u>下划线</u>  <s>删除线</s>
<code>等宽字体</code>  <pre>代码块</pre>
<tg-spoiler>点击前隐藏</tg-spoiler>
<blockquote>引用</blockquote>
<blockquote expandable>默认折叠</blockquote>
<a href="url">链接</a>
<a href="tg://user?id=123">通过 ID 提及用户</a>

转义

仅在文本内容中转义以下字符(不在 HTML 标签内):
- &&amp;首先执行此操作,避免双重转义)
- <&lt;
- >&gt;

常见问题:包含 & 的内容(例如 "R&D", "Q&A")如果不转义,会破坏 HTML 解析。

结构模式

表情 <b>大写标题</b>

<b>标签:</b> 值
<b>标签:</b> 值

<b>章节</b>

• 要点
• 另一个要点

<blockquote>关键引用或摘要</blockquote>

<blockquote expandable><b>详情</b>

隐藏内容在此...
长内容应放在可展开块中。</blockquote>

<a href="https://...">操作链接 →</a>

样式规则

  1. 伪标题: 表情 <b>大写标题</b>,后跟空行
  2. 表情符号: 每条消息使用 1-3 个作为视觉锚点,而非装饰
  3. 空白: 章节之间使用空行分隔
  4. 长内容: 使用 <blockquote expandable>
  5. 链接: 单独一行,带箭头:链接文本 →

示例

状态更新:

📋 <b>任务完成</b>

<b>任务:</b> 部署 v2.3
<b>状态:</b> ✅ 完成
<b>耗时:</b> 12 分钟

<blockquote>所有健康检查均已通过。</blockquote>

警报:

⚠️ <b>需注意</b>

<b>问题:</b> API 频率限制已达 90%
<b>操作:</b> 检查使用情况

<a href="https://dashboard.example.com">查看仪表板 →</a>

列表:

✅ <b>优先级事项</b>

• <s>审核 PR #234</s> —— 已完成
• <b>完成文档</b> —— 进行中
• 部署到预发布环境

<i>3 项中已完成 2 项</i>

移动端友好的数据显示

切勿使用 <pre> 显示统计数据、摘要或视觉布局。 <pre> 使用等宽字体,在移动设备上换行效果差,会破坏对齐和树状字符。请将 <pre> 仅用于实际的代码/命令。

对于结构化数据,使用表情符号 + 粗体 + 分隔符:

❌ 错误(在移动端会换行):
<pre>
├─ 🟠 Reddit  32 个主题 │ 1,658 分
└─ 🌐 Web     8 个页面
</pre>

✅ 正确(自然流动):
🟠 <b>Reddit:</b> 32 个主题 · 1,658 分 · 625 条评论
🔵 <b>X:</b> 22 篇帖子 · 10,695 个赞 · 1,137 次转发
🌐 <b>Web:</b> 8 个页面(补充)
🗣️ <b>热门声音:</b> @handle1 · @handle2 · r/subreddit

其他模式:

记录卡片:

<b>Ruby</b>
生日:6月16日 · 年龄:11岁

<b>Rhodes</b>
生日:10月1日 · 年龄:8岁

要点列表:

• <b>hzl-cli:</b> 1.12.0
• <b>skill:</b> 1.0.6

限制与分割

  • 消息最大长度: 4,096 个字符
  • 标题最大长度: 1,024 个字符

如果格式化后的消息超过 4,096 个字符:
1. 在章节边界处分割(<b>标题</b> 块之间的空行)
2. 每个分块必须是有效的 HTML(不要在标签内分割)
3. 按顺序发送分块,分块之间延迟 1 秒
4. 第一个分块包含完整标题;后续分块添加续接指示符:<i>(续)</i>


错误处理

如果 Telegram API 返回错误:

错误 操作
Bad Request: can't parse entities HTML 格式错误。移除所有 HTML 标签,以纯文本形式重新发送。
Bad Request: message is too long 根据上述规则分割并重试。
Bad Request: message thread not found 不带 message_thread_id 重试(发送到“常规”话题)。
Too Many Requests: retry after X 等待 X 秒,然后重试一次。
任何其他错误 报告错误;不要重试。

后备规则: 如果 HTML 格式化失败两次,则发送纯文本,而不是完全不发送。消息送达比格式更重要。


子代理执行清单

作为子代理运行时,请遵循以下步骤:

  1. 解析任务 —— 提取机器人账户名、聊天 ID、主题 ID(如有)、技能路径和原始内容
  2. 读取此 SKILL.md —— 加载格式化规则
  3. 格式化内容 —— 应用 HTML 标签、结构模式、样式规则、移动端友好的数据显示
  4. 转义特殊字符 —— 仅在文本内容中转义 & 然后 < 然后 >(不在 HTML 标签内)
  5. 检查长度 —— 如果超过 4,096 个字符,在章节边界处分割
  6. 获取机器人令牌 —— 自动检测配置文件路径,提取指定账户的令牌(如果未找到则报错)
  7. 通过 curl 发送 —— 使用适当的模板(带/不带主题 ID)
  8. 检查响应 —— 解析 curl 输出,检查 "ok": true
  9. 处理错误 —— 遵循上方的错误处理表
  10. 报告结果 —— 成功则回复消息 ID,失败则回复错误详情
3 次点击  ∙  0 人收藏  
登录后收藏  
0 条回复
About   ·   Help   ·    
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
Developed with Cursor