Create interactive Telegram messages with inline buttons using OpenClaw CLI. Use when you need user interaction in Telegram (selection from a list, confirmat...
📖 First time setup? See SETUP.md for detailed configuration instructions.
openclaw - OpenClaw CLI (install: npm install -g openclaw)bash - Shell for helper scriptspython3 - For JSON validation script (recommended)Telegram Bot Setup Required:
Create a Telegram bot via @BotFather
/newbot to BotFatherConfigure OpenClaw with your bot token:
Edit ~/.openclaw/config.json (or your workspace openclaw.json):
{
"channels": {
"telegram": {
"enabled": true,
"botToken": "YOUR_BOT_TOKEN_HERE"
}
}
}
Get your chat ID:
openclaw message send --target "telegram:YOUR_CHAT_ID" --message "Test"Target Format: All examples use telegram:CHAT_ID format. Replace CHAT_ID with your actual Telegram chat ID (numeric).
Scripts in this skill:
bashopenclaw CLI with user-provided argumentsvalidate_buttons.py parses JSON (no external connections)Before running:
Credential Scope:
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.
Basic button message:
openclaw message send \
--target "telegram:CHAT_ID" \
--message "Choose an option:" \
--buttons '[[{"text": "Option 1", "callback_data": "opt1"}, {"text": "Option 2", "callback_data": "opt2"}]]'
Key points:
--buttons argumenttext and callback_dataThe --buttons parameter accepts a JSON array of arrays (rows):
[
[{"text": "B1", "callback_data": "c1"}, {"text": "B2", "callback_data": "c2"}],
[{"text": "B3", "callback_data": "c3"}]
]
Layout Limits:
Each button object supports:
text (required): Display textcallback_data (required): Unique identifier for the callbackstyle (optional): primary, success, or dangerExample with styles:
openclaw message send \
--target "telegram:CHAT_ID" \
--message "Confirm action?" \
--buttons '[[{"text": "✅ Confirm", "callback_data": "confirm", "style": "success"}, {"text": "❌ Cancel", "callback_data": "cancel", "style": "danger"}]]'
Use the provided helper for cleaner code:
bash scripts/send_buttons.sh "telegram:CHAT_ID" "Choose:" '[[{"text": "Yes", "callback_data": "yes"}, {"text": "No", "callback_data": "no"}]]'
When a user clicks a button, Telegram sends a callback with the callback_data value. Handle it in two steps:
Example flow:
# User clicked button with callback_data="yes"
# Step 1: Send confirmation
openclaw message send \
--target "telegram:CHAT_ID" \
--message "✅ You selected: Yes"
# Step 2: Edit original message (remove buttons)
openclaw message edit \
--target "telegram:CHAT_ID" \
--message-id "MESSAGE_ID" \
--message "Choose: [Selection complete]"
Remove buttons after selection:
openclaw message edit \
--target "telegram:CHAT_ID" \
--message-id "939" \
--message "Updated message text without buttons"
Or use the helper:
bash scripts/edit_message.sh "telegram:CHAT_ID" "939" "Selection complete"
openclaw message send \
--target "telegram:CHAT_ID" \
--message "Delete this file?" \
--buttons '[[{"text": "Yes", "callback_data": "delete_yes"}, {"text": "No", "callback_data": "delete_no"}]]'
openclaw message send \
--target "telegram:CHAT_ID" \
--message "What would you like to do?" \
--buttons '[[{"text": "🎬 Search", "callback_data": "wf_search"}, {"text": "📊 Metrics", "callback_data": "wf_metrics"}], [{"text": "📅 Calendar", "callback_data": "wf_calendar"}, {"text": "⚙️ Settings", "callback_data": "wf_settings"}]]'
openclaw message send \
--target "telegram:CHAT_ID" \
--message "How many results?" \
--buttons '[[{"text": "5", "callback_data": "count_5"}, {"text": "10", "callback_data": "count_10"}, {"text": "20", "callback_data": "count_20"}]]'
wf_search not btn1scripts/validate_buttons.py before sending"buttons[0][0] requires text and callback_data"
\"text\" instead of "text")Buttons not appearing
python3 scripts/validate_buttons.py 'YOUR_JSON'Multiple buttons per user click
send_buttons.sh - Helper for sending button messagesedit_message.sh - Helper for editing messagesvalidate_buttons.py - JSON validation before sendingREFERENCE.md - Complete parameter reference and advanced examplesbasic_yes_no.sh - Simple confirmation dialogworkflows_menu.sh - Multi-option workflow menufull_flow_example.sh - Complete callback handling flowZIP package — ready to use