#23728: fix(telegram): clear done reaction when removeAckAfterReply is true
channel: telegram
size: S
Cluster:
Telegram Message Handling Fixes
## Summary
- Fix status reaction cleanup in Telegram when `statusReactions.enabled` and `removeAckAfterReply` are both true
- After `setDone()` or `setError()`, sleep for the appropriate hold delay then call `clear()` — mirroring Discord's existing behavior
- Add three test cases covering the done, error, and no-clear paths
## Problem
When `statusReactions.enabled: true` and `removeAckAfterReply: true` in Telegram, the done reaction (👍) was never removed after replying. Discord correctly calls `statusReactions.clear()` after a hold delay, but Telegram only called `setDone()` without the subsequent cleanup.
Closes #23664
## Test plan
- [x] Verify `statusReactionController.clear()` is called after `setDone()` with `DEFAULT_TIMING.doneHoldMs` delay when `removeAckAfterReply` is true
- [x] Verify `statusReactionController.clear()` is NOT called when `removeAckAfterReply` is false
- [x] Verify `statusReactionController.clear()` is called after `setError()` with `DEFAULT_TIMING.errorHoldMs` delay when `removeAckAfterReply` is true and no final response
- [x] All 47 existing + new tests pass (`npx vitest run src/telegram/bot-message-dispatch.test.ts`)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixes status reaction cleanup in Telegram to match Discord's behavior when both `statusReactions.enabled` and `removeAckAfterReply` are true. After setting done (👍) or error (❌) reactions, the code now sleeps for the appropriate hold delay (`DEFAULT_TIMING.doneHoldMs` or `DEFAULT_TIMING.errorHoldMs`) before calling `statusReactionController.clear()`.
**Changes:**
- Added `sleep` import from `../utils.js` and `DEFAULT_TIMING` import from `../channels/status-reactions.js`
- Modified both done and error reaction handlers to use fire-and-forget async IIFEs that conditionally call `clear()` after the hold delay when `removeAckAfterReply` is true
- Added three test cases covering: done reaction cleanup, no cleanup when disabled, and error reaction cleanup
**Implementation notes:**
- Correctly uses fire-and-forget pattern (`void (async () => {...})()`) consistent with Discord implementation in `src/discord/monitor/message-handler.process.ts:717-724`
- Error handling properly wraps the entire sequence in try-catch
- Tests use `vi.waitFor()` to handle async fire-and-forget assertions
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with no concerns
- The implementation correctly mirrors Discord's existing pattern, uses appropriate error handling, and includes comprehensive test coverage for all code paths. The fix is well-scoped to address the specific issue without introducing side effects.
- No files require special attention
<sub>Last reviewed commit: fc331c1</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#21346: [AI-assisted] Telegram: add reaction state machine with fallback an...
by Archie818 · 2026-02-19
82.7%
#17316: fix: ack reaction not removed when block streaming is enabled (Tele...
by czmathew · 2026-02-15
80.5%
#14977: fix(telegram): remove ack reaction after block-streamed replies
by Diaspar4u · 2026-02-12
79.6%
#20236: fix(telegram): make reaction handling soft-fail and message-id resi...
by PeterShanxin · 2026-02-18
78.7%
#22331: Fix Telegram reaction emoji normalization
by AIflow-Labs · 2026-02-21
78.4%
#19213: Telegram: preserve DM topic thread in direct replies
by Kemalau · 2026-02-17
76.4%
#12978: fix(telegram): use real message_id for inline button callback react...
by omair445 · 2026-02-10
76.1%
#19050: fix(telegram): skip message_thread_id for private chats to prevent ...
by Limitless2023 · 2026-02-17
75.9%
#12936: fix(telegram): omit message_thread_id for private DM chats
by omair445 · 2026-02-09
75.6%
#16105: fix: handle message_reaction updates in group polling mode
by claw-sylphx · 2026-02-14
75.4%