fix(telegram): chunk long html outbound messages#42240
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
Greptile SummaryThis PR correctly fixes the core bug—Telegram messages via the HTML-mode outbound path now chunk properly instead of hitting the 4096-char limit. The One logic issue: The overflow branch in Confidence Score: 4/5
Last reviewed commit: 1856ec9 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e264a8b724
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@greptile-apps fix, review again. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1856ec91f2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6eee849ad9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const plainTextChunks = splitTelegramPlainTextFallback(fallbackText, htmlChunks.length, 4000); | ||
| return htmlChunks.map((htmlText, index) => ({ | ||
| htmlText, | ||
| plainText: plainTextChunks[index] ?? htmlText, |
There was a problem hiding this comment.
Treat empty fallback slices as missing in chunked HTML retries
When opts.plainText is shorter than the number of HTML chunks, splitTelegramPlainTextFallback can emit empty strings for trailing chunks, and this mapping keeps them because ?? only falls back on null/undefined. If a later HTML chunk hits a parse error, requestPlain then retries with "", which Telegram rejects with message text is empty, so the send fails instead of recovering. This is introduced in the chunked HTML path and is reproducible with a long malformed HTML message plus a short plainText fallback.
Useful? React with 👍 / 👎.
6eee849 to
dd8d85a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd8d85abb0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const plainTextChunks = splitTelegramPlainTextFallback(fallbackText, htmlChunks.length, 4000); | ||
| return htmlChunks.map((htmlText, index) => ({ | ||
| htmlText, | ||
| plainText: plainTextChunks[index] ?? htmlText, |
There was a problem hiding this comment.
Treat empty fallback chunks as missing text
When opts.plainText is shorter than the number of HTML chunks, splitTelegramPlainTextFallback can emit "" for trailing entries, and this mapping preserves those empty strings because it uses ??. If a later HTML chunk hits a parse-entity error, the retry path sends an empty plain-text message for that chunk, which Telegram rejects (message text is empty), so delivery fails instead of falling back to the chunk content.
Useful? React with 👍 / 👎.
dd8d85a to
4d79c41
Compare
Summary
channelData/ inline buttons) bypass chunking and hit Telegram's 4096-char limit.400: Bad Request: message is too long, silently dropping user-visible output.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
Long Telegram HTML-mode replies now arrive as multiple messages instead of failing once they exceed Telegram's message limit. Inline buttons remain attached to the final chunk.
Security Impact (required)
Yes, explain risk + mitigation:Repro + Verification
Environment
Steps
telegramOutbound.sendPayloadwithpayload.textlonger than 4096 chars andchannelData.telegram.buttonspresent.sendMessageTelegram.Expected
sendMessagecalls, each within Telegram's limit.reply_markuponly on the last chunk.Actual
sendMessagecall, then400: Bad Request: message is too long.4000and1001chars) with buttons only on the last chunk.Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
src/telegram/send.test.tsstill has two pre-existing retry-test failures unrelated to this path.Review Conversations
Compatibility / Migration
Failure Recovery (if this breaks)
src/telegram/send.ts,src/telegram/format.tsmessage is too long.Risks and Mitigations