# Creates contact when Instagram returns `No matching Instagram user`
## Description
The error occurs when Facebook tries to validate the Facebook App
created to authorize Instagram integration.
The Facebook's agent uses a Bot to make tests on the App where is not a
valid user via API, returning `{"error"=>{"message"=>"No matching
Instagram user", "type"=>"IGApiException", "code"=>9010}}`.
Then Facebook rejects the request saying this app is still not ready
once the integration with Instagram didn't work.
We can safely create an unknown contact, making this integration work.
## 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?
There's automated test to cover.
## 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
- [ ] 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>
# Pull Request Template
## Description
This PR adds support for WhatsApp campaigns to Chatwoot, allowing
businesses to reach their customers through WhatsApp. The implementation
includes backend support for WhatsApp template messages, frontend UI
components, and integration with the existing campaign system.
Fixes#8465
Fixes https://linear.app/chatwoot/issue/CW-3390/whatsapp-campaigns
## Type of change
- [x] New feature (non-breaking change which adds functionality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] 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?
- Tested WhatsApp campaign creation UI flow
- Verified backend API endpoints for campaign creation
- Tested campaign service integration with WhatsApp templates
- Validated proper filtering of WhatsApp campaigns in the store
## 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
## What we have changed:
We have added support for WhatsApp campaigns as requested in the
discussion.
Ref: https://github.com/orgs/chatwoot/discussions/8465
**Note:** This implementation doesn't exactly match the maintainer's
specification and variable support is missing. This is an initial
implementation that provides the core WhatsApp campaign functionality.
### Changes included:
**Backend:**
- Added `template_params` column to campaigns table (migration + schema)
- Created `Whatsapp::OneoffCampaignService` for WhatsApp campaign
execution
- Updated campaign model to support WhatsApp inbox types
- Added template_params support to campaign controller and API
**Frontend:**
- Added WhatsApp campaign page, dialog, and form components
- Updated campaign store to filter WhatsApp campaigns separately
- Added WhatsApp-specific routes and empty state
- Updated i18n translations for WhatsApp campaigns
- Modified sidebar to include WhatsApp campaigns navigation
This provides a foundation for WhatsApp campaigns that can be extended
with variable support and other enhancements in future iterations.
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
## Description
This PR introduces WhatsApp Embedded Signup functionality, enabling
users to connect their WhatsApp Business accounts through Meta's
streamlined OAuth flow without manual webhook configuration. This
significantly improves the user experience by automating the entire
setup process.
**Key Features:**
- Embedded signup flow using Facebook SDK and Meta's OAuth 2.0
- Automatic webhook registration and phone number configuration
- Enhanced provider selection UI with card-based design
- Real-time progress tracking during signup process
- Comprehensive error handling and user feedback
## Required Configuration
The following environment variables must be configured by administrators
before this feature can be used:
Super Admin Configuration (via
super_admin/app_config?config=whatsapp_embedded)
- `WHATSAPP_APP_ID`: The Facebook App ID for WhatsApp Business API
integration
- `WHATSAPP_CONFIGURATION_ID`: The Configuration ID for WhatsApp
Embedded Signup flow (obtained from Meta Developer Portal)
- `WHATSAPP_APP_SECRET`: The App Secret for WhatsApp Embedded Signup
flow (required for token exchange)

## How Has This Been Tested?
#### Backend Tests (RSpec):
- Authentication validation for embedded signup endpoints
- Authorization code validation and error handling
- Missing business parameter validation
- Proper response format for configuration endpoint
- Unauthorized access prevention
#### Manual Test Cases:
- Complete embedded signup flow (happy path)
- Provider selection UI navigation
- Facebook authentication popup handling
- Error scenarios (cancelled auth, invalid business data, API failures)
- Configuration presence/absence behavior
## Related Screenshots:





