#12978: fix(telegram): use real message_id for inline button callback reactions
channel: telegram
size: XS
Cluster:
Messaging Platform Improvements
## Summary
Fixes Telegram inline button callback using the callback query ID instead of the real message ID, causing reactions to fail with `400: Bad Request: message to react not found`.
Closes #12886
## Changes
- **`bot-handlers.ts`**: Added `reactionMessageId: String(callbackMessage.message_id)` to both callback query handler paths (model selection + generic callbacks), preserving `callback.id` as `messageIdOverride` for dedup
- **`bot-message-context.ts`**: Added `reactionMessageId` to options type; populates `MessageSidFull` with the real message ID when set
- **`bot-message.ts`** / **`bot-native-commands.ts`**: Updated options type to include `reactionMessageId`
## How It Works
- `MessageSid` = `callback.id` (callback query ID) — used for message dedup, so distinct button presses are processed independently
- `MessageSidFull` = `callbackMessage.message_id` (real Telegram message ID) — used for the `[message_id: ...]` hint shown to agents
- Existing resolution (`MessageSidFull ?? MessageSid`) ensures agents see the real message ID for reactions
## Testing
- Added test verifying `MessageSid` remains the callback query ID and `MessageSidFull` contains the real message ID
- All 415 Telegram tests pass
- Pre-existing dedup test continues to pass (callback IDs remain distinct for dedup)
🤖 Generated with Claude (AI-assisted)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes Telegram inline-button callback handling by keeping `MessageSid` as the callback query id (so each button press dedups independently) while additionally exposing the *real* Telegram `message_id` via `MessageSidFull` (used downstream for reactions and other message-id based features). Concretely, the callback_query handler now passes `reactionMessageId` derived from `callbackQuery.message.message_id`, and the Telegram message context builder wires that into `ctxPayload.MessageSidFull`.
This fits the existing reply pipeline where downstream code already prefers `MessageSidFull ?? MessageSid` when it needs an actual provider message id (e.g., for reaction APIs), while still using `MessageSid` as the primary stable/dedup identifier.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Changes are small, localized, and align with existing downstream expectations (`MessageSidFull ?? MessageSid`). A targeted test was added to validate the new behavior for callback_query flows, and the new option is threaded through relevant types without altering unrelated processing paths.
- No files require special attention
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#20236: fix(telegram): make reaction handling soft-fail and message-id resi...
by PeterShanxin · 2026-02-18
82.1%
#9734: fix(telegram): correct sender identification for channel messages (...
by divol89 · 2026-02-05
78.9%
#16105: fix: handle message_reaction updates in group polling mode
by claw-sylphx · 2026-02-14
78.8%
#19213: Telegram: preserve DM topic thread in direct replies
by Kemalau · 2026-02-17
77.6%
#19050: fix(telegram): skip message_thread_id for private chats to prevent ...
by Limitless2023 · 2026-02-17
77.6%
#12936: fix(telegram): omit message_thread_id for private DM chats
by omair445 · 2026-02-09
77.5%
#21346: [AI-assisted] Telegram: add reaction state machine with fallback an...
by Archie818 · 2026-02-19
77.0%
#14443: fix(telegram): skip General topic thread ID for all chat types (#14...
by lailoo · 2026-02-12
76.9%
#17316: fix: ack reaction not removed when block streaming is enabled (Tele...
by czmathew · 2026-02-15
76.9%
#22095: feat: add Telegram inline buttons to exec approval requests
by AIflow-Labs · 2026-02-20
76.6%