Telegram Interactive Buttons
Requirements
📖 First time setup? See SETUP.md for detailed configuration instructions.
Required Binaries
- -
openclaw - OpenClaw CLI (install: npm install -g openclaw) - INLINECODE2 - Shell for helper scripts
Optional Binaries
- -
python3 - For JSON validation script (recommended)
Credentials & Configuration
Telegram Bot Setup Required:
- 1. Create a Telegram bot via @BotFather
- Send
/newbot to BotFather
- Follow prompts to get your bot token
- 2. Configure OpenClaw with your bot token:
Edit ~/.openclaw/config.json (or your workspace openclaw.json):
CODEBLOCK0
- 3. Get your chat ID:
- Start a chat with your bot
- Send any message
- Run:
openclaw message send --target "telegram:YOUR_CHAT_ID" --message "Test"
- Check OpenClaw logs or use Telegram bot API to retrieve your chat ID
Target Format: All examples use telegram:CHAT_ID format. Replace CHAT_ID with your actual Telegram chat ID (numeric).
Security Notes
Scripts in this skill:
- - Execute local shell commands via INLINECODE10
- Call
openclaw CLI with user-provided arguments - INLINECODE12 parses JSON (no external connections)
Before running:
- 1. Review all scripts - they are short and readable
- Replace placeholder chat IDs in examples
- Run only in trusted environments
- Never pass untrusted inputs to scripts without validation
- Store bot token securely (use environment variables or secure config files)
Credential Scope:
- - Bot token allows sending messages to chats where bot is added
- Scripts do not modify bot permissions or settings
- No sensitive data is transmitted beyond standard Telegram API calls
Overview
This skill provides reliable methods for creating interactive Telegram messages with inline buttons using the OpenClaw CLI. After extensive testing across different models (Gemini, Claude), the CLI approach via exec tool has proven to be the most stable method for sending buttons.
Why this skill exists: The message tool's buttons parameter can be fragile across different models. The CLI provides consistent, predictable button rendering.
Quick Start
Basic button message:
CODEBLOCK1
Key points:
- - Use single quotes around the entire
--buttons argument - Buttons is a JSON array of arrays (rows)
- Each button needs
text and INLINECODE18 - Keep 1-2 buttons per row for mobile UX
Sending Buttons
Button Structure
The --buttons parameter accepts a JSON array of arrays (rows):
CODEBLOCK2
Layout Limits:
- - Max buttons per row: 8 (use this for grids/keypads)
- Max buttons total: 100
- Mobile UX Recommendation: While 8 are supported, keep 1-3 buttons per row for standard menus to ensure readability on mobile. Use the full 8-button width only for grids (e.g., calculators, calendars, or numeric selectors).
Button Properties
Each button object supports:
- -
text (required): Display text - INLINECODE21 (required): Unique identifier for the callback
- INLINECODE22 (optional):
primary, success, or INLINECODE25
Example with styles:
CODEBLOCK3
Helper Script
Use the provided helper for cleaner code:
CODEBLOCK4
Handling Callbacks
When a user clicks a button, Telegram sends a callback with the callback_data value. Handle it in two steps:
- 1. Send confirmation message - Acknowledge the selection
- Edit original message - Remove buttons to prevent accidental re-clicks
Example flow:
CODEBLOCK5
Editing Messages
Remove buttons after selection:
CODEBLOCK6
Or use the helper:
CODEBLOCK7
Common Patterns
Yes/No Confirmation
CODEBLOCK8
Workflow Menu
CODEBLOCK9
Number Selection
CODEBLOCK10
Best Practices
- 1. Keep it mobile-friendly - 1-2 buttons per row maximum
- Use descriptive callback_data -
wf_search not INLINECODE28 - Always edit after callback - Remove buttons to prevent confusion
- Add visual indicators - Emojis help distinguish button types (✅ 🎬 📊 ⚙️)
- Validate JSON - Use
scripts/validate_buttons.py before sending
Troubleshooting
Common Errors
"buttons[0][0] requires text and callback_data"
- - Cause: Escaped quotes in JSON (
\"text\" instead of "text") - Fix: Use clean JSON without escaping
Buttons not appearing
- - Cause: Invalid JSON structure
- Fix: Validate with INLINECODE32
Multiple buttons per user click
- - Cause: Not editing original message after callback
- Fix: Always edit and remove buttons after handling callback
Resources
scripts/
- -
send_buttons.sh - Helper for sending button messages - INLINECODE34 - Helper for editing messages
- INLINECODE35 - JSON validation before sending
references/
- -
REFERENCE.md - Complete parameter reference and advanced examples
assets/examples/
- -
basic_yes_no.sh - Simple confirmation dialog - INLINECODE38 - Multi-option workflow menu
- INLINECODE39 - Complete callback handling flow
Telegram 交互式按钮
前置要求
📖 首次设置? 请参阅 SETUP.md 获取详细配置说明。
必需二进制文件
- - openclaw - OpenClaw CLI(安装:npm install -g openclaw)
- bash - 用于辅助脚本的 Shell
可选二进制文件
- - python3 - 用于 JSON 验证脚本(推荐)
凭证与配置
需要设置 Telegram 机器人:
- 1. 通过 @BotFather 创建 Telegram 机器人
- 向 BotFather 发送 /newbot
- 按照提示获取机器人令牌
- 2. 使用机器人令牌配置 OpenClaw:
编辑 ~/.openclaw/config.json(或工作区的 openclaw.json):
json
{
channels: {
telegram: {
enabled: true,
botToken: YOURBOTTOKEN_HERE
}
}
}
- 3. 获取聊天 ID:
- 与机器人开始对话
- 发送任意消息
- 运行:openclaw message send --target telegram:YOUR
CHATID --message Test
- 查看 OpenClaw 日志或使用 Telegram 机器人 API 获取聊天 ID
目标格式: 所有示例均使用 telegram:CHATID 格式。将 CHATID 替换为实际的 Telegram 聊天 ID(数字格式)。
安全说明
此技能中的脚本:
- - 通过 bash 执行本地 shell 命令
- 使用用户提供的参数调用 openclaw CLI
- validate_buttons.py 解析 JSON(无外部连接)
运行前:
- 1. 审查所有脚本——它们简短且可读
- 替换示例中的占位聊天 ID
- 仅在受信任的环境中运行
- 未经验证切勿将不可信输入传递给脚本
- 安全存储机器人令牌(使用环境变量或安全配置文件)
凭证范围:
- - 机器人令牌允许向已添加机器人的聊天发送消息
- 脚本不会修改机器人权限或设置
- 除标准 Telegram API 调用外,不会传输敏感数据
概述
此技能提供了使用 OpenClaw CLI 创建带内联按钮的交互式 Telegram 消息的可靠方法。经过跨不同模型(Gemini、Claude)的广泛测试,通过 exec 工具的 CLI 方法已被证明是发送按钮最稳定的方式。
此技能存在的原因: message 工具的 buttons 参数在不同模型间可能不稳定。CLI 提供了一致且可预测的按钮渲染。
快速开始
基本按钮消息:
bash
openclaw message send \
--target telegram:CHAT_ID \
--message 选择一个选项: \
--buttons [[{text: 选项 1, callbackdata: opt1}, {text: 选项 2, callbackdata: opt2}]]
关键点:
- - 在 --buttons 参数周围使用单引号
- 按钮是一个数组的数组(行)的 JSON
- 每个按钮需要 text 和 callback_data
- 每行保持 1-2 个按钮以获得良好的移动端体验
发送按钮
按钮结构
--buttons 参数接受一个数组的数组(行)的 JSON:
json
[
[{text: B1, callbackdata: c1}, {text: B2, callbackdata: c2}],
[{text: B3, callback_data: c3}]
]
布局限制:
- - 每行最大按钮数: 8(用于网格/键盘)
- 按钮总数上限: 100
- 移动端体验建议: 虽然支持 8 个按钮,但标准菜单建议每行保持 1-3 个按钮以确保在移动设备上的可读性。仅在网格布局(如计算器、日历或数字选择器)中使用完整的 8 按钮宽度。
按钮属性
每个按钮对象支持:
- - text(必需):显示文本
- callback_data(必需):回调的唯一标识符
- style(可选):primary、success 或 danger
带样式的示例:
bash
openclaw message send \
--target telegram:CHAT_ID \
--message 确认操作? \
--buttons [[{text: ✅ 确认, callbackdata: confirm, style: success}, {text: ❌ 取消, callbackdata: cancel, style: danger}]]
辅助脚本
使用提供的辅助脚本使代码更简洁:
bash
bash scripts/sendbuttons.sh telegram:CHATID 选择: [[{text: 是, callbackdata: yes}, {text: 否, callbackdata: no}]]
处理回调
当用户点击按钮时,Telegram 会发送一个包含 callback_data 值的回调。分两步处理:
- 1. 发送确认消息 - 确认选择
- 编辑原始消息 - 移除按钮以防止意外重复点击
示例流程:
bash
用户点击了 callback_data=yes 的按钮
步骤 1:发送确认
openclaw message send \
--target telegram:CHAT_ID \
--message ✅ 您选择了:是
步骤 2:编辑原始消息(移除按钮)
openclaw message edit \
--target telegram:CHAT_ID \
--message-id MESSAGE_ID \
--message 选择:[选择完成]
编辑消息
选择后移除按钮:
bash
openclaw message edit \
--target telegram:CHAT_ID \
--message-id 939 \
--message 已更新的消息文本(无按钮)
或使用辅助脚本:
bash
bash scripts/editmessage.sh telegram:CHATID 939 选择完成
常见模式
是/否确认
bash
openclaw message send \
--target telegram:CHAT_ID \
--message 删除此文件? \
--buttons [[{text: 是, callbackdata: deleteyes}, {text: 否, callbackdata: deleteno}]]
工作流菜单
bash
openclaw message send \
--target telegram:CHAT_ID \
--message 您想做什么? \
--buttons [[{text: 🎬 搜索, callbackdata: wfsearch}, {text: 📊 指标, callbackdata: wfmetrics}], [{text: 📅 日历, callbackdata: wfcalendar}, {text: ⚙️ 设置, callbackdata: wfsettings}]]
数字选择
bash
openclaw message send \
--target telegram:CHAT_ID \
--message 多少个结果? \
--buttons [[{text: 5, callbackdata: count5}, {text: 10, callbackdata: count10}, {text: 20, callbackdata: count20}]]
最佳实践
- 1. 保持移动端友好 - 每行最多 1-2 个按钮
- 使用描述性 callbackdata - 使用 wfsearch 而非 btn1
- 回调后始终编辑 - 移除按钮以防止混淆
- 添加视觉指示 - 表情符号有助于区分按钮类型(✅ 🎬 📊 ⚙️)
- 验证 JSON - 发送前使用 scripts/validate_buttons.py
故障排除
常见错误
buttons[0][0] requires text and callback_data
- - 原因:JSON 中转义引号(使用 \text\ 而非 text)
- 修复:使用无转义的干净 JSON
按钮不显示
- - 原因:JSON 结构无效
- 修复:使用 python3 scripts/validatebuttons.py YOURJSON 验证
用户点击后出现多个按钮
- - 原因:回调后未编辑原始消息
- 修复:处理回调后始终编辑并移除按钮
资源
scripts/
- - sendbuttons.sh - 发送按钮消息的辅助脚本
- editmessage.sh - 编辑消息的辅助脚本
- validate_buttons.py - 发送前的 JSON 验证
references/
- - REFERENCE.md - 完整参数参考和高级示例
assets/examples/