chatwoot/app/services/messages
ramalau 36a05097fa
fix(webhooks): strip trailing newlines from webhook message content (#14272)
The TipTap/ProseMirror editor stores agent messages with trailing
paragraph nodes that produce trailing newlines (e.g. \`\n\n\n\`) in the
\`content\` field. While Chatwoot's native channel delivery already
handles this, webhook payloads and API responses were returning raw
content with trailing whitespace — causing visible blank space below
messages in every external integration that consumes Chatwoot webhooks
(WhatsApp via Evolution API, Telegram bots, custom webhook consumers).

Closes #13459

## Root cause

\`Messages::WebhookContentNormalizer\` already strips CommonMark hard
line breaks (\`\\\` + newline) for webhook consumers, but it did not
strip trailing whitespace. All webhook and API responses flow through
this normaliser, so it is the single correct place to apply the fix
without touching stored data.

## What changed

Added \`.rstrip\` to \`Messages::WebhookContentNormalizer.normalize\`:

\`\`\`ruby
# before
text.gsub(/\\\r?\n/, "\n")

# after
text.gsub(/\\\r?\n/, "\n").rstrip
\`\`\`

## Trade-offs considered

| Option | Decision |
|---|---|
| \`before_save\` on \`Message\` model | Would clean stored data but is
a broader change affecting all message creation paths and would require
a data migration for existing records. Out of scope for this bug. |
| Trim in each channel's send path | DRY violation — many channels, each
would need the same patch. |
| Fix at normaliser level (chosen) | Single location, only affects
webhook/API output, zero risk to stored data or native channel delivery.
|

**Known limitation:** existing messages in the database still have
trailing newlines in storage. They will be delivered correctly through
webhooks after this fix, but a follow-up migration could clean stored
content if needed.

## How to reproduce

1. Send an agent reply from the Chatwoot UI
2. Inspect the \`content\` field of the outgoing \`message_created\`
webhook payload
3. Observe trailing \`\n\n\n\` after the message text

After this fix, the \`content\` field is trimmed before delivery.

---------

Co-authored-by: Ramalau Debeila <rdebeila@datacentrix.co.za>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
2026-06-02 23:28:13 +05:30
..
markdown_renderers fix(whatsapp): Preserve ordered list numbering in messages (#13339) 2026-01-22 14:14:40 +04:00
in_reply_to_message_builder.rb feat: support reply to for outgoing message in WhatsApp (#8107) 2023-10-19 13:24:46 -07:00
markdown_renderer_service.rb fix: Preserve double newlines in text-based messaging channels (#13055) 2025-12-12 16:35:53 +05:30
mention_service.rb fix(notifications): Respect conversation access when notifying agents (#14412) 2026-05-12 10:57:29 +04:00
new_message_notification_service.rb fix: Prevent duplicate notifications for mentions (#10675) 2025-01-13 11:20:31 +05:30
send_email_notification_service.rb feat: add per-account daily rate limit for outbound emails (#13411) 2026-02-03 02:06:51 +05:30
status_update_service.rb feat: API Endpoints to update message status (#11387) 2025-04-29 15:33:11 -07:00
webhook_content_normalizer.rb fix(webhooks): strip trailing newlines from webhook message content (#14272) 2026-06-02 23:28:13 +05:30