- Fix ordered lists being sent as unordered lists in WhatsApp
integrations
- The WhatsApp markdown renderer was converting all lists to bullet
points (-), ignoring numbered list formatting
- Added ordered list support by tracking list_type and list_item_number
from CommonMarker AST metadata
Before:
Input: "1. First\n2. Second\n3. Third"
Output: "- First\n- Second\n- Third"
After:
Input: "1. First\n2. Second\n3. Third"
Output: "1. First\n2. Second\n3. Third"
Problem: SystemStackError: stack level too deep occurred when rendering
messages with indented content (4+ spaces) for WhatsApp, Instagram, and
Facebook channels.
Root Cause: CommonMarker::Renderer#code_block contains a self-recursive
placeholder that must be overridden:
```
def code_block(node)
code_block(node) # calls itself infinitely
end
```
WhatsAppRenderer and InstagramRenderer were missing this override,
causing infinite recursion when markdown with 4-space indentation
(interpreted as code blocks) was rendered.
Fix: Added code_block method to both renderers that outputs the node
content as plain text:
```
def code_block(node)
out(node.string_content)
end
```
Fix https://linear.app/chatwoot/issue/CW-6217/systemstackerror-stack-level-too-deep-systemstackerror
## Description
This PR fixes an issue where Twilio WhatsApp messages were losing
newlines and markdown formatting. The problem had two root causes:
1. Text-based renderers (WhatsApp, Instagram, SMS) were converting
newlines to spaces when processing plain text without markdown list
markers
2. Twilio WhatsApp channels were incorrectly using the plain text
renderer instead of the WhatsApp renderer, stripping all markdown
formatting
The fix updates the markdown rendering system to:
- Preserve newlines by overriding the `softbreak` method in WhatsApp,
Instagram, and PlainText renderers
- Detect Twilio WhatsApp channels (via the `medium` field) and route
them to use the WhatsApp renderer
- Maintain backward compatibility with existing code
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality not to work as expected)
- [ ] This change requires a documentation update
## How Has This Been Tested?
Added comprehensive test coverage:
- 3 new tests for newline preservation in WhatsApp, Instagram, and SMS
channels
- 4 new tests for Twilio WhatsApp specific behavior (medium detection,
formatting preservation, backward compatibility)
- All 53 tests passing (up from 50)
Manual testing verified:
- Twilio WhatsApp messages with plain text preserve newlines
- Twilio WhatsApp messages with markdown preserve formatting (bold,
italic, links)
- Regular WhatsApp, Instagram, and SMS channels continue to work
correctly
- Backward compatibility maintained when channel parameter is not
provided
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
# Pull Request Template
## Description
This PR includes,
1. **Channel-specific formatting and menu options** for the rich reply
editor.
2. **Removal of the plain reply editor** and full **standardization** on
the rich reply editor across all channels.
3. **Fix for multiple canned responses insertion:**
* **Before:** The plain editor only allowed inserting canned responses
at the beginning of a message, making it impossible to combine multiple
canned responses in a single reply. This caused inconsistent behavior
across the app.
* **Solution:** Replaced the plain reply editor with the rich
(ProseMirror) editor to ensure a unified experience. Agents can now
insert multiple canned responses at any cursor position.
4. **Floating editor menu** for the reply box to improve accessibility
and overall user experience.
5. **New Strikethrough formatting option** added to the editor menu.
---
**Editor repo PR**:
https://github.com/chatwoot/prosemirror-schema/pull/36
Fixes https://github.com/chatwoot/chatwoot/issues/12517,
[CW-5924](https://linear.app/chatwoot/issue/CW-5924/standardize-the-editor),
[CW-5679](https://linear.app/chatwoot/issue/CW-5679/allow-inserting-multiple-canned-responses-in-a-single-message)
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
### Screenshot
**Dark**
<img width="850" height="345" alt="image"
src="https://github.com/user-attachments/assets/47748e6c-380f-44a3-9e3b-c27e0c830bd0"
/>
**Light**
<img width="850" height="345" alt="image"
src="https://github.com/user-attachments/assets/6746cf32-bf63-4280-a5bd-bbd42c3cbe84"
/>
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com>