* 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>
* 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
- Refactor HandleStripeEventService to better manage features by plan
- Add constants for features available in each plan tier (Startup,
Business, Enterprise)
- Add channel_instagram to Startup plan features
- Improve downgrade handling to properly disable higher-tier features
- Clean up and optimize tests for maintainability
- Add comprehensive test coverage for plan upgrades and downgrades
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
* 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>
Add ability to send files as attachments instead of links
Fixes: https://github.com/chatwoot/chatwoot/issues/1074
## Changes
- `emaily_reply` : We will attach the small attachments as attachments
and large ones as links
- `reply_with_summary`, `conversation_transcript`,
`reply_with_out_summary` : We will change the attachment format to the
following instead of the previous `View the attachment here`
```
Attachments:
file_name
file_name2
```
---------
ref: https://github.com/chatwoot/chatwoot/pull/10318/files -> for fixing
: https://github.com/chatwoot/chatwoot/pull/9655#issuecomment-2183962550
---------
Co-authored-by: Marco Marinho <marcomarinho12@gmail.com>
Co-authored-by: Pranav <pranavrajs@gmail.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: exclude inbox_id from webhook update parameters
* feat: display inbox label in webhook settings
* feat: add inbox selection to webhook form
* feat: prevent updating inbox_id in webhook update
* feat: integrate MultiselectDropdown for inbox selection in webhook form
* feat: add inbox matching logic to webhook event delivery
* feat: remove unused inbox input placeholder from webhook form
* fix: MultiselectDropdown component submiting form
* feat: refine webhook parameters for create and update actions
* feat: disable URL input field when editing webhook
* chore: remove unnecessary parentheses
* chore: update webhook controller spec to ignore inbox_id and url updates
* fix: clean up JSON formatting
* fix: standardize inbox_id to inboxId in WebhookForm component
* refactor: replace LabelItem with InboxName component in WebhookRow
* chore: enhance MultiselectDropdown with button variant prop and update styling in WebhookForm
* chore: simplify MultiselectDropdown wrapper in WebhookForm component
* chore: update selectedInbox initialization to null and reorder form fields
* refactor: simplify InboxName
* chore: add dark variant styling for buttons in SCSS
* test: add inbox filtering for webhook event triggers in WebhookListener
* test: refactor webhook controller spec to use a variable for URL and improve update expectations
* feat(webhook): all inboxes option
* chore: remove dark variant styling for buttons in SCSS
* fix: bad interaction multiselectdropdown inside label
* chore: invert if
* chore: rename to assignedInbox and drop inboxId
* refactor(WebhookForm): restore div separating fields from buttons
* test: improve description
---------
Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
* feat(migration): add name column to webhook table
* feat(webhooks): add name parameter to webhook params
* feat(webhooks): add example webhook name constant and input field to form
* fix(webhooks): add webhook name label and placeholder to multiple locales in the form
* feat(webhooks): display webhook name in the UI and include it in the API response
* Revert 'fix(webhooks): add webhook name label and placeholder to multiple locales in the form'
This reverts commit e547778a1c038c934e22ceb25935f541cb09e2cd.
* test(webhooks): add tests for creating and updating webhooks with name attribute
* chore(webhooks): add name property to webhook definitions in Swagger documentation
* chore(webhooks): remove unnecessary input touch event for webhook name field
* chore(webhooks): apply review changes requested
* chore(webhooks): revert auto lint changes in commit 18ec4cafeb72fd385b70f65f1873d7cfb65216a6
- Removes the portal_members table and all associated records
- Updates policies to use custom roles with knowledge_base_manage
permission
- Updates controllers, models, and views to work without portal
membership
- Adds tests for the new permission model