e84875ca04
850 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fb6fec167b
|
chore: general improvements (#204)
* chore: update scheduled messages author association to nullable and adjust related specs * chore: update sender handling for WhatsApp messages and add external sender name |
||
|
|
f9d1146cb0
|
feat: mensagens agendadas (#198)
* feat: Adds model for scheduling messages * feat: Implement scheduled message handling and processing jobs * feat: Add ScheduledMessagesController and associated specs for managing scheduled messages * refactor: Simplify scheduled message job specs and improve metadata handling * feat: Add ScheduledMessagePolicy for managing access to scheduled messages * feat: Add routes for managing scheduled messages * feat: Add scheduled message event handling and broadcasting * feat: Add JSON views for scheduled messages creation, destruction, updating, and indexing * feat: Update scheduled message status and dispatch update event after message creation * feat: Ensure scheduled message updates trigger dispatch event * feat: Add mutation types for managing scheduled messages * feat: Add additionalAttributes prop to Message component and provider * feat: Implement scheduled message handling in ActionCable and Vuex store * feat: Add unit tests for scheduled messages actions and mutations * feat: implement scheduled messages functionality - Added support for scheduling messages in the conversation dashboard. - Introduced new components: ScheduledMessageModal and ScheduledMessages for managing scheduled messages. - Enhanced ReplyBottomPanel to include scheduling options. - Updated Base.vue to handle scheduled message styling. - Integrated Vuex store module for managing scheduled messages state. - Added necessary translations for scheduled messages in English and Portuguese. * feat: add pagination to scheduled messages index and update tests accordingly * chore: update scheduled messages specs for future time validation and response status * chore: enhance scheduled messages API with pagination and add skeleton loader component * feat: add create_scheduled_message action to automation rule attributes * feat: implement create_scheduled_message action and enhance attachment handling * feat: add scheduled message functionality with UI components and localization * test: enhance scheduledMessages mutations tests with meta handling and structure * chore: update label to display file name upon successful upload in AutomationFileInput component * feat: add initialAttachment prop to ScheduledMessageModal and update ReplyBox to pass attachment * chore: prepend_mod_with to ScheduledMessagesController for better module handling * fix: attachment visibility in ScheduledMessageItem component * chore: enhance ScheduledMessage model with validations and reduce controller load * refactor: simplify ScheduledMessagesAPI methods by removing unnecessary instance variable * chore: update event emission for scheduled message creation in ReplyBox and ScheduledMessageModal * refactor: update status configuration to use label keys * chore: update date formatting in ScheduledMessageItem component * refactor: collapse logic to checkOverflow and update related functionality * chore: add author indication for current user in scheduled messages * chore: enhance scheduled message metadata with author information and localization * fix: send message shortcut * chore: handle errors in scheduled message submission * chore: update scheduled message modal to use combined date and time input * chore: refactor scheduled messages handling to remove pagination and update related tests * fix: ensure scheduled messages update status and dispatch on failure * fix: update scheduled message due date logic and simplify sending checks * refactor: rename build_message method for send_message * fix: update scheduled message creation time and improve test reliability * chore: ignore unnecessary check * chore: add scheduled message metadata handling in message builder, add scheduled message factorie and update specs * refactor: use scheduled message factorie creation in specs * chore: streamline error handling in scheduled message job and remove dispatch logic * fix: change scheduled_messages association to destroy dependent records * refactor: remove unused attributes from scheduled message payload builder * chore: update scheduled message retrieval to use conversation association * chore: correct cron format for scheduled messages job * chore: remove migration for author_type in scheduled_messages * feat: enhance scheduled messages management with delete confirmation and error handling * chore: set cron poll interval to 10 seconds for improved scheduling precision * feat: include additional_attributes in message JSON response * feat: enhance scheduled message validation and localization support * chore: update scheduled message display * Merge branch 'main' into Cayo-Oliveira/CU-86aenh268/Mensagens-agendadas * feat: add scheduled message indicators and validation for message length * fix: remove unnecessary condition from line-clamp class binding * feat: update scheduled messages localization and enhance content validation * feat: update scheduled messages order, enhance scheduledAt computation, and add message association * fix: reorder condition for Facebook channel message length computation * fix: change detection for attachments in scheduled messages * fix: remove unnecessary colon from close-on-backdrop-click prop in ScheduledMessageModal * chore: add error handling for scheduled message deletion and update localization for delete failure * fix: enforce minimum delay of 1 minute for scheduled messages and update validation * fix: remove unused private property and improve locale formatting for scheduled messages * fix: adjust positioning of DropdownBody in ReplyBottomPanel and clean up schema foreign keys * docs: add scheduled messages management APIs and payload definitions --------- Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com> |
||
|
|
0de6001b97
|
feat: add message editing functionality with UI support (#195)
* feat: add message editing functionality with UI support * feat: enhance message editing with content length validation and context menu adjustments |
||
|
|
77c90a69ca
|
feat(whatsapp): delete messages on baileys/zapi providers (#194)
* feat(baileys): implement message deletion functionality * feat(zapi): add message deletion functionality and corresponding tests * feat(whatsapp): update message deletion logic for provider compatibility * feat(whatsapp): enhance message deletion logic to handle missing phone numbers |
||
|
|
6ab1898992 | Merge branch 'main' into chore/merge-upstream-4.10 | ||
|
|
d451615811
|
fix: prevent NoMethodError in mute helpers when contact is nil (#13277)
## Linear Ticket https://linear.app/chatwoot/issue/CW-4569/nomethoderror-undefined-method-blocked-for-nil-nomethoderror ## Description Fixes NoMethodError in ConversationMuteHelpers that occurs during contact deletion race condition. When a contact is deleted, there's a brief window (~50-150ms) where contact_id becomes nil but conversations still exist. If ResolutionJob runs during this window, the muted? method crashes trying to call blocked? on nil.Fixes # (issue) ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Created orphaned conversations (contact_id = nil) - Called muted?, mute!, unmute! - all return gracefully - Verified async deletion still works correctly ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] 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 - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Co-authored-by: Sojan Jose <sojan@pepalo.com> |
||
|
|
a8b302d4cd
|
feat(ee): Review Notes for CSAT Reports (#13289)
CSAT scores are helpful, but on their own they rarely tell the full story. A drop in rating can come from delayed timelines, unclear expectations, or simple misunderstandings, even when the issue itself was handled correctly. Review Notes for CSAT let admins/report manager roles add internal-only context next to each CSAT response. This makes it easier to interpret scores properly and focus on patterns and root causes, not just numbers. <img width="2170" height="1680" alt="image" src="https://github.com/user-attachments/assets/56df7fab-d0a7-4a94-95b9-e4c459ad33d5" /> ### Why this matters * Capture the real context behind individual CSAT ratings * Clarify whether a low score points to a genuine service issue or a process gap * Spot recurring themes across conversations and teams * Make CSAT reviews more useful for leadership reviews and retrospectives ### How Review Notes work **View CSAT responses** Open the CSAT report to see overall metrics, rating distribution, and individual responses. **Add a Review Note** For any CSAT entry, managers can add a Review Note directly below the customer’s feedback. **Document internal insights** Use Review Notes to capture things like: * Why a score was lower or higher than expected * Patterns you are seeing across similar cases * Observations around communication, timelines, or customer expectations Review Notes are visible only to administrators and people with report access only. We may expand visibility to agents in the future based on feedback. However, customers never see them. Each note clearly shows who added it and when, making it easy to review context and changes over time. |
||
|
|
ee7187d2ed
|
fix: prevent deserialization error on deletion (#13264) | ||
|
|
c483034a07
|
feat: Add support for sending CSAT surveys via templates (Whatsapp Twilio) (#13143)
Fixes https://linear.app/chatwoot/issue/CW-6189/support-for-sending-csat-surveys-via-approved-whatsapp --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com> Co-authored-by: iamsivin <iamsivin@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
34b42a1ce1
|
feat: add global config for captain settings (#13141)
Co-authored-by: aakashb95 <aakashbakhle@gmail.com> Co-authored-by: Aakash Bakhle <48802744+aakashb95@users.noreply.github.com> |
||
|
|
d526cf283d
|
fix: pass serialized data in notification.deleted event to avoid Deserialisation (#13061)
https://one.newrelic.com/alerts/issue?account=3437125&duration=259200000&state=d088e9b7-d0ce-3fcf-fda5-145df8b9cb2a ## Description Pass serialized data instead of ActiveRecord object in dispatch_destroy_event to prevent ActiveJob::DeserializationError when the notification is already deleted. This error occurs frequently because RemoveDuplicateNotificationJob deletes notifications, and by the time the async EventDispatcherJob runs, the record no longer exists. ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] 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 - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Avoids ActiveJob deserialization failures by sending serialized data for notification deletion and updating the listener accordingly. > > - `Notification#dispatch_destroy_event` now dispatches `NOTIFICATION_DELETED` with serialized `notification_data` (`id`, `user_id`, `account_id`) instead of the AR object > - `ActionCableListener#notification_deleted` reads `notification_data`, finds `User`/`Account`, computes `unread_count`/`count` via `NotificationFinder`, and broadcasts using the user’s pubsub token > - Specs updated to pass `notification_data` and assert payload (including `unread_count`/`count`) > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e2ffbe765b148fdfd2cd2e031c657c36e423c1f5. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com> |
||
|
|
7ba7bf842e
|
fix: Use SignedId instead of regular ID in portal update (#13197)
The Active Storage blob ids were handled inconsistently across the API. - When a new logo was uploaded, the upload controller returned a signed_id - When loading an existing portal that already had a logo, the portal model returned a blob_id. This caused the API portal API to fail. There are about 107 instances of this in production, so this change will fix that. |
||
|
|
566de02385
|
feat: allow agent bot and captain responses to reset waiting since (#13181)
When AgentBot responds to customer messages, the `waiting_since`
timestamp is not reset, causing inflated reply time metrics when a human
agent eventually responds. This results in inaccurate reporting that
incorrectly includes periods when customers were satisfied with bot
responses.
### Timeline from Production Data
```
Dec 12, 16:20:14 - Customer sends message (ID: 368451924)
↓ waiting_since = Dec 12, 16:20:14
Dec 12, 16:20:17 - AgentBot replies (ID: 368451960)
↓ waiting_since STILL = Dec 12, 16:20:14 ❌
↓ (Bot response doesn't clear it)
14-day gap - Customer satisfied, no messages
↓ waiting_since STILL = Dec 12, 16:20:14 ❌
Dec 26, 22:25:45 - Customer sends new message (ID: 383522275)
↓ waiting_since STILL = Dec 12, 16:20:14 ❌
↓ (New message doesn't reset it)
Dec 26-27 - More AgentBot interactions
↓ waiting_since STILL = Dec 12, 16:20:14 ❌
Dec 27, 07:36:53 - Human agent finally replies (ID: 383799517)
↓ Reply time calculated: 1,268,404 seconds
↓ = 14.7 DAYS ❌
```
## Root Cause
The core issues is in `app/models/message.rb`, where **AgentBot messages
does not clear `waiting_since`** - The `human_response?` method only
returns true for `User` senders, so bot replies never trigger the
clearing logic. This means once `waiting_since` is set, it stays set
even when customers send new messages after receiving bot responses.
The solution is to simply reset `waiting_since` **after a bot has
responded**. This ensures reply time metrics reflect actual human agent
response times, not bot-handled periods.
### What triggers the rest
This is an intentional "gotcha", that only `AgentBot` and
`Captain::Assistant` messages trigger the waiting time reset. Automation
and campaign messages maintain current behavior (no reset). This is
because interactive bot assistants provide conversational help that
might satisfy customers. Automation and campaigns are one-way
communications and shouldn't affect waiting time calculations.
## Related Work
Extends PR #11787 which fixed `waiting_since` clearing on conversation
resolution. This PR addresses the bot interaction scenario which was not
covered by that fix.
Scripts to clean data:
https://gist.github.com/scmmishra/bd133208e219d0ab52fbfdf03036c48a
|
||
|
|
e58600d1b9
|
fix: the webhook url to be text (#13157)
## Description Change the url type from string to text, to support more than 255 characters Fixes # (issue) https://app.chatwoot.com/app/accounts/1/conversations/65240 ## Type of change Please delete options that are not relevant. - [ ] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] 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 - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |
||
|
|
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 |
||
|
|
544aeaa5a0
|
fix: annotaterb (#173)
* fix: annotaterb * fix: ensure Hash values are accessed with indifferent access in SerializedValueCoder Also include missing annotaterb options |
||
|
|
549214e96d | Merge branch main into chore/merge-upstream | ||
|
|
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> |
||
|
|
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> |
||
|
|
1de8d3e56d
|
feat: legacy features to ruby llm (#12994) | ||
|
|
aa21c15d0e
|
fix: hide linear card when not enabled (#12918)
The Linear card now only appears in conversation sidebar when: - The linear_integration feature flag is enabled for the account - LINEAR_CLIENT_ID is configured (inferred from the integration existing in the store) This matches the backend behavior: if LINEAR_CLIENT_ID is not set, the integration is filtered out of the API response, so it won't exist in the store. In addition, I discovered that Settings/Integrations page showed Linear card even if it was disabled but Linear client_id set. Now the Linear card shows only if both conditions are met. Fixes #12909 ## How Has This Been Tested? #### Before https://github.com/user-attachments/assets/cd21b881-5332-48f8-b230-662abc256ba2 #### After https://github.com/user-attachments/assets/d794cc2e-19d6-4545-b2ef-3af054c2ac81 --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> |
||
|
|
399c91adaa
|
feat: Standardize rich editor across all channels (#12600)
# 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> |
||
|
|
5c3b85334b
|
feat: Add support for shared post and story attachment types in Instagram messages (#12997)
When users share Instagram posts or stories via DM, Instagram sends webhooks with type `ig_post` and `ig_story` attachments. The system was failing on these types because they weren't defined in the file_types. This PR fixes the issue by handling all shared types and rendering them on the front end. **Shared post** <img width="2154" height="1828" alt="CleanShot 2025-12-03 at 16 29 14@2x" src="https://github.com/user-attachments/assets/7e731171-4904-43a6-abeb-b1db2c262742" /> **Shared status** <img width="1702" height="1676" alt="CleanShot 2025-12-03 at 16 10 25@2x" src="https://github.com/user-attachments/assets/6a151233-ce47-429d-b7c2-061514b20e05" /> Fixes https://linear.app/chatwoot/issue/CW-5441/argumenterror-ig-story-is-not-a-valid-file-type-argumenterror |
||
|
|
e6a7e836a0
|
fix: Add support for ig_post attachment type in Instagram messages (#12992)
Fixes https://linear.app/chatwoot/issue/CW-6055/argumenterror-ig-post-is-not-a-valid-file-type-argumenterror This PR fixes an issue where Instagram sends webhooks with both "type": "share" and "type": "ig_post" attachments when users share Instagram posts in direct messages. The system was failing on the ig_post type because it wasn't defined, causing ArgumentError exceptions. https://github.com/user-attachments/assets/577b8ebd-80e3-4c11-95f5-d8a8c3e16534 |
||
|
|
f1079574e3
|
fix: Disable SSL verification for LINE webhooks in development (#12960)
## Summary - Fixes SSL certificate verification errors when testing LINE webhooks in development environments - Configures the LINE Bot API client to skip SSL verification only in development mode ## Background When testing LINE webhooks locally on macOS, the LINE Bot SDK was failing with: ``` OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get certificate CRL) ``` This occurs because the LINE Bot SDK tries to fetch user profiles via HTTPS, and OpenSSL on macOS development environments may not have proper access to Certificate Revocation Lists (CRLs). ## Changes - Added `http_options` configuration to the LINE Bot client in `Channel::Line#client` - Sets `verify_mode: OpenSSL::SSL::VERIFY_NONE` only when `Rails.env.development?` is true - Production environments continue to use full SSL verification for security ## Test Plan - [x] Send a LINE message to trigger webhook in development - [x] Verify webhook is processed without SSL errors - [x] Confirm change only applies in development mode Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> |
||
|
|
e635122ff6
|
fix: add presence validation for account name (#12636)
## Description When a user tries creating a new account through the Super Admin dashboard, and they forget to fill in the account name, they're faced with an ugly error (generic "Something went wrong" on production). This PR simply adds the `validates :name, presence: true` model validation on `Account` model, which is translated as a proper error message on the Super Admin UI. |
||
|
|
9a2136caf1
|
fix: Change messages.source_id to text column (#12908)
## Summary Changes `messages.source_id` from `string` (255 char limit) to `text` (20,000 char limit) to support long email Message-ID headers. ## Changes - Migration to change column type from string to text - Added spec tests for source_id length validation ## Related Fixes https://linear.app/chatwoot/issue/CW-5961/activerecordrecordinvalid-validation-failed-source-is-too-long-maximum |
||
|
|
b03dfdb751
|
Chore/merge upstream 4.8.0 (#150)
* chore: Hide "Learn More" button in feature spotlight for self-hosted (#12675) * feat: single query for reporting event stats (#12664) This PR collapses multiple queries fetching stats from a single table to a single query ```sql SELECT user_id as user_id, COUNT(CASE WHEN name = 'conversation_resolved' THEN 1 END) as resolved_count, AVG(CASE WHEN name = 'conversation_resolved' THEN value END) as avg_resolution_time, AVG(CASE WHEN name = 'first_response' THEN value END) as avg_first_response_time, AVG(CASE WHEN name = 'reply_time' THEN value END) as avg_reply_time FROM "reporting_events" WHERE "reporting_events"."account_id" = <account_id> AND "reporting_events"."created_at" >= '2025-09-14 18:30:00' AND "reporting_events"."created_at" < '2025-10-14 18:29:59' GROUP BY "reporting_events"."user_id"; ``` ### Why this works? Here's why this optimization is faster based on PostgreSQL internals: - Single Table Scan vs Multiple Scans: Earlier we did 4 sequential scans (or 4 index scans) of the same data, with the same where clause, now in a single scan all 4 `CASE` expressions are evaluated in a single pass. - Shared Buffer Cache Efficiency: PostgreSQL's shared buffer cache stores recently accessed pages, with this, pages are loaded once and re-used for all aggregation, earlier with separate queries we were forced to re-read all from the disk each time - Reduced planning and network overhead (4 vs 1 query) ### How is it tested 1. The specs all pass without making any changes 2. Verified the reports side by side after generating from report seeder #### How to test Generate seed data using the following command ```bash ACCOUNT_ID=1 ENABLE_ACCOUNT_SEEDING=true bundle exec rake db:seed:reports_data ``` Once done download the reports, checkout to this branch and download the reports again and compare them * chore: Update translations (#12625) * chore: Migrate mailers from the worker to jobs (#12331) Previously, email replies were handled inside workers. There was no execution logs. This meant if emails silently failed (as reported by a customer), we had no way to trace where the issue happened, the only assumption was “no error = mail sent.” By moving email handling into jobs, we now have proper execution logs for each attempt. This makes it easier to debug delivery issues and would have better visibility when investigating customer reports. Fixes https://linear.app/chatwoot/issue/CW-5538/emails-are-not-sentdelivered-to-the-contact --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> * chore(deps-dev): bump vite from 5.4.20 to 5.4.21 (#12700) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.20 to 5.4.21. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/releases">vite's releases</a>.</em></p> <blockquote> <h2>v5.4.21</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v5.4.21/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/blob/v5.4.21/packages/vite/CHANGELOG.md">vite's changelog</a>.</em></p> <blockquote> <h2><!-- raw HTML omitted -->5.4.21 (2025-10-20)<!-- raw HTML omitted --></h2> <ul> <li>fix(dev): trim trailing slash before <code>server.fs.deny</code> check (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20968">#20968</a>) (<a href="https://github.com/vitejs/vite/tree/HEAD/packages/vite/issues/20970">#20970</a>) (<a href=" |
||
|
|
7f0748460e
|
feat: dashboard apps on sidebar (#146)
* feat: dashboard apps on sidebar * fix: handle dashboard app not found * chore: minor refactoring |
||
|
|
5f2b2f4221
|
feat: APIs to assign agents_bots as assignee in conversations (#12836)
## Summary - add an assignee_agent_bot_id column as an initital step to prototype this before fully switching to polymorphic assignee - update assignment APIs and conversation list / show endpoints to reflect assignee as agent bot - ensure webhook payloads contains agent bot assignee [Codex Task](https://chatgpt.com/codex/tasks/task_e_6912833377e48326b6641b9eee32d50f) --------- Co-authored-by: Pranav <pranav@chatwoot.com> |
||
|
|
77f492590e
|
feat: Control the allowed login methods via Super Admin (#12892)
- Control the allowed authentication methods for a chatwoot installation via super admin configs. [SAML, Google Auth etc] ------ [Codex Task](https://chatgpt.com/codex/tasks/task_e_6917d503b6e48326a261672c1de91462) --------- Co-authored-by: Pranav <pranav@chatwoot.com> Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> |
||
|
|
bf806f0c28
|
feat: allow configuring attachment upload limit (#12835)
## Summary - add a configurable MAXIMUM_FILE_UPLOAD_SIZE installation setting and surface it through super admin and global config payloads - apply the configurable limit to attachment validations and shared upload helpers on dashboard and widget - introduce a reusable helper with unit tests for parsing the limit and extend attachment specs for configurability ------ [Codex Task](https://chatgpt.com/codex/tasks/task_e_6912644786b08326bc8dee9401af6d0a) --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: iamsivin <iamsivin@gmail.com> |
||
|
|
93374f4327
|
fix: Change contact_inboxes.source_id to text column (#12882)
## Description Fixes CW-5961 where IMAP email processing failed with `ActiveRecord::RecordInvalid: Validation failed: Source is too long (maximum is 255 characters)` error. This changes the `contact_inboxes.source_id` column from `string` (255 character limit) to `text` (unlimited) to accommodate long email message IDs that were causing validation failures. Fixes CW-5961 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Added spec test validating `source_id` values longer than 255 characters (300 chars) - All existing `contact_inbox_spec.rb` tests pass (7 examples, 0 failures) - Migration applied successfully with reversible up/down methods - Verified `source_id` column type changed to `text` with `null: false` constraint preserved ## 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 or that my feature works - [x] New and existing unit tests pass locally with my changes |
||
|
|
c9823d9409
|
feat: Assignment service (v2) (#12320)
## Linear Link ## Description This PR introduces a new robust auto-assignment system for conversations in Chatwoot. The system replaces the existing round-robin assignment with a more sophisticated service-based architecture that supports multiple assignment strategies, rate limiting, and Enterprise features like capacity-based assignment and balanced distribution. ## Type of change - [ ] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? - Unit test cases - Test conversations getting assigned on status change to open - Test the job directly via rails console ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] 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 - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds a new service-based auto-assignment system with scheduled jobs, rate limiting, enterprise capacity/balanced selection, and wiring via inbox/handler; includes Redis helpers and comprehensive tests. > > - **Auto-assignment v2 (core services)**: > - Add `AutoAssignment::AssignmentService` with bulk assignment, configurable conversation priority, RR selection, and per-agent rate limiting via `AutoAssignment::RateLimiter`. > - Add `AutoAssignment::RoundRobinSelector` for agent selection. > - **Jobs & scheduling**: > - Add `AutoAssignment::AssignmentJob` (per-inbox bulk assign; env-based limit) and `AutoAssignment::PeriodicAssignmentJob` (batch over accounts/inboxes). > - Schedule periodic run in `config/schedule.yml` (`periodic_assignment_job`). > - **Model/concerns wiring**: > - Include `InboxAgentAvailability` in `Inbox`; add `Inbox#auto_assignment_v2_enabled?`. > - Update `AutoAssignmentHandler` to trigger v2 job when `auto_assignment_v2_enabled?`, else fallback to legacy. > - **Enterprise extensions**: > - Add `Enterprise::InboxAgentAvailability` (capacity-aware filtering) and `Enterprise::Concerns::Inbox` association `inbox_capacity_limits`. > - Extend service via `Enterprise::AutoAssignment::AssignmentService` (policy-driven config, capacity filtering, exclusion rules) and add selectors/services: `BalancedSelector`, `CapacityService`. > - **Infrastructure**: > - Enhance `Redis::Alfred` with `expire`, key scan/count, and extended ZSET helpers (`zadd`, `zcount`, `zcard`, `zrangebyscore`). > - **Tests**: > - Add specs for jobs, core service, rate limiter, RR selector, and enterprise features (capacity, balanced selection, exclusions). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0ebe187c8aea73765b0122a44b18d6f465c2477f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> |
||
|
|
c041090675
|
feat(baileys): upgrade to v7 (#143)
* feat(baileys): upgrade to v7 (#139) * feat(baileys): v7 * chore(zapi): match baileys changes * test: fix send on whatsapp spec * chore: simplify logic and minor fixes * fix: ensure contact avatar updates when profile picture changes * chore: add beta release workflow * feat: enhance contact update logic to handle conflicts in inbox updates (#140) * feat: update GitHub Actions workflow to trigger on release events and adjust GIT_REF handling * fix: prevent unique constraint error when LID contact inbox already exists (#141) * fix: prevent unique constraint error when LID contact inbox already exists * feat(baileys): handle ephemeral messages |
||
|
|
bdcb1934c0
|
feat(webhooks): add name to webhook (#12641)
## Description When working with webhooks, it's easy to lose track of which URL is which. Adding a `name` (optional) column to the webhook model is a straight-forward solution to make it significantly easier to identify webhooks. ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? Model and controller specs, and also running in production over several months without any issues. | Before | After | | --- | --- | | <img width="949" height="990" alt="image copy 3" src="https://github.com/user-attachments/assets/6b33c072-7d16-4a9c-a129-f9c0751299f5" /> | <img width="806" height="941" alt="image" src="https://github.com/user-attachments/assets/77f3cb3a-2eb0-41ac-95bf-d02915589690" /> | | <img width="1231" height="650" alt="image copy 2" src="https://github.com/user-attachments/assets/583374af-96e0-4436-b026-4ce79b7f9321" /> | <img width="1252" height="650" alt="image copy" src="https://github.com/user-attachments/assets/aa81fb31-fd18-4e21-a40e-d8ab0dc76b4e" /> | ## 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 - [x] 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 |
||
|
|
4f09c2203c
|
feat: allow querying reporting events via the API (#12832) | ||
|
|
ec6c3b3571
|
feat: allow bots to handle campaigns when sender_id is nil (#12805) | ||
|
|
d9b840f161
|
fix: Optimize Message search_data to prevent OpenSearch field explosion (#12786)
## Description
Refactored the `Message#search_data` method to prevent exceeding
OpenSearch's 1000 field limit during reindex operations.
**Problem:** The previous implementation serialized entire ActiveRecord
objects (Inbox, Sender, Conversation) with all their JSONB fields,
causing dynamic field explosion in OpenSearch. This resulted in
`Searchkick::ImportError` with "Limit of total fields [1000] has been
exceeded".
**Solution:** Whitelisted only necessary fields for search and
filtering, and flattened JSONB `custom_attributes` into key-value pair
arrays to prevent unbounded field creation.
Linked to: CW-5861
## 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)
- [x] This change requires a documentation update
## How Has This Been Tested?
- Verified rubocop passes with no offenses
- Code review of search field usage from
`enterprise/app/services/enterprise/search_service.rb`
- Analyzed actual search queries to determine required indexed fields
**Still needed:**
- Full reindex test on staging/production environment
- Verify search functionality still works after reindex
- Confirm field count is under 1000 limit
## Changes Made
### Before
- Indexed 1000+ fields (entire AR objects with JSONB)
- `inbox` = full Inbox object (23+ fields + JSONB)
- `sender` = full Contact/User/AgentBot object (10+ fields + JSONB)
- `conversation` = full push_event_data
- Dynamic JSONB keys creating unlimited fields
### After
- ~35-40 controlled fields
- Whitelisted search fields: `content`, `attachment_transcribed_text`,
`email_subject`
- Filter fields: `account_id`, `inbox_id`, `conversation_id`,
`sender_id`, `sender_type`, etc.
- Flattened `custom_attributes`: `[{key, value, value_type}]` format
- Helper methods: `search_conversation_data`, `search_inbox_data`,
`search_sender_data`, `search_additional_data`
## 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
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
## Post-merge Steps
After merging, the following steps are required:
1. **Reindex all messages:**
```bash
bundle exec rails runner "Message.reindex"
```
2. **Verify field count:**
```bash
bundle exec rails runner "
client = Searchkick.client
index_name = Message.searchkick_index.name
mapping = client.indices.get_mapping(index: index_name)
fields = mapping.dig(index_name, 'mappings', 'properties')
puts 'Total fields: ' + fields.keys.count.to_s
"
```
3. **Test search functionality** to ensure queries still work as
expected
---------
Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
|
||
|
|
c234023a4a
|
feat(zapi): handle contact messages and ignore notifications (#124)
* chore: skip notification messages * feat: contact card messages * fix: notification message handling * chore: reduce code duplication * fix: improve contact name handling in attachment * chore(zapi): promo banner with affiliate link (#126) * chore(zapi): promo banner with affiliate link * chore: remove useless comment * chore(zapi): add note about hardcoded affiliate link * feat: provider.event_received for raw provider events (#127) * chore(zapi): promo banner with affiliate link * chore: remove useless comment * feat: provider.event_received for raw provider events * feat: add provider_event_received handling in webhook listener * feat(baileys): use senderLid as contact identifier (#128) * chore(zapi): promo banner with affiliate link * chore: remove useless comment * feat: provider.event_received for raw provider events * feat(baileys): use senderLid as contact identifier * fix: simplify webhook_data method by removing unnecessary fields |
||
|
|
f12b77c550
|
fix(instagram): include identifier in contact attributes for contact inbox creation (#125) | ||
|
|
254d5dcf9a
|
chore: Migrate mailers from the worker to jobs (#12331)
Previously, email replies were handled inside workers. There was no execution logs. This meant if emails silently failed (as reported by a customer), we had no way to trace where the issue happened, the only assumption was “no error = mail sent.” By moving email handling into jobs, we now have proper execution logs for each attempt. This makes it easier to debug delivery issues and would have better visibility when investigating customer reports. Fixes https://linear.app/chatwoot/issue/CW-5538/emails-are-not-sentdelivered-to-the-contact --------- Co-authored-by: Sojan Jose <sojan@pepalo.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> |
||
|
|
8d4a6b856a | Merge branch main into chore/merge-upstream-4.7.0 | ||
|
|
4fc80ba4ee
|
feat(zapi): Z-API integration (#115)
* feat(zapi): connect flow and UI updates * fix(zapi): re-add manage connection section * feat(zapi): reply * feat: send message * fix: qrcode job logic * test: qr code job specs * chore: concurrent index * chore: whatsapp model minor * test: message window service specs * chore: service refactor * test: zapi service * chore: zapi beta * chore: minor fixes * test: incoming message specs * chore: minor fixes * feat: handle status transitions * test: refactor spec * test: refactor spec * chore(z-api): use feature flag * chore: fix migration name |
||
|
|
9cd3edb497
|
fix: revert Twilio message creation using create! instead of create (#118) | ||
|
|
38f16ba677
|
feat: Secure external credentials with database encryption (#12648)
## Changelog
- Added conditional Active Record encryption to every external
credential we store (SMTP/IMAP passwords, Twilio tokens,
Slack/OpenAI hook tokens, Facebook/Instagram tokens, LINE/Telegram keys,
Twitter secrets) so new writes are encrypted
whenever Chatwoot.encryption_configured? is true; legacy installs still
receive plaintext until their secrets are
updated.
- Tuned encryption settings in config/application.rb to allow legacy
reads (support_unencrypted_data) and to extend
deterministic queries so lookups continue to match plaintext rows during
the rollout; added TODOs to retire the
fallback once encryption becomes mandatory.
- Introduced an MFA-pipeline test suite
(spec/models/external_credentials_encryption_spec.rb) plus shared
examples to
verify each attribute encrypts at rest and that plaintext records
re-encrypt on update, with a dedicated Telegram case.
The existing MFA GitHub workflow now runs these tests using the
preconfigured encryption keys.
fixes:
https://linear.app/chatwoot/issue/CW-5453/encrypt-sensitive-credentials-stored-in-plain-text-in-database
## Testing Instructions
1. Instance without encryption keys
- Unset ACTIVE_RECORD_ENCRYPTION_* vars (or run in an environment where
they’re absent).
- Create at least one credentialed channel (e.g., Email SMTP).
- Confirm workflows still function (send/receive mail or a similar
sanity check).
- In the DB you should still see plaintext values—this confirms the
guard prevents encryption when keys are missing.
2. Instance with encryption keys
- Configure the three encryption env vars and restart.
- Pick a couple of representative integrations (e.g., Email SMTP +
Twilio SMS).
- Legacy channel check:
- Use existing records created before enabling keys. Trigger their
workflow (send an email / SMS, or hit the
webhook) to ensure they still authenticate.
- Inspect the raw column—value remains plaintext until changed.
- Update legacy channel:
- Edit one legacy channel’s credential (e.g., change SMTP password).
- Verify the operation still works and the stored value is now encrypted
(raw column differs, accessor returns
original).
- New channel creation:
- Create a new channel of the same type; confirm functionality and that
the stored credential is encrypted from
the start.
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
|
||
|
|
96d1003548
|
feat: add presence validation for account name (#117) | ||
|
|
7c5bb343c6
|
fix: Optimize message reindexing to reduce sidekiq job creation (#12618)
Changes searchkick callback behavior to check `should_index?` before creating reindex jobs, preventing unnecessary job creation for messages that don't need indexing (activity messages, unpaid accounts, etc.). Previously, `callbacks: :async` created reindex jobs for all messages (~5,100/min or 7.3M/day in production), which were then filtered by `should_index?` inside the job worker - resulting in 98% wasted jobs, Redis memory pressure, and avoidable p0 alerts. Now, `should_index?` is checked before job creation via `after_commit` callback, reducing job creation to actual incoming/outgoing messages from paid accounts. Changes: - Disable automatic searchkick callbacks - Add manual `after_commit` callback with `should_index?` condition - Add specs to verify callback behavior Expected impact: - 98% reduction in sidekiq job creation (~7.3M → ~150K jobs/day) - Reduced redis memory usage - Same async indexing behavior for eligible messages |
||
|
|
170ea7691f
|
feat: Add company model and API with tests (#12548)
# Pull Request Template ## Description * add Company model with validations for name, domain, description and avatar * Add database migration fo * Implement endpoints for company CRUD operations * Add optional company relationship for contacts * Add test for models, controllers, factories and policies * Add authorization policies restricting delete to admins * support JSON API responses Please include a summary of the change and issue(s) fixed. Also, mention relevant motivation, context, and any dependencies that this change requires. Fixes #(cw-5650) ## Type of change Please delete options that are not relevant. - [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? Tests are implemented using `RSpec` ``` $ bundle exec rails db:migrate $ bundle exec rspec spec/models/company_spec.rb spec/controllers/api/v1/accounts/companies_controller_spec.rb ``` ## 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 - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules |
||
|
|
606adffeeb
|
fix: I18n::MissingInterpolationArgument for assignee activity messages (#12617)
# Pull Request Template
## Description
This PR fixes the following error:
`I18n::MissingInterpolationArgument: missing interpolation argument
:assignee_name in "Asignado a %{assignee_name} por %{user_name}"
({user_name: "Marketing Telpronet"} given)
(I18n::MissingInterpolationArgument)`
**Issue**
In the Spanish locale, an `I18n::MissingInterpolationArgument` error
occurred during bulk assignee operations.
This happened because `assignee&.name` was returning `nil`, and the
`.compact` method removed the `assignee_name` key entirely from the
params.
<img width="1744" height="164" alt="image"
src="https://github.com/user-attachments/assets/3c15ed77-48c0-4938-a7fd-356bdb07da39"
/>
**Solution**
* Always include the `assignee_name` key with an empty string (`''`)
when its value is `nil`.
* Removed the `.compact` method call to ensure the interpolation key is
always present.
Fixes
https://linear.app/chatwoot/issue/CW-5747/i18nmissinginterpolationargument-missing-interpolation-argument
## 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
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
|