#14549: feat(telegram): add support for URL-type inline buttons
channel: telegram
agents
stale
size: S
Cluster:
Telegram Inline Button Enhancements
## Summary
This PR adds support for Telegram URL-type inline buttons, enabling bots to include buttons that open links directly when tapped.
## Changes
- **Updated button types** to support both `callback_data` and `url`
- `src/telegram/model-buttons.ts`: Updated `ButtonRow` type
- `src/agents/tools/telegram-actions.ts`: Updated `TelegramButton` type
- `src/telegram/send.ts`: Updated `TelegramSendOpts` and `TelegramEditOpts`
- `src/channels/plugins/outbound/telegram.ts`: Updated channel data types
- **Enhanced validation** in `readTelegramButtons`
- Accepts buttons with either `callback_data` OR `url` (but not both)
- Clear error messages for invalid button configurations
- **Updated `buildInlineKeyboard`** to handle both button types
- Passes `callback_data` buttons through as before (backward compatible)
- Passes `url` buttons to Telegram's InlineKeyboardButton API
## Testing
The changes are backward compatible:
- Existing `callback_data` buttons work exactly as before
- New `url` buttons can now be used
Example usage:
```typescript
// URL button
buttons: [[{ text: "View PR", url: "https://github.com/openclaw/openclaw/pull/123" }]]
// Callback button (existing behavior)
buttons: [[{ text: "Approve", callback_data: "approve_123" }]]
// Mixed row
buttons: [[
{ text: "View", url: "https://example.com" },
{ text: "Delete", callback_data: "delete_123" }
]]
```
## Closes
Fixes #14548
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This change extends Telegram inline keyboard support to allow URL buttons in addition to callback buttons.
Updates include widening button types across the agent tool parser (`src/agents/tools/telegram-actions.ts`), outbound plugin payload typing (`src/channels/plugins/outbound/telegram.ts`), model button row type (`src/telegram/model-buttons.ts`), and send/edit option types plus keyboard construction (`src/telegram/send.ts`). The core behavior change is in `buildInlineKeyboard`, which now maps either `{ text, callback_data }` or `{ text, url }` into Telegram’s `InlineKeyboardButton` shape.
<h3>Confidence Score: 3/5</h3>
- Moderately safe, but there are a couple of end-to-end correctness gaps for URL buttons.
- Types and mapping for URL buttons are mostly consistent, but one bot delivery path still hard-casts buttons as callback-only, and `buildInlineKeyboard` can accept malformed button objects from unvalidated channelData (leading to Telegram API errors).
- src/telegram/bot/delivery.ts, src/telegram/send.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#22095: feat: add Telegram inline buttons to exec approval requests
by AIflow-Labs · 2026-02-20
81.8%
#9265: Feature: Telegram Inline Button Support for Exec Approvals
by vishaltandale00 · 2026-02-05
78.5%
#19991: feat(telegram): callback direct mode with dedupe, button state, and...
by li-yifei · 2026-02-18
77.8%
#16102: Fix: Telegram Inline Button Support for Exec Approvals (builds on #...
by RoguePhoenix117 · 2026-02-14
75.5%
#19829: fix(telegram): fall back to default scope for array capabilities wi...
by NewdlDewdl · 2026-02-18
75.4%
#12978: fix(telegram): use real message_id for inline button callback react...
by omair445 · 2026-02-10
74.9%
#11920: Telegram: create forum topics via message tool (thread-create)
by larsderidder · 2026-02-08
74.6%
#12950: feat: add Telegram pin/unpin message support
by alex-muradov · 2026-02-09
74.6%
#21898: fix(telegram): auto-detect captionable messages for editMessageCaption
by ptrkstr · 2026-02-20
74.4%
#19869: feat(telegram): add disableWebPagePreview option
by bip-bup-bip-bup · 2026-02-18
74.1%