Fixes
https://linear.app/chatwoot/issue/CW-2131/spec-for-whatsapp-cloud-channels-sign-in-with-facebook
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Sojan Jose <sojan@pepalo.com>
This PR allows agents to mention entire teams in private messages using
`@team_name` syntax. When a team is mentioned, all team members with
inbox access are automatically notified. The scheme changes can be found
[here](https://github.com/chatwoot/prosemirror-schema/pull/34).
---------
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Sojan Jose <sojan@pepalo.com>
Added conversation_status, assignee_id, team_id, and priority to the
message_created event to allow users to build automations based on
conversation details. Also introduced a new open_conversation action.
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
# Pull Request Template
## Linear task:
https://linear.app/chatwoot/issue/CW-4482/captain-should-be-able-to-access-private-notes-only-on-copilot
## Description
Captain should be able to access private notes (only on copilot)
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## 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
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
# Pull Request Template
## Linear Link
https://linear.app/chatwoot/issue/CW-4480/expose-custom-attributes-in-conversation-to-captain-so-that-it-can
## Description
Expose custom attributes in conversation to Captain so that it can
provide more information
## Type of change
- [ ] New feature (non-breaking change which adds functionality)
## 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
* feat: add received messages handling in WhatsApp services
* feat: ensure received messages are processed in the conversation
* tests: add received messages specs
* tests: add spec for call provider received_messages after save incoming message
* test: add spec to prevent calling received_messages for outgoing messages
* feat: add received_messages to error handling methods
* test: add spec for sending received messages request in WhatsappBaileysService
* fix: update fromMe flag in WhatsappBaileysService
* test: add spec to verify received_messages is not called for protocol messages
* test: improve received_messages stub
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
Added support for Telegram Business bots. Telegram webhooks from such bots include the business_message field, which we transform into a standard message for Chatwoot. This PR also modifies how we handle replies, attachments, and image uploads when working with Telegram Business bots.
demo: https://drive.google.com/file/d/1Yz82wXBVRtb-mxjXogkUju4hlJbt3qyh/view?usp=sharing&t=4Fixes#10181
* fix: fill whatsapp provider url with value from inbox provider config
* chore: compact blank on setup channel provider
* fix: deadlock on `reconnecting` state
This PR adds support for handling Telegram's video_note messages (circular video messages), which are commonly used for short voice-style video replies in messaging.
Fixes: #11503
Co-authored-by: Sojan Jose <sojan@pepalo.com>
# Pull Request Template
## Description
Added input_select message type support for LINE
## Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [X] 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?
add testcase. and test manually by myself
## 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
- [ ] 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: Muhsin Keloth <muhsinkeramam@gmail.com>
* fix: update contact creation in messages.update event spec and remove redundant content update test
* fix: enhance message type detection for document messages and improve content retrieval
* fix: add support for edited messages and improve document message handling
* chore: enhance message filtering logic to ignore specific message types
* test: add support for messages with captions in document messages
* test: add handling for edited messages to prevent contact and message creation
* fix: improve message handling by ignoring specific message types
* fix: add support to ignore context messages to prevent contact and message creation
* refactor: organize incoming baileys specs
…on (#11584)"
This reverts commit b5ebc47637.
# Pull Request Template
## Description
Please include a summary of the change and issue(s) fixed. Also, mention
relevant motivation, context, and any dependencies that this change
requires.
Fixes # (issue)
## Type of change
Please delete options that are not relevant.
- [ ] 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?
Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration.
## 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
* feat: implement connection update handling for Baileys
* feat: add message update handling for Baileys integration
* feat: implement message processing and handling for Baileys integration
* fix: clear message source ID from Redis when contact is not found
* fix: raise error when attachment file is not found during media handling
* refactor: reorganize includes in incoming_message_baileys_service
* feat: add helper methods for message handling in Baileys integration
* feat: include IncomingMessageServiceHelpers in MessagesUpdate module
* refactor: replace IncomingMessageServiceHelpers with BaileysHandlers::Helpers in connection_update, messages_update, and messages_upsert modules
* fix: mark message as unsupported when attachment file is not found
* refactor: remove unnecessary namespace for includes in IncomingMessageBaileysService
* refactor: add private visibility to methods in connection_update, helpers, messages_update, and messages_upsert modules
* refactor: preserve original message in handle_edited_content method
* fix: attachment error handling
* feat: implement conversation creation logic in set_conversation method
* refactor: remove unused error handling for attachment not found in messages update and upsert
* feat: update last seen timestamps in conversation on message status update
* feat: log warning for unsupported message update status in Baileys service
* chore: merge
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
* feat: update message status and last seen timestamps
* test: enhance message status and content update handling in Baileys service tests
* feat: update last seen timestamps in conversation on message update
* chore: simplify status update condition for incoming messages
* feat: optimize last seen timestamp updates in conversation
* chore: improve last seen spec
* feat: update message content handling in content update scenario
Fixes https://github.com/chatwoot/chatwoot/issues/11569
## Problem
On platforms like WhatsApp and Facebook Messenger, customers cannot
reply to messages after 24 hours (or other channel-specific messaging
windows). Despite this limitation, the system continued sending CSAT
surveys to customers outside their messaging window, making it
impossible for them to respond.
## Solution
Added a check for `conversation.can_reply?` in the
`should_send_csat_survey?` method. This leverages the existing
`MessageWindowService` which already handles all channel-specific
messaging window logic.
* fix: correct structure of lastMessages in message content
* fix: update send_message to store external_created_at timestamp with result from request
* fix: filter incoming messages for unread conversation logic
* fix: improve extraction of message timestamp in send_message method
* feat: enhance message timestamp extraction and update logic in send_message method
* refactor: send_message to improve error handling and update external_created_at timestamp
* chore: move message timestamp extraction to helper
* fix: use message timestamp extract on incoming
* fix: update unread_conversation to handle last message correctly for Baileys provider
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
- Automate the deletion of accounts that have requested deletion via
account settings.
- Add a Sidekiq job that runs daily to find accounts that have requested
deletion and have passed the 7-day window.
- This job deletes the account and then soft-deletes users if they do
not belong to any other account.
- This job also sends an email to the Chatwoot instance admin for
compliance purposes.
- The Chatwoot instance admin's email is configurable via the
`CHATWOOT_INSTANCE_ADMIN_EMAIL` global config.
---------
Co-authored-by: Sojan Jose <sojan@pepalo.com>
A while back, we added a UX enhancement that disabled sending the OOO
message when an agent had replied to the conversation in the last 5
minutes.
https://github.com/chatwoot/chatwoot/pull/11073
This would not send a "we will be back" message even if that reply was a
private note. This would break for bots that posted private notes, and
even for agents who need to just add a note and not actually reply to
the email.
* feat: add MESSAGES_UNREAD event and implement unread action in ConversationsController
* feat: rename MESSAGES_UNREAD event to CONVERSATION_UNREAD and update unread action in ConversationsController
* feat: implement send_unread_conversation method and update conversation_unread event handling
* feat: add test for dispatching conversation.unread event in ConversationsController
* feat: add conversation_unread event handling in ChannelListener
* feat: add send_unread_conversation method and corresponding tests in Whatsapp channel
* feat: add logging for nil last_message in send_unread_conversation method
* feat: add send_unread_conversation to error handling methods
* feat: implement send_unread_conversation method with logging for nil last_message
* fix: add nil check and logging for last_message in send_unread_conversation method
* fix: update conversation_unread method to call unread_conversation instead of send_unread_conversation
* refactor: rename send_unread_conversation to unread_conversation and update method implementation
* refactor: rename send_unread_conversation to send_unread_messages and update implementation to handle multiple messages
* refactor: rename send_read_messages to read_messages and send_unread_messages to unread_message for clarity
* refactor: rename send_read_messages to read_messages and send_unread_messages to unread_message for clarity
* refactor: rename send_read_messages to read_messages for consistency
* feat: add get_media method to retrieve media from provider service
* feat: implement media attachment handling and add media_url method
* feat: add includeMedia option to webhook request in WhatsappBaileysService
* feat: add get_media method to error handling in WhatsappBaileysService
* feat: add includeMedia option to webhook request in WhatsappBaileysService spec
* feat: add media_url method to retrieve media URL in WhatsappBaileysService spec
* refactor: remove get_media method from WhatsappBaileysService and Channel::Whatsapp
* refactor: streamline message handling in IncomingMessageBaileysService spec
* chore: add todo comment about includeMedia
* refactor: simplify media download stubbing in IncomingMessageBaileysService spec
* refactor: simplify media download stubbing in IncomingMessageBaileysService spec
* fix: add missing end statements missed in rebase
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
# Pull Request Template
## Description
This PR addresses an issue where users were unable to view images sent
via WhatsApp on Chatwoot due to incorrect Twilio authentication
configuration.
https://app.chatwoot.com/app/accounts/1/conversations/50824
The problem stemmed from how authentication was being handled for Twilio
API requests. The user had configured their inbox using api_key_sid, but
the backend logic used only auth_token, leading to failed
authentication. Further investigation showed that some customers might
input api_secret into the auth_token field unintentionally.
## 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?
- Tested on console with Client(api_key_sid, auth_token, account_sid)
and validated successful authentication for the customer (Twilio channel
ID: 2702).
- Simulated toggling the “Use API Key Authentication” checkbox to ensure
backend behavior matches UI intent
- Verified image rendering by testing with the same image URL that was
previously failing for the user.
## 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
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
- Refactor email validation logic to be a service
- Use the service for both email/pass signup and Google SSO
- fix account email validation during signup
- Use `blocked_domain` setting for both email/pass signup and Google
Sign In [`BLOCKED_DOMAIN` via GlobalConfig]
- add specs for `account_builder`
- add specs for the new service
---------
Co-authored-by: Sojan Jose <sojan@pepalo.com>
Earlier, we were manually checking if a user was an agent and filtering
their conversations based on inboxes. This logic should have been part
of the conversation permissions service.
This PR moves the check to the right place and updates the logic
accordingly.
Other updates:
- Add support for search_conversations service for copilot.
- Use PermissionFilterService in contacts/conversations, conversations,
copilot search_conversations.
---------
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
* feat: enhance message_content_attributes to handle reaction messages
* fix: update external_created_at to use raw message timestamp directly
* fix: update readableTime to use externalCreatedAt if available
* feat: enhance timestamp formatting with localization support for pt-BR
* feat: add note to message_content_attributes about external_created_at timestamp
* fix: add missing newline at end of conversation.json files
* test: add additional cases for messageTimestamp formatting
* chore: remove outdated note about external_created_at in message_content_attributes
* refactor: remove out of scope task changes
* feat: add test for setting external_created_at in content_attributes on new message
* fix: use last_seen_at message query conditions only if present
* test: add SQL execution tests for messages_read with last_seen_at conditions
* fix: ensure SQL notifications are unsubscribed after message read events
* refactor: streamline message query in messages_read method
* test: update messages_read specs to test expected behavior
* refactor: simplify readableTime computation by removing unnecessary externalCreatedAt check
* fix: update readableTime computation to use externalCreatedAt if available
* test: enhance messages_read specs to use a consistent event object
* test: refactor spec for creating message with external_created_at in messages.upsert event
* Refactor incoming message specs for clarity and consistency
- Consolidated raw_message and params definitions using let blocks for better readability.
- Updated tests to directly manipulate raw_message and params within individual examples.
- Ensured consistent naming and structure across different message types.
- Improved assertions to reflect changes in message attributes and expectations.
* refactor: streamline messages.update event handling and improve test clarity
* test: refactor messages.upsert event specs to use a consistent timestamp
* test: enhance reaction message handling in incoming_message_baileys_service_spec
# Pull Request Template
## Description
This PR introduces basic customization options for the CSAT survey:
* **Display Type**: Option to use star ratings instead of emojis.
* **Message Text**: Customize the survey message (up to 200 characters).
* **Survey Rules**: Send surveys based on labels — trigger when a
conversation has or doesn't have a specific label.
Fixes
https://linear.app/chatwoot/document/improve-csat-responses-a61cf30e054e
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
### Loom videos
**Website Channel (Widget)**
https://www.loom.com/share/7f47836cde7940ae9d17b7997d060a18?sid=aad2ad0a-140a-4a09-8829-e01fa2e102c5
**Email Channel (Survey link)**
https://www.loom.com/share/e92f4c4c0f73417ba300a25885e093ce?sid=4bb006f0-1c2a-4352-a232-8bf684e3d757
## 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: Pranav <pranavrajs@gmail.com>
This PR introduces support for optionally exposing more data during LLM
function calls. This will be useful as we expand Copilot’s capabilities.
Changes included:
- Add support for ArticleLlmFormatter
- Add missing specs for ContactLLMFormatter and ArticleLLMFormatter
- Add additional spec for ConversationLLMFormatter based on config
**Issue**
When attempting to send a message to Instagram users who have never
previously messaged the connected Instagram account, we encounter a
"User consent is required to access user profile" error
**Fix**
This PR implements proper error handling for cases where user consent is
required. We can only access a user's profile after they have initiated
contact with the Instagram account
* feat: implement send_read_messages method for WhatsApp channel
* feat: implement messages_read event handling and dispatch for conversations
* feat: enhance messages_read handling to include last_seen_at and conversation context
* feat: update last_seen handling to reference agent_last_seen_at for messages read event
* chore: fix rebase
* feat: update error handling
* feat: update send_read_messages to mark received messages as not sent by the user
* test: controller spec
* test: channel listener
* test: channel and provider
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
### Summary
- Converts conversation auto-resolution duration from days to minutes
for more
granular control
- Updates validation to allow values from 10 minutes (minimum) to 999
days (maximum)
- Implements smart messaging to show appropriate time units in activity
messages
### Changes
- Created migration to convert existing durations from days to minutes
(x1440)
- Updated conversation resolver to use minutes instead of days
- Added dynamic translation key selection based on duration value
- Updated related specs and documentation
- Added support for displaying durations in days, hours, or minutes
based on value
### Test plan
- Verify account validation accepts new minute-based ranges
- Confirm existing account settings are correctly migrated
- Test auto-resolution works properly with minute values
- Ensure proper time unit display in activity messages
---------
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
* fix: handle protocol messages in IncomingMessageBaileysService and ignore it
* fix: ignore protocol messages before create conversation and contact
* feat: add flag to edited messages and content history tracking
* refactor: update message model to use edit_history instead of content_history for tracking edits
* refactor: update message model to track previous content instead of edit history
* test: fix message content update test to correctly track original content
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
* fix: handle protocol messages in IncomingMessageBaileysService and ignore it
* fix: ignore protocol messages before create conversation and contact
* chore: update test description for contact inbox and message creation
* chore: simplify protocol message check in handle_message method
- Added an api endpoint for update message status ( available only for
api inboxes )
- Moved message status management to a service.
- Handles case where read status arrive before delivered
fixes: #10314 , #9962
* fix: return not_found status for missing messages in WhatsApp webhook
* feat: enhance message handling to support image attachments
* chore: Handle incoming whatsapp baileys service attachments and implement specs for images and videos
* fix: add file_content_type method to incoming baileys messages
* chore: specs for stickers, audio and files
* fix: handle media attachment errors
* chore: convert file_content_type to string when attaching media
* fix: add handling for attachment not found error in incoming message service
* chore: refactor file_content_type method and simplify filename method
* chore: update media attachment tests
* feat: baileys unsupported message alert (#27)
* feat: create alert message for unsupported message types
* chore: fail message when try send not supported type in baileys
* chore: add tests for unsupported message handling in Baileys service
* chore: correct spelling
* chore: NIT in spec name
* chore: remove unnecessary message reload in unsupported message type test
* feat: baileys support to send attachments (#28)
* feat: enhance message sending logic with support for attachments and interactive messages
* fix: update message format to use messageContent for text messages
* feat: attachment message sending
* fix: use strict encoding for attachment file download
* chore: streamline message sending logic and remove unused error classes
* chore: remove type from message sending logic
* chore: update message sending specs
* chore: raise MessageNotSentError instead of updating message status to failed
* chore: change baileys contact name preferences (#30)
* refactor: improve contact name handling and extraction from JID
* test: enhance message handling to update contact names based on pushName and verifiedBizName
* chore: update contact name condition to match phone number from JID
* chore: correct method name typo
* chore: correct variable names for phone number consistency in tests
* chore: update message payload structure and improve error handling in send_message
* test: re-add testing for error handling
* feat: enhance contact name handling and add self-message detection
* fix: ensure presence check for verified business name in contact name retrieval
* test: improve specs
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
Co-authored-by: Gabriel Jablonski <gabriel@fazer.ai>
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
Co-authored-by: Gabriel Jablonski <gabriel@fazer.ai>
* fix: try to disconnect baileys before destroy inbox (#29)
* fix: ensure proper disconnection of Baileys provider on channel destruction
* test: add callback tests for disconnecting channel provider in Whatsapp spec
* refactor: simplify condition for disconnecting Baileys provider on channel destruction
* refactor: enhance disconnect_channel_provider specs for Baileys provider
* test: verify channel destruction does not call disconnect_channel_provider
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
Co-authored-by: Gabriel Jablonski <gabriel@fazer.ai>
- Add agent bots management UI in settings with avatar upload
- Enable agent bot configuration for all inbox types
- Implement proper CRUD operations with webhook URL support
- Fix agent bots menu item visibility in settings sidebar
- Remove all CSML-related code and features
- Add migration to convert existing CSML bots to webhook bots
- Simplify agent bot model and services to focus on webhook bots
- Improve UI to differentiate between system bots and account bots
## Video
https://github.com/user-attachments/assets/3f4edbb7-b758-468c-8dd6-a9537b983f7d
---------
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
This PR will handle the Instagram test events. We are using the last
created Instagram channel as the test channel since we don't have any
other channels for testing purposes at the time of Meta approval.
https://github.com/user-attachments/assets/98302b7a-d72c-4950-9660-861a5e08d55f
---------
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
* feat: add message update processing in IncomingMessageBaileysService
* feat: implement message update handling in IncomingMessageBaileysService
* feat: add MessageNotFoundError for handling invalid update messages in IncomingMessageBaileysService
* chore: specs for message.update events and bug fixes
* chore: refactor message update handling in IncomingMessageBaileysService
* chore: nit remove redundant comment
* chore: enhance logging for unsupported message update statuses in IncomingMessageBaileysService and disabled metrics
* chore: message status update logic with transition checks
* chore: update status mapping for PENDING to sent in status_mapper
* chore: update status_mapper comments and fix case statement for status codes
* fix: logging for unsupported message updates in update_message_content method
* test: add specs for unsupported status transitions in messages.update event
* refactor: ensure message status is reloaded before assertion in messages.update event spec
* refactor: status variable in status_mapper method
* refactor: rename status_transition_allowed method to status_transition_allowed?
* refactor: streamline message creation in specs by using let! for setup
* feat: process webhook whatsapp await response (#21)
* feat: enhance WhatsApp webhook processing and error responses handling
* chore: correct spelling of 'WhatsApp' in webhook controller specs
* refactor: rename webhook processing method and improve error handling
* chore: update error handling in WhatsApp controller specs for specific exceptions
* refactor: remove handling for StandardError in WhatsApp controller specs
* refactor: simplify perform_whatsapp_events_job method
* chore: update response status from not_found to bad_request for invalid message
* refactor: update expectations for job processing in WhatsApp controller specs
This PR introduces basic minimum version of **Instagram Business
Login**, making Instagram inbox setup more straightforward by removing
the Facebook Page dependency. This update enhances user experience and
aligns with Meta’s recommended best practices.
Fixes
https://linear.app/chatwoot/issue/CW-3728/instagram-login-how-to-implement-the-changes
## Why Introduce Instagram as a Separate Inbox?
Currently, our Instagram integration requires linking an Instagram
account to a Facebook Page, making setup complex. To simplify this
process, Instagram now offers **Instagram Business Login**, which allows
users to authenticate directly with their Instagram credentials.
The **Instagram API with Instagram Login** enables businesses and
creators to send and receive messages without needing a Facebook Page
connection. While an Instagram Business or Creator account is still
required, this approach provides a more straightforward integration
process.
| **Existing Approach (Facebook Login for Business)** | **New Approach
(Instagram Business Login)** |
| --- | --- |
| Requires linking Instagram to a Facebook Page | No Facebook Page
required |
| Users log in via Facebook credentials | Users log in via Instagram
credentials |
| Configuration is more complex | Simpler setup |
Meta recommends using **Instagram Business Login** as the preferred
authentication method due to its easier configuration and improved
developer experience.
---
## Implementation Plan
The core messaging functionality is already in place, but the transition
to **Instagram Business Login** requires adjustments.
### Changes & Considerations
- **API Adjustments**: The Instagram API uses `graph.instagram`, whereas
Koala (our existing library) interacts with `graph.facebook`. We may
need to modify API calls accordingly.
- **Three Main Modules**:
1. **Instagram Business Login** – Handle authentication flow.
2. **Permissions & Features** – Ensure necessary API scopes are granted.
3. **Webhooks** – Enable real-time message retrieval.

---
## Instagram Login Flow
1. User clicks **"Create Inbox"** for Instagram.
2. App redirects to the [Instagram Authorization
URL](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login#embed-the-business-login-url).
3. After authentication, Instagram returns an authorization code.
5. The app exchanges the code for a **long-lived token** (valid for 60
days).
6. Tokens are refreshed periodically to maintain access.
7. Once completed, the app creates an inbox and redirects to the
Chatwoot dashboard.
---
## How to Test the Instagram Inbox
1. Create a new app on [Meta's Developer
Portal](https://developers.facebook.com/apps/).
2. Select **Business** as the app type and configure it.
3. Add the Instagram product and connect a business account.
4. Copy Instagram app ID and Instagram app secret
5. Add the Instagram app ID and Instagram app secret to your app config
via `{Chatwoot installation
url}/super_admin/app_config?config=instagram`
6. Configure Webhooks:
- Callback URL: `{your_chatwoot_url}/webhooks/instagram`
- Verify Token: `INSTAGRAM_VERIFY_TOKEN`
- Subscribe to `messages`, `messaging_seen`, and `message_reactions`
events.
7. Set up **Instagram Business Login**:
- Redirect URL: `{your_chatwoot_url}/instagram/callback`
8. Test inbox creation via the Chatwoot dashboard.
## Troubleshooting & Common Errors
### Insufficient Developer Role Error
- Ensure the Instagram user is added as a developer:
- **Meta Dashboard → App Roles → Roles → Add People → Enter Instagram
ID**
### API Access Deactivated
- Ensure the **Privacy Policy URL** is valid and correctly set.
### Invalid request: Request parameters are invalid: Invalid
redirect_uri
- Please configure the Frontend URL. The Frontend URL does not match the
authorization URL.
---
## To-Do List
- [x] Basic integration setup completed.
- [x] Enable sending messages via [Messaging
API](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api).
- [x] Implement automatic webhook subscriptions on inbox creation.
- [x] Handle **canceled authorization errors**.
- [x] Handle all the errors
https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/error-codes
- [x] Dynamically fetch **account IDs** instead of hardcoding them.
- [x] Prevent duplicate Instagram channel creation for the same account.
- [x] Use **Global Config** instead of environment variables.
- [x] Explore **Human Agent feature** for message handling.
- [x] Write and refine **test cases** for all scenarios.
- [x] Implement **token refresh mechanism** (tokens expire after 60
days).
Fixes https://github.com/chatwoot/chatwoot/issues/10440
---------
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
* fix: resolve bug for contact name when user stats a new conversation with a new contact
* chore: update specs to cover the bug resolution
* chore: correct variable name
* chore: simplify update contact name handling
* chore: ensure pushName is always a string and leave a comment to keep an eye if always pushName will be present
* fix: update contact name access
* chore: identify and permit only direct users jid types (#14)
* fix: add jid_type method to classify message sender types and prevent processing for non-user jids
* chore: update jid parsing to correctly extract phone number and improve message type detection
* chore: add spec to ensure no conversation is created for non-user messages
* chore: update jid shape comment
* chore: refactor jid_type method
* chore: update message_type logic for classify text messages when is a extendedTextMessage
* refactor: update spec that no conversation is created for non-user messages
* fix: use update! method for contact name update
* chore: add note on distinguishing broadcast and status JIDs in Baileys
* chore: add note on Baileys internal function for JID classification
* feat: baileys provider and placeholder for link device modal
* chore: drop qrcode.vue in favor of just img tag
* chore: update modal props
* feat: setup channel provider connection
* chore: update .env.example with Baileys API default configuration
* feat: add support for Baileys provider in WhatsApp events processing
* chore: rename Baileys API default host variable to DEFAULT_BAILEYS_URL
* feat: add setup and disconnect methods for Baileys channel provider in inboxes controller that will be implemented
* feat: add CHANNEL_CONNECTION_UPDATE event and include it in broadcast data preparation
* refactor: simplify channel retrieval logic in WhatsappEventsJob
* refactor: revert CHANNEL_UPDATE_EVENTS constant from ActionCableBroadcastJob
* feat: add 'baileys' as a provider option in Whatsapp channel model
* feat: add provider_connection field to Whatsapp channel model and migration
* refactor: remove unnecessary CHANNEL_CONNECTION_UPDATE event type
* feat: implement channel provider connection with baileys API
* feat: add inbox association to Whatsapp channel model and update webhook URL handling
* feat: enhance Baileys service to handle webhook multiple event types
* refactor: simplify webhook verification logic in Baileys service
* feat: add setup channel provider call, and refactor some logic
* chore: adapt logic to new API
* refactor: fix typo
* refactor: fix import
* refactor: fix typo
* chore: add fixme comment about race condition
* fix: remove double disconnect call
* feat: implement message processing for incoming WhatsApp messages
* refactor: streamline message type determination and improve readability
* chore: increase cache key granularity
provider connection info might be updated multiple times within 1 second, so updates might be lost due to cache key not being updated. changing cache key to milliseconds solves this
* feat: add `is-loading` to buttons
* feat: update send_message method to use 'to' parameter and improve error handling
* refactor: simplify test setup and update API key in specs
* chore: add setup and disconnect channel provider specs
* test: fix spec after increase cache key granularity
* feat: handle reconnecting state on modal
* style: centered error text
* feat: advanced options on create inbox
* feat: handle new reconnecting on backend
* refactor: update inbox controller specs and leave a FIXME note
* test: add specs for Whatsapp::IncomingMessageBaileysService
* feat: add baileys configuration page
* feat: link device button when disconnected on conversation
* chore: refactor .env.example
* feat: add TODO for unimplemented methods in IncomingMessageBaileysService
* fix: correct method name and update environment variable references in WhatsappBaileysService
* refactor: simplify channel lookup by removing redundant method and handling phone number check directly
* chore: add TODO for unimplemented event processing methods in IncomingMessageBaileysService
* fix: update environment variable references in WhatsappBaileysService tests
* chore(webhook): add pt-BR translations
* chore: add pt-br translations
* chore: inboxname component margin
* refactor: inboxname computed prop
* feat: enhance WhatsApp provider connection handling and message processing
* test: inbox controller
* chore: improve baileys connection and messages handling
* test: incoming message service baileys
* refactor: update provider config validation and improve test setup for WhatsApp Baileys service
* fix: ensure only text messages are sent and update message source ID
* fix: create message
* fix: only update message on success
* test: fix broken specs
* chore: raise error on unsupported message content type
* feat: hide provider connection data from non-admins
* fix: update advanced options
* chore: move class definition
* fix: issue with send_message not returning id
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
* chore: lint files
* chore: suppress warning
* chore: disable suggest extensions
* chore: do not stage changes in pre-commit
* chore: remove git add from FE lint and `-a` flag from rubocop on husky
1. Add permission filter service to separate permission filtering logic
from conversation queries
2. Implement hierarchical permissions with cleaner logic:
- conversation_manage gives access to all conversations
- conversation_unassigned_manage gives access to unassigned and user's
conversations
- conversation_participating_manage gives access only to user's
conversations
---------
Co-authored-by: Pranav <pranav@chatwoot.com>
The expected payload on WhatsApp Cloud API is the following.
```json
{
"template": {
"name": "TEMPLATE_NAME",
"language": {
"code": "LANGUAGE_AND_LOCALE_CODE"
},
"components": [
"<NAMED_PARAMETER_INPUT>",
"<POSITIONAL_PARAMETER_INPUT>"
]
}
}
```
Named templates expect a `parameter_name`
```json
{
"type": "body",
"parameters": [
{
"type": "text",
"parameter_name": "customer_name",
"text": "John"
},
{
"type": "text",
"parameter_name": "order_id",
"text": "9128312831"
}
]
}
```
In this PR, we would check if the template is a name template, then we
would send the `parameter_name` as well.
Reference: https://github.com/chatwoot/chatwoot/issues/10886
- Add a job to remove stale contacts and contact_inboxes across all accounts
Stale anonymous contact is defined as
- have no identification (email, phone_number, and identifier are NULL)
- have no conversations
- are older than 30 days
---------
Co-authored-by: Pranav <pranav@chatwoot.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
- Add dynamic importing for routes.
- Added caching for `campaign`, `articles` and `inbox_members` API end
points.
---------
Co-authored-by: Pranav <pranavrajs@gmail.com>
In this PR https://github.com/chatwoot/chatwoot/pull/11139, if there is
an attempt to create a duplication session for the contact in the same
inbox, we will anonymize the old session.
This PR would prevent sending messages to the older sessions. The
support agents will have to create a new conversation to continue
messages with customer.
This PR updates the search implementation to better utilize the GIN
indexes. The option is toggled behind a feature flag for us to test it
internally before making it available publicly
At 5 PM, when business hours officially end, an automatic out-of-office
message is sent to customers. However, this creates a poor experience if
an agent is actively chatting with the customer. This update ensures
that the out-of-office message is only sent if no agent message has been
sent in the last 5 minutes. If the customer reaches out again after 5
minutes, the out-of-office message will be triggered.
This PR adds missing error handlers for the following channels and cases
1. WhatsApp - Generic Handlers for both Cloud and 360Dialog (Deprecated)
2. Instagram - Handler for a case where there is an HTTP error instead
of an `:error` in the 200 response
3. Facebook - Errors from the two sentry issues
([Net::OpenTimeout](https://chatwoot-p3.sentry.io/issues/6164805227) &
[JSON::ParserError](https://chatwoot-p3.sentry.io/issues/5903200786))
4. SMS: Generic handlers for Bandwidth SMS
#### Checklist
- [x] Bandwidth SMS
- [x] Whatsapp Cloud + 360 Dialog
- [x] Twilio SMS
- [x] Line
- [x] Telegram
- [x] Instagram
- [x] Facebook
- [x] GMail
- [x] 365 Mail
- [x] SMTP Mail
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
# Pull Request Template
## Description
This PR adds the ability to see the shared contact name in Telegram
channels.
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
**Loom video**
https://www.loom.com/share/cd318056ad4d44d4a1fc4b5d4ad38d60?sid=26d833ae-ded9-4cf0-9af7-81eecfa37f19
## 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: Shivam Mishra <scm.mymail@gmail.com>
# Pull Request Template
## Description
This PR adds support for displaying shared contacts in a Telegram
channel.
**NB:** Tested with both old and new bubbles.
Multiple numbers for a single contact are not supported at this time,
but multiple contacts are supported.
In the future, we can add support for displaying contact names as well.
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
**Loom video**
https://www.loom.com/share/95efadace3194887bc0663c53e7c08bc?sid=a5c27176-3dd8-456c-80b9-c63dbb89dca1
## 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
- [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
The update ensures proper handling of text updates in photo/video
messages by accounting for the caption attribute in addition to the text
attribute. This change enables consistent processing across both
messages.
Fixes https://github.com/chatwoot/chatwoot/issues/10760
Note: TIL, you can update the video/photo you’ve sent on Telegram, not
just the text. Currently, we’re not handling this. To support it, we
need to parse the payload and update the attachments accordingly. This
could be taken as a followup.
Migration Guide: https://chwt.app/v4/migration
This PR imports all the work related to Captain into the EE codebase. Captain represents the AI-based features in Chatwoot and includes the following key components:
- Assistant: An assistant has a persona, the product it would be trained on. At the moment, the data at which it is trained is from websites. Future integrations on Notion documents, PDF etc. This PR enables connecting an assistant to an inbox. The assistant would run the conversation every time before transferring it to an agent.
- Copilot for Agents: When an agent is supporting a customer, we will be able to offer additional help to lookup some data or fetch information from integrations etc via copilot.
- Conversation FAQ generator: When a conversation is resolved, the Captain integration would identify questions which were not in the knowledge base.
- CRM memory: Learns from the conversations and identifies important information about the contact.
---------
Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This PR addresses an issue where mention_notification was being
overwritten by assigned_conversation_new_message notifications.
Similarly, participating_conversation_new_message was taking priority
over assigned_conversation_new_message.
The fix ensures that additional notifications are not created in these
scenarios by establishing a priority order for notifications as follows:
1. mention_notification
2. assigned_conversation_new_message
3. participating_conversation_new_message
This change maintains consistency and prevents redundant notifications.
----
Note: In the older implementation of notifications in Chatwoot,
notification objects were created only if the user had subscribed to a
specific notification type. With the new inbox_view model, we are
changing this approach to create notification objects in all cases. This
PR updates the services to remove reliance on notification preferences,
simplifying the logic.
----
Caveat: Since we don’t create extra notifications for new messages if a
mention_notification already exists, a user subscribed to
new_message_notification push/email notifications but not to
mention_notification will not receive notifications in these cases.
This commit fixes the issue with Line stickers URLs to prevent certain
images from failing to display. The problem was due to the use of
incorrect URLs. The original URLs pointed to the `iphone` variant, which
failed to load properly in some cases. The fix updates the URLs to use
the `android` variant, ensuring all images are displayed correctly.
### Example:
- Original (failing URL):
`https://stickershop.line-scdn.net/stickershop/v1/sticker/17/iphone/sticker.png`
- Fixed (working URL):
`https://stickershop.line-scdn.net/stickershop/v1/sticker/17/android/sticker.png`
## How Has This Been Tested?
1. Verified the updated URLs by loading multiple Line sticker images to
ensure they display correctly.
2. Tested in both local and production-like environments to confirm the
fix resolves the issue.
3. Reviewed logs to ensure no additional errors are generated related to
Line sticker URLs.
The current task for loading `GeoLite2-City.mmdb` doesn't work for all build types. This PR addresses this and move the task to initializer to ensure consistency across environments.
---------
Co-authored-by: Sojan Jose <sojan@pepalo.com>
Co-authored-by: Sojan Jose <sojan.official@gmail.com>
We received customer reports that attachments in Twilio messages
required page reloads to appear. This issue occurred because in the old
Twilio builder, we saved the message and attachment in two stages. The
new builders follow a streamlined approach, where both are saved in a
single transaction. This update aligns the Twilio channel with the new
builder format and resolves the issue.
### Testing:
Tests cover the attachment cases, ensuring that all original tests pass
with these changes.
Webpush gem throws errors such as `WebPush::ExpiredSubscription`,
`WebPush::InvalidSubscription`, `WebPush::Unauthorized`. We handled only
ExpiredSubscription.
If the SDK threw any other errors, it would pause sending the
notification to all other devices for that user. This change would
update the logic to remove the expired subscription and handle the rest
of the errors gracefully.
Fixes
https://linear.app/chatwoot/issue/CW-3399/webpushinvalidsubscription-host-fcmgoogleapiscom-nethttpnotfound-404
This PR adds the following changes
1. Add `Imap::GoogleFetchEmailService` and
`Google::RefreshOauthTokenService`. The
`Google::RefreshOauthTokenService` uses
`OmniAuth::Strategies::GoogleOauth2` which is already added as a packge
2. Update `Inboxes::FetchImapEmailsJob` to handle Google inboxes
3. Add SMTP settings for Google in `ConversationReplyMailerHelper` to
allow sending emails
## Preview
#### Incoming emails

#### Outgoing email

---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This PR has the following changes
1. Add `AZURE_APP_ID` and `AZURE_APP_SECRET` to installation config
2. Add Microsoft config to `super_admin/features.yml`
3. Replace usage of `ENV.fetch` with `GlobalConfigService.load` for
fetch App ID and Secret
* feat: Update location and country code when the contact create/update
* feat: Update the location and country_code when creating or updating the contact.
* chore: improve comments
* feat: Update the contact_type when the contact created/updated
* chore: add more specs
* chore: code cleanups
* chore: code cleanups
* Update contact_spec.rb
* Update inbox.rb
* Update sync_attributes_spec.rb
* chore: build fixes
* chore: check visitor type before update
* chore: review fixes
* fix: downcase email when finding
* feat: add `from_email` class
* refactor: use `from_email`
* feat: add rule to disallow find_by email directly
* chore: remove redundant test
Since the previous imlpmentation didn't do a case-insentive search, a new user would be created, and the error would be raised at the DB layer. With the new changes, this test case is redundant
* refactor: use from_email
- Added a trait called microsoft_email for the Channel::Email factory.
- Rewrote the logic to make it simple to understand
- Rewrote the specs for readability
Currently, we do not support reactions, ephemeral messages, or the request_welcome event for the WhatsApp channel. However, if this is the first event we receive in Chatwoot (i.e., there is no previous conversation or contact in Chatwoot), it will create a contact and a conversation without any messages. This confuses our customer, as it may appear that Chatwoot has missed some messages. There are multiple cases where this might be the first event we receive in Chatwoot. One quick example is when the user has sent an outbound campaign from another tool and their customers reacted to the message.
Another event like this is request_welcome event. WhatsApp has a concept for welcome messages. You can send an outbound message even though the user has not send a message. You can receive notifications through a webhook whenever a WhatsApp user initiates a chat with you for the first time. (Read the Welcome message section: https://developers.facebook.com/docs/whatsapp/cloud-api/phone-numbers/conversational-components/ ). Although this can help the business send a pro-active message to the user, we don't have it scoped in our feature set. For now, I'm ignoring this event.
Fixes https://linear.app/chatwoot/issue/CW-3018/whatsapp-handle-request-welcome-case-properly
Fixes https://linear.app/chatwoot/issue/CW-3017/whatsapp-handle-reactions-properly
In rare cases, the API call to Telegram for the file path fails. We were logging the error in sentry, switching to logs instead.
Co-authored-by: Sojan <sojan@pepalo.com>
In the previous release, we enabled "HTTP Basic Authentication" to secure all attachments requiring HTTP authentication. This is particularly important for media files that may contain sensitive data, as recommended by Twilio. However, some users experienced issues because they did not enable this option despite our alerts prompting them to do so. If the authenticated attachment download call fails, add another call to download the attachment without authentication.
- Mark all messages as read by providing the conversation ID and timestamp.
- For Instagram, ensure all previous messages that weren't marked as failed are now marked as read. This is because the read events are only triggered for the most recent message and not for any previous ones.
DISTINCT query with custom attributes return an error. To avoid the error, this PR refactors the query to include tags only when it is required.
Fixes#7931Fixes#7836
Co-authored-by: Sojan Jose <sojan@pepalo.com>
We've had some messages come in from a few different phone numbers that had null bytes in them. I don't know how this happens. They don't seem to be malicious.
They currently cause the Postgres gem to raise an error when Chatwoot attempts to save the message body to the database:
ArgumentError (string contains null byte)
Related Rails GitHub issue: rails/rails#26891
- Ensure existing contact information is updated on data import
- Refactor the existing job to make it more readable
- Fixes issues with import files in the wrong encoding
fixes: #7307
This update will mean that errors will roll back the current transaction and the error will be sent back to the frontend and the user will know that the Inbox did not finish setting up successfully.