#16997: fix(telegram): preserve entities during text fragment reassembly
channel: telegram
stale
size: M
Cluster:
Telegram Message Handling Fixes
## Summary
- When long Telegram messages are split into fragments and reassembled, all formatting entities (bold, italic, code blocks, links, mentions) were explicitly discarded by setting `entities: undefined` on the synthetic message. This could cause bot mentions in entities to be lost, potentially causing messages to be ignored in mention-gated groups.
- Extracted a `mergeFragmentEntities()` utility that merges entities from all fragments with correctly adjusted `offset` values, accounting for concatenated text positions and optional separators.
- Fixed both the text fragment reassembly path (no separator) and the inbound debounce flush path (`"\n"` separator).
## Test plan
- [x] Added unit tests for `mergeFragmentEntities()` covering: single fragments, multi-fragment offset adjustment, newline separator handling, bot mention preservation, interspersed empty-entity fragments, empty text fragments, empty input, and extra entity fields (url, user)
- [x] All 10 tests pass
- [x] TypeScript type-check passes with no errors
- [x] Linter and formatter pass with no issues
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixes a bug where Telegram message entities (bold, italic, mentions, links, etc.) were discarded during text fragment reassembly and inbound debounce flushing. Previously, the synthetic merged message set `entities: undefined`, which caused `hasBotMention()` and `expandTextLinks()` to lose formatting and mention data — potentially causing the bot to ignore messages in mention-gated groups.
- Extracts a new `mergeFragmentEntities()` utility in `src/telegram/merge-entities.ts` that correctly accumulates UTF-16 offsets across concatenated fragments, accounting for optional separators and empty fragments.
- Both call sites in `bot-handlers.ts` (debounce flush with `"\n"` separator, and text fragment flush with no separator) are updated consistently, with the debounce path correctly pre-filtering to non-empty fragments.
- Comprehensive test suite covers offset adjustment, separator handling, empty fragments, extra entity fields, and bot mention preservation.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge — it fixes a real entity-loss bug with correct offset math and thorough tests.
- The change is well-scoped: a single new utility with clean offset arithmetic, two consistent call sites, and 10 unit tests covering edge cases. The merging logic correctly uses JavaScript string.length (UTF-16 code units) which matches Telegram's entity offset convention. Both call sites maintain consistency between how combinedText is built and how entities are merged. No regressions are introduced — the previous behavior was strictly worse (discarding all entities).
- No files require special attention.
<sub>Last reviewed commit: 04a039b</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#15985: fix(telegram): defer buffer deletion until processing succeeds
by coygeek · 2026-02-14
77.2%
#17953: fix(telegram): prevent silent message loss and duplicate messages i...
by zuyan9 · 2026-02-16
75.9%
#17769: fix(telegram): preserve reply text in threaded mode dispatch
by Glucksberg · 2026-02-16
75.9%
#8368: fix(telegram): preserve forwarded message metadata during debounce ...
by PatrickBauer · 2026-02-03
75.4%
#11347: fix: scope Telegram update offset to bot token
by anooprdawar · 2026-02-07
75.4%
#17629: fix(telegram): fall back to plain text when HTML formatter produces...
by Glucksberg · 2026-02-16
75.2%
#21276: fix(telegram): stabilize partial finalization and MEDIA dedupe (AI-...
by HOYALIM · 2026-02-19
74.8%
#19479: fix(telegram): skip redundant final edit in partial streaming mode
by v8hid · 2026-02-17
74.8%
#7141: fix(telegram): unify network error detection to prevent poll crashes
by hclsys · 2026-02-02
74.8%
#19375: telegram: align tool-error summaries
by NorthyIE · 2026-02-17
74.5%