Commit Graph

5837 Commits

Author SHA1 Message Date
Gabriel Jablonski
24d348cdd3
feat: whastapp cloud provider voice notes (#186) 2026-01-15 23:00:30 -03:00
Gabriel Jablonski
5a2658fd19
fix: fixed bundler version to avoid bundler 4.0.4 incompatibility (#187) 2026-01-15 22:59:57 -03:00
Gabriel Jablonski
f54d113571
fix: whatsapp race condition (#185)
* feat: include external created at in whatsapp cloud message

* fix: whatsapp providers race condition

* refactor: remove redundant comments and streamline message processing lock acquisition

* fix: scope message source key by inbox.id to prevent race condition

* fix: scope message source key by inbox.id to prevent race condition
2026-01-15 22:16:32 -03:00
Gabriel Jablonski
43d7642485
feat: signature preview and fix sending signature on whatsapp cloud channel (#183)
* fix: send signature on whatsapp cloud provider

* fix: simplify attachment checks and remove redundant comments in ReplyBox

* feat: signature preview

* fix: update default signature position to top in Editor and ReplyBox components

* fix: refactor signature application logic in ReplyBox component
2026-01-13 23:51:38 -03:00
Gabriel Jablonski
4db3c7c7ed
feat: include account_id in contact and inbox JSON responses (#182)
* test: include account_id in inbox response validation
2026-01-13 00:51:10 -03:00
Gabriel Jablonski
85e8258a87
feat(webhook): message incoming/outgoing (#181)
* feat(webhook): message created incoming/outgoing

* feat(webhook): rename message_created_incoming/outgoing to message_incoming/outgoing

* chore: remove redundant comment
2026-01-03 00:11:50 -03:00
Gabriel Jablonski
8655e5b025
feat(webhook): retry webhook job on any error (#180) 2026-01-02 23:59:08 -03:00
Gabriel Jablonski
3c2d535de2
feat(webhook): retry job on 404 (#179)
* feat(webhook): retry job on 404

* feat(webhook): enhance retry logic for 404 errors and update message status

* feat(webhook): update supported message events to use dynamic error handling

* chore: refactor logic

* feat(webhook): simplify RetriableError initialization and improve error handling for 404 responses
2026-01-01 20:42:16 -03:00
Gabriel Jablonski
544aeaa5a0
fix: annotaterb (#173)
* fix: annotaterb

* fix: ensure Hash values are accessed with indifferent access in SerializedValueCoder

Also include missing annotaterb options
2025-12-30 15:18:43 -03:00
Gabriel Jablonski
a27737e91c
feat: allow updating attachment metadata (#172)
* feat: allow updating attachment metadata

* feat: allow updating attachment metadata

* feat: add tests for handling requests without meta parameter and empty meta parameter
2025-12-25 19:27:47 -03:00
Gabriel Jablonski
ba9a0160ac
fix: improve handling of empty custom attributes list in settings (#171) 2025-12-25 19:11:31 -03:00
Gabriel Jablonski
331338b302
fix(sidebar): improve active child route matching logic (#170) 2025-12-20 18:12:27 -03:00
Gabriel Jablonski
0fd57d47d2
Merge pull request #169 from fazer-ai/chore/merge-upstream
Chore/merge upstream
2025-12-20 13:05:56 -03:00
gabrieljablonski
6d9a344186 chore: fix linting 2025-12-20 12:55:27 -03:00
gabrieljablonski
549214e96d Merge branch main into chore/merge-upstream 2025-12-20 12:44:31 -03:00
Sojan Jose
20d97be4c9 Merge branch 'release/4.9.0' into develop 2025-12-19 19:13:03 -08:00
Sojan Jose
6365a7ea53 Bump version to 4.9.0 2025-12-19 19:12:13 -08:00
Pranav
2adc040a8f
fix: Validate blob before attaching it to a record (#13115)
Previously, attachments relied only on blob_id, which made it possible
to attach blobs across accounts by enumerating IDs. We now require both
blob_id and blob_key, add cross-account validation to prevent blob
reuse, and centralize the logic in a shared BlobOwnershipValidation
concern.

It also fixes a frontend bug where mixed-type action params (number +
string) were incorrectly dropped, causing attachment uploads to fail.
2025-12-19 19:02:21 -08:00
Pranav
86da3f7c06
fix: Remove account_id from params since it is not used (#13116)
account_id was permitted in strong parameters, allowing authenticated
admins to transfer resources (Portals, Automation Rules, Macros) to
arbitrary accounts.

 Fix: Removed account_id from permitted params in 4 controllers:
  - portals_controller.rb
  - automation_rules_controller.rb
  - macros_controller.rb
  - twilio_channels_controller.rb
2025-12-19 17:07:53 -08:00
Sojan Jose
c22a31c198
feat: Voice Channel (#11602)
Enables agents to initiate outbound calls and receive incoming calls
directly from the Chatwoot dashboard, with Twilio as the initial
provider.

Fixes:  #11481 

> This is an integration branch to ensure features works well and might
be often broken on down merges, we will be extracting the
functionalities via smaller PRs into develop

- [x] https://github.com/chatwoot/chatwoot/pull/11775
- [x] https://github.com/chatwoot/chatwoot/pull/12218
- [x] https://github.com/chatwoot/chatwoot/pull/12243
- [x] https://github.com/chatwoot/chatwoot/pull/12268
- [x] https://github.com/chatwoot/chatwoot/pull/12361
- [x]  https://github.com/chatwoot/chatwoot/pull/12782
- [x] #13064
- [ ] Ability for agents to join the inbound calls ( included in this PR
)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
2025-12-19 12:41:33 -08:00
Chatwoot Bot
8019e7c636
chore: Update translations (#13105)
Co-authored-by: Sojan Jose <sojan@pepalo.com>
2025-12-18 01:39:35 -08:00
Vishnu Narayanan
29f670189a
fix: skip orphaned inbox members in widget api endpoint (#13054) 2025-12-18 14:22:54 +05:30
Ynon Perek
2b5638287c
chore: Add Hebrew translation to components.json (#13072)
- Add Hebrew translation to components.json
2025-12-17 18:52:32 -08:00
Yuval
c117257b42
chore: Updated Hebrew translations (#12883)
Text in hebrew was broken and incomplete - i have completed the
translation and fixed some annoying terms for better understanding and
user experience.
2025-12-17 17:34:42 -08:00
Gvidas
07b561952b
chore: Update Lithuanian translations in lt.json (#12927)
Description

This pull request updates several Lithuanian (lt.json) translations in
the Chatwoot widget.
The previous versions contained grammatical issues, unnatural phrasing,
and direct machine-translated structures.
The updated translations now follow proper Lithuanian grammar, natural
wording, and are consistent with the tone used across the rest of the
UI.

Fixes: No linked issue (translation improvement).
2025-12-17 17:22:25 -08:00
Lavesh Patil
d747b95f6e
fix: Add Contact form buttons cut off on mobile web (fixes #13081) (#13099) 2025-12-18 05:34:35 +05:30
Sojan Jose
7314c279ee
test(leadsquared): make ApiError specs reload-safe (#13098)
- fix the flaky lead-squared spec
2025-12-17 13:30:34 -08:00
Mazen Khalil
ca5e112a8c
feat: TikTok channel (#12741)
fixes: #11834

This pull request introduces TikTok channel integration, enabling users
to connect and manage TikTok business accounts similarly to other
supported social channels. The changes span backend API endpoints,
authentication helpers, webhook handling, configuration, and frontend
components to support TikTok as a first-class channel.


**Key Notes**
* This integration is only compatible with TikTok Business Accounts
* Special permissions are required to access the TikTok [Business
Messaging
API](https://business-api.tiktok.com/portal/docs?id=1832183871604753).
* The Business Messaging API is region-restricted and is currently
unavailable to users in the EU.
* Only TEXT, IMAGE, and POST_SHARE messages are currently supported due
to limitations in the TikTok Business Messaging API
* A message will be successfully sent only if it contains text alone or
one image attachment. Messages with multiple attachments or those
combining text and attachments will fail and receive a descriptive error
status.
* Messages sent directly from the TikTok App will be synced into the
system
* Initiating a new conversation from the system is not permitted due to
limitations from the TikTok Business Messaging API.


**Backend: TikTok Channel Integration**

* Added `Api::V1::Accounts::Tiktok::AuthorizationsController` to handle
TikTok OAuth authorization initiation, returning the TikTok
authorization URL.
* Implemented `Tiktok::CallbacksController` to handle TikTok OAuth
callback, process authorization results, create or update channel/inbox,
and handle errors or denied scopes.
* Added `Webhooks::TiktokController` to receive and verify TikTok
webhook events, including signature verification and event dispatching.
* Created `Tiktok::IntegrationHelper` module for JWT-based token
generation and verification for secure TikTok OAuth state management.

**Configuration and Feature Flags**

* Added TikTok app credentials (`TIKTOK_APP_ID`, `TIKTOK_APP_SECRET`) to
allowed configs and app config, and registered TikTok as a feature in
the super admin features YAML.
[[1]](diffhunk://#diff-5e46e1d248631a1147521477d84a54f8ba6846ea21c61eca5f70042d960467f4R43)
[[2]](diffhunk://#diff-8bf37a019cab1dedea458c437bd93e34af1d6e22b1672b1d43ef6eaa4dcb7732R69)
[[3]](diffhunk://#diff-123164bea29f3c096b0d018702b090d5ae670760c729141bd4169a36f5f5c1caR74-R79)

**Frontend: TikTok Channel UI and Messaging Support**

* Added `TiktokChannel` API client for frontend TikTok authorization
requests.
* Updated channel icon mappings and tests to include TikTok
(`Channel::Tiktok`).
[[1]](diffhunk://#diff-b852739ed45def61218d581d0de1ba73f213f55570aa5eec52aaa08f380d0e16R16)
[[2]](diffhunk://#diff-3cd3ae32e94ef85f1f2c4435abf0775cc0614fb37ee25d97945cd51573ef199eR64-R69)
* Enabled TikTok as a supported channel in contact forms, channel
widgets, and feature toggles.
[[1]](diffhunk://#diff-ec59c85e1403aaed1a7de35971fe16b7033d5cd763be590903ebf8f1ca25a010R47)
[[2]](diffhunk://#diff-ec59c85e1403aaed1a7de35971fe16b7033d5cd763be590903ebf8f1ca25a010R69)
[[3]](diffhunk://#diff-725b90ca7e3a6837ec8291e9f57094f6a46b3ee00e598d16564f77f32cf354b0R26-R29)
[[4]](diffhunk://#diff-725b90ca7e3a6837ec8291e9f57094f6a46b3ee00e598d16564f77f32cf354b0R51-R54)
[[5]](diffhunk://#diff-725b90ca7e3a6837ec8291e9f57094f6a46b3ee00e598d16564f77f32cf354b0R68)
* Updated message meta logic to support TikTok-specific message statuses
(sent, delivered, read).
[[1]](diffhunk://#diff-e41239cf8dda36c1bd1066dbb17588ae8868e56289072c74b3a6d7ef5abdd696R23)
[[2]](diffhunk://#diff-e41239cf8dda36c1bd1066dbb17588ae8868e56289072c74b3a6d7ef5abdd696L63-R65)
[[3]](diffhunk://#diff-e41239cf8dda36c1bd1066dbb17588ae8868e56289072c74b3a6d7ef5abdd696L81-R84)
[[4]](diffhunk://#diff-e41239cf8dda36c1bd1066dbb17588ae8868e56289072c74b3a6d7ef5abdd696L103-R107)
* Added support for embedded message attachments (e.g., TikTok embeds)
with a new `EmbedBubble` component and updated message rendering logic.
[[1]](diffhunk://#diff-c3d701caf27d9c31e200c6143c11a11b9d8826f78aa2ce5aa107470e6fdb9d7fR31)
[[2]](diffhunk://#diff-047859f9368a46d6d20177df7d6d623768488ecc38a5b1e284f958fad49add68R1-R19)
[[3]](diffhunk://#diff-c3d701caf27d9c31e200c6143c11a11b9d8826f78aa2ce5aa107470e6fdb9d7fR316)
[[4]](diffhunk://#diff-cbc85e7c4c8d56f2a847d0b01cd48ef36e5f87b43023bff0520fdfc707283085R52)
* Adjusted reply policy and UI messaging for TikTok's 48-hour reply
window.
[[1]](diffhunk://#diff-0d691f6a983bd89502f91253ecf22e871314545d1e3d3b106fbfc76bf6d8e1c7R208-R210)
[[2]](diffhunk://#diff-0d691f6a983bd89502f91253ecf22e871314545d1e3d3b106fbfc76bf6d8e1c7R224-R226)

These changes collectively enable end-to-end TikTok channel support,
from configuration and OAuth flow to webhook processing and frontend
message handling.


------------

# TikTok App Setup & Configuration
1. Grant access to the Business Messaging API
([Documentation](https://business-api.tiktok.com/portal/docs?id=1832184145137922))
2. Set the app authorization redirect URL to
`https://FRONTEND_URL/tiktok/callback`
3. Update the installation config with TikTok App ID and Secret
4. Create a Business Messaging Webhook configuration and set the
callback url to `https://FRONTEND_URL/webhooks/tiktok`
([Documentation](https://business-api.tiktok.com/portal/docs?id=1832190670631937))
. You can do this by calling
`Tiktok::AuthClient.update_webhook_callback` from rails console once you
finish Tiktok channel configuration in super admin ( will be automated
in future )
5. Enable TikTok channel feature in an account

---------

Co-authored-by: Sojan Jose <sojan@pepalo.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
2025-12-17 07:54:50 -08:00
Muhsin Keloth
116ed54c7e
fix: Prioritize SDK enableFileUpload flag when explicitly set (#13091)
### Problem
Currently, the attachment button visibility in the widget uses both the
SDK's `enableFileUpload` flag AND the inbox's attachment settings with
an AND condition. This creates an issue for users who want to control
attachments solely through inbox settings, since the SDK flag defaults
to `true` even when not explicitly provided.

  **Before:**
- SDK not set → `enableFileUpload: true` (default) + inbox setting =
attachment shown only if both true
- SDK set to false → `enableFileUpload: false` + inbox setting =
attachment always hidden
- SDK set to true → `enableFileUpload: true` + inbox setting =
attachment shown only if both true
  
This meant users couldn't rely solely on inbox settings when the SDK
flag wasn't explicitly provided.

  ### Solution

Changed the logic to prioritize explicit SDK configuration when
provided, and fall back to inbox settings when not provided:

  **After:**
  - SDK not set → `enableFileUpload: undefined` → use inbox setting only
- SDK set to false → `enableFileUpload: false` → hide attachment (SDK
controls)
- SDK set to true → `enableFileUpload: true` → show attachment (SDK
controls)

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
2025-12-17 19:03:54 +05:30
Muhsin Keloth
cfa0bb953b
feat: Custom attribute page redesign (#13087)
Fixes
https://linear.app/chatwoot/issue/CW-6096/custom-attributes-page-redesign
<img width="2390" height="1822"
alt="524664368-b92a6eb7-7f6c-40e6-bf23-6a5310f2d9c5"
src="https://github.com/user-attachments/assets/a29726e7-3d28-4811-8429-6483056d57cb"
/>

---------

Co-authored-by: iamsivin <iamsivin@gmail.com>
2025-12-17 14:30:49 +05:30
Pranav
b6a14bda48
chore: Enable YearInReview for everyone, include analytics (#13090)
Remove the query param condition and enable it for everyone.
2025-12-16 18:20:10 -08:00
Sivin Varghese
fd8919b901
chore: Replace installation name in captain empty state (#13083)
# Pull Request Template

## Description

This PR fixes the installation name in empty states on the Captain
Documents and Captain FAQs pages.

Fixes
https://linear.app/chatwoot/issue/CW-6159/display-brand-name-in-empty-state-messages-on-the-captain-page

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

### Screenshots
<img width="986" height="700" alt="image"
src="https://github.com/user-attachments/assets/7ba32fbb-ea93-4206-9e8d-ef037a83f72e"
/>
<img width="1062" height="699" alt="image"
src="https://github.com/user-attachments/assets/a70bec15-9bfe-4600-b355-f486f93a6839"
/>



## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] 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
- [ ] 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
2025-12-16 15:04:34 +05:30
Muhsin Keloth
0d490640f2
feat: Conversation workflow backend changes (#13070)
Extracted the backend changes from
https://github.com/chatwoot/chatwoot/pull/13040

- Added the support for saving `conversation_required_attributes` in
account
- Delete `conversation_required_attributes` if custom attribute deleted.

Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com>
2025-12-16 14:43:15 +05:30
Sivin Varghese
02216471c3
feat: Enable attachment paste in new conversation modal (#13082) 2025-12-16 14:35:42 +05:30
Sivin Varghese
68d8e62a5c
fix: Share modal not working in year-in-review (#13079) 2025-12-16 12:32:52 +05:30
Pranav
bb8bafe3dc
feat(ce): Add Year in review feature (#13078)
<img width="1502" height="813" alt="Screenshot 2025-12-15 at 5 01 57 PM"
src="https://github.com/user-attachments/assets/ea721f00-403c-4adc-8410-5c0fa4ee4122"
/>
2025-12-15 17:24:45 -08:00
Sojan Jose
d2ba9a2ad3
feat(enterprise): add voice conference API (#13064)
The backend APIs for the voice call channel 
ref: #11602
2025-12-15 15:11:59 -08:00
Gabriel Jablonski
6a220ea7fd
fix: update message creation method to avoid using bang operator (#167) 2025-12-15 17:10:35 -03:00
Aakash Bakhle
3fce56c98f
fix: captain template message conflict (#13048)
Co-authored-by: aakashb95 <aakash@chatwoot.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
2025-12-15 15:47:26 +05:30
Gabriel Jablonski
34b5b58d72
fix: improve error handling for Baileys API unavailability (#166) 2025-12-12 11:29:15 -03:00
Vishnu Narayanan
26b4a24f11
fix: linear and user association spec (#13056)
- Linear::CallbacksController: Replace broken
`described_class.new`mocking with proper `GlobalConfigService` stubbing
and real JWT token generation. The old pattern doesn't work in request
specs since Rails instantiates controllers internally.
- User associations: Remove `.class_name('Conversation')` assertion that
fails intermittently due to enterprise `prepend_mod_with` timing in
parallel tests. The class_name is already enforced by Rails at runtime -
if wrong, the app would crash immediately. No need to explicitly test
for this

Fixes
https://linear.app/chatwoot/issue/CW-6138/debug-linear-and-user-spec-failures-in-ci
2025-12-12 18:53:26 +05:30
Gabriel Jablonski
774c168d94
fix: z-api read message (#165)
* fix: z-api read messages

* fix: use threads for parallel requests

* feat: use jobs instead

* fix: refactor ZapiReadMessageJob to use service method for sending read messages
2025-12-12 09:58:12 -03:00
Vinay Keerthi
a8ed074bf0
fix: Preserve double newlines in text-based messaging channels (#13055)
## Summary

Fixes the issue where double newlines (paragraph breaks) were collapsing
to single newlines in text-based messaging channels (Telegram, WhatsApp,
Instagram, Facebook, LINE, SMS).

### Root Cause

The `preserve_multiple_newlines` method only preserved 3+ consecutive
newlines using the regex `/\n{3,}/`. When users pressed Enter twice
(creating a paragraph break with 2 newlines), CommonMarker would parse
this as separate paragraphs, which then collapsed to a single newline in
the output.

This caused:
-  Normal Enter: Double newlines collapsed to single newline
-  Shift+Enter: Worked (created hard breaks)

### Fix

Changed the regex from `/\n{3,}/` to `/\n{2,}/` to preserve 2+
consecutive newlines. This prevents CommonMarker from collapsing
paragraph breaks.

Now:
-  Single newline (`\n`) → Single newline (handled by softbreak)
-  Double newline (`\n\n`) → Double newline (preserved with
placeholders)
-  Triple+ newlines → Preserved as before

### Test Coverage

Added comprehensive tests for:
- Single newlines preservation
- Double newlines (paragraph breaks) preservation  
- Multiple consecutive newlines
- Newlines with varying amounts of whitespace between them (1 space, 3
spaces, 5 spaces, tabs)

All 66 tests passing.

### Impact

This fix affects all text-based messaging channels that use the markdown
renderer:
- Telegram
- WhatsApp
- Instagram  
- Facebook
- LINE
- SMS
- Twilio SMS (when configured for WhatsApp)

Fixes
https://linear.app/chatwoot/issue/CW-6135/double-newline-is-breaking

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-12-12 16:35:53 +05:30
Sivin Varghese
96fe3e146d
chore: Clean up reply box component (#13060) 2025-12-12 10:50:02 +05:30
Sivin Varghese
696564863c
feat: Add plain-text editor for non-rich content channels (#13058)
# Pull Request Template

## Description

This PR restores the plain text editor for all channels except Website,
Email, and API.

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)


## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] 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
- [ ] 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
2025-12-12 10:14:22 +05:30
Sivin Varghese
df4c8cf58b
chore: Strip unsupported signature formatting by channel (#13046)
# Pull Request Template

## Description

1. This PR is an enhancement to
https://github.com/chatwoot/chatwoot/pull/13045
It strips unsupported formatting from **message signatures** based on
each channel’s formatting capabilities defined in the `FORMATTING`
config

2. Remove usage of plain editor in Compose new conversation modal

Only the following signature elements are considered:
<strong>bold (<code inline="">strong</code>), italic (<code
inline="">em</code>), links (<code inline="">link</code>), images (<code
inline="">image</code>)</strong>.</p>

Any formatting not supported by the target channel is automatically
removed before the signature is appended.

<h3>Channel-wise Signature Formatting Support</h3>

Channel | Keeps in Signature | Strips from Signature
-- | -- | --
Email | bold, italic, links, images | —
WebWidget | bold, italic, links, images | —
API | bold, italic | links, images
WhatsApp | bold, italic | links, images
Telegram | bold, italic, links | images
Facebook | bold, italic | links, images
Instagram | bold, italic | links, images
Line | bold, italic | links, images
SMS | — | everything
Twilio SMS | — | everything
Twitter/X | — | everything


<hr>
<h3>📝 Note</h3>
<blockquote>
<p>Message signatures only support <strong>bold, italic, links, and
images</strong>.<br>
Other formatting options available in the editor (lists, code blocks,
strike-through, etc.) do <strong>not apply</strong> to signatures and
are ignored.</p>
</blockquote>

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

### Loom video
https://www.loom.com/share/d325ab86ca514c6d8f90dfe72a8928dd


## 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>
2025-12-11 19:58:59 +05:30
Muhsin Keloth
2bd8e76886
feat: Add backend changes for whatsapp csat template (#12984)
This PR add the backend changes for the feature [sending CSAT surveys
via WhatsApp message templates
](https://github.com/chatwoot/chatwoot/pull/12787)

---------

Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com>
2025-12-11 16:36:37 +05:30
Aakash Bakhle
1de8d3e56d
feat: legacy features to ruby llm (#12994) 2025-12-11 14:17:28 +05:30
Sivin Varghese
f2054e703a
fix: Handle rich message signatures & attachment overflow (#13045) 2025-12-10 23:13:04 +05:30
Vinay Keerthi
89d02e2c92
fix: Preserve multiple newlines with whitespace in text-based messaging channels (#13044)
## Description

Fixes an issue where multiple newlines with whitespace between them
(e.g., `\n \n \n`) were being collapsed to single newlines in text-based
messaging channels (Telegram, WhatsApp, Instagram, Facebook, Line, SMS).

The frontend was sending messages with spaces/tabs between newlines, and
the markdown renderer was treating these as paragraph content,
collapsing them during rendering.

### Changes:
1. Added whitespace normalization in `render_telegram_html`,
`render_whatsapp`, `render_instagram`, `render_line`, and
`render_plain_text` methods
2. Strips whitespace from whitespace-only lines before markdown
processing
3. Added comprehensive regression tests for all affected channels

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

1. **Unit Tests**: Added 7 new specs testing multiple newlines with
whitespace between them for all text-based channels
2. **Manual Testing**: Verified with actual frontend payload containing
`\n \n \n` patterns
3. **Regression Testing**: All existing 63 specs pass

### Test Results:
-  All 63 markdown renderer specs pass (56 original + 7 new)
-  All 12 Telegram channel specs pass
-  All 27 WhatsApp + Instagram specs pass
-  Verified with real-world payload: 18 newlines preserved (previously
collapsed to 1)

### Test Command:
```bash
RAILS_ENV=test bundle exec rspec spec/services/messages/markdown_renderer_service_spec.rb
RAILS_ENV=test bundle exec rspec spec/models/channel/telegram_spec.rb
```

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective
- [x] New and existing unit tests pass locally with my changes
2025-12-10 21:44:16 +05:30