fix: use queue-based re-splitting for HTML expansion validation

After re-splitting an oversized chunk, sub-chunks were sent without
verifying their HTML also fits under 4096 chars. Non-uniform HTML
expansion (e.g. a sub-chunk dense with bold/links) could still exceed
the limit. Use a queue that pushes sub-chunks back for re-validation
instead of sending them blindly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
I Putu Eddy Irawan
2026-03-04 22:19:04 +07:00
parent 3de4cb863b
commit bd0018a5d7
+10 -8
View File
@@ -242,23 +242,25 @@ func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) err
// we never break HTML tags/entities by splitting converted output.
mdChunks := channels.SplitMessage(msg.Content, 4000)
for _, chunk := range mdChunks {
// Use a queue so that chunks whose HTML expansion still exceeds
// Telegram's 4096-char limit can be re-split until every chunk fits.
queue := append([]string{}, mdChunks...)
for len(queue) > 0 {
chunk := queue[0]
queue = queue[1:]
htmlContent := markdownToTelegramHTML(chunk)
// If HTML expansion pushes the chunk over Telegram's 4096-char limit,
// re-split the markdown chunk with a proportionally smaller maxLen.
if len([]rune(htmlContent)) > 4096 {
ratio := float64(len([]rune(chunk))) / float64(len([]rune(htmlContent)))
smallerLen := int(float64(4096) * ratio * 0.95) // 5% safety margin
if smallerLen < 100 {
smallerLen = 100
}
// Push sub-chunks back to the front of the queue for
// re-validation instead of sending them blindly.
subChunks := channels.SplitMessage(chunk, smallerLen)
for _, sub := range subChunks {
if err := c.sendHTMLChunk(ctx, chatID, markdownToTelegramHTML(sub), sub); err != nil {
return err
}
}
queue = append(subChunks, queue...)
continue
}