Commit Graph
65 Commits
Author SHA1 Message Date
Sojan JoseandGitHub 0e07a27c74 fix: enforce inbox limits at model level (#14949)
Fixes https://linear.app/chatwoot/issue/CW-7559/inbox-limit-abuse

## Why

The regular inbox API checked limits in the controller, but WhatsApp
embedded signup creates inboxes through a service using `Inbox.create!`.
That let Enterprise account inbox limits be skipped for embedded signup.

## What this change does

- Adds an Inbox create-time validation hook in OSS and implements the
limit check in the Enterprise Inbox module.
- Removes the duplicate controller/helper limit check so the model is
the single enforcement point.
- Preserves the existing `402 Payment Required` API response for account
inbox limit failures.
- Keeps updates to existing inboxes allowed when an account is already
at its inbox limit.

## Validation

- `bundle exec rspec
spec/controllers/api/v1/accounts/inboxes_controller_spec.rb
spec/enterprise/models/inbox_spec.rb`
2026-07-08 13:18:07 +04:00
13f66e3a88 fix: incorrect scope across controllers (#14459)
Co-authored-by: Sojan Jose <sojan@pepalo.com>
2026-05-14 20:34:18 +05:30
dd7f5c27e5 perf: eliminate N+1 queries on inboxes#index (#14451)
The `inboxes#index` API endpoint was firing 3 queries per inbox while
rendering the response — one each for the polymorphic channel, avatar
attachment, and working hours. For accounts with many inboxes this
turned a routine list call into a multi-second request — measured at 35
seconds on an account with 5,000 inboxes.

Two root causes:
1. `policy_scope` was silently discarding the controller's
`.includes(...)` chain because `InboxPolicy::Scope#resolve` returns a
fresh `user.assigned_inboxes` relation, ignoring whatever scope is
passed in. So the eager loading never actually applied.
2. `Inbox#weekly_schedule` called `working_hours.order(...).select(...)`
which fires a new query per inbox even when the association is
preloaded.

The fix chains the eager loads and ordering after `policy_scope` so they
apply to the relation the policy actually returns, adds `:portal` and
`:working_hours` to the preload list, and refactors `weekly_schedule` to
sort the preloaded collection in Ruby and build the hash directly.

Result: queries drop from O(n) to a constant ~15 regardless of inbox
count, and total request time drops 5–6× across every account size
tested. Response payload is byte-identical.

## How to test

1. Open the agent dashboard for an account with a large number of
inboxes (1000+). On a stock dev DB you can seed quickly with
`Seeders::AccountSeeder` or by creating a few hundred `Channel::Api`
inboxes via the rails console.
2. Hit any UI surface that lists inboxes (settings → inboxes, sidebar
inbox list, agent assignment dropdowns). Should feel near-instant where
it previously hung.
3. Confirm every inbox shows the same data as before — channel type,
working hours, avatar, portal/help-center link. No fields should be
missing or different.

## Benchmarks

Real HTTP requests via curl against a dev Rails server (median of 5
timed trials after warmup; "Server total" is the time reported in Rails'
`Completed 200 OK in <X>ms` log line).

| Account | Channel mix | OLD | NEW | Speedup |
|---|---|---|---|---|
| 1000 inboxes | 3 types, no portals/avatars | 5.87 s | 0.96 s |
**6.1×** |
| 5000 inboxes | 3 types, no portals/avatars | 33.07 s | 6.93 s |
**4.8×** |
| 5000 inboxes | 10 types, 25% portals, 10% avatars | 35.04 s | 6.55 s |
**5.4×** |

Detailed breakdown for the realistic 5000-inbox case:

|                 | OLD       | NEW      | Δ        |
|-----------------|-----------|----------|----------|
| Server total    | 35,042 ms | 6,550 ms | −81%     |
| Views           | 32,034 ms | 6,452 ms | −80%     |
| ActiveRecord    | 2,948 ms  | 92 ms    | −97%     |
| Allocations     | 42.3 M    | 11.3 M   | −73%     |
| Queries         | ~15,000   | 15       | −99.9%   |

## What changed

- `app/controllers/api/v1/accounts/inboxes_controller.rb` — chain
`.includes(:channel, :portal, :working_hours, avatar_attachment:
:blob).order_by_name` *after* `policy_scope(...)`. The previous code
passed them into `policy_scope` but the policy resolver dropped the
chain.
- `app/models/concerns/out_of_offisable.rb` — `weekly_schedule` now
sorts the preloaded `working_hours` collection in Ruby and constructs
the result hashes inline, avoiding both the per-inbox query from
`.order(...).select(...)` and the `as_json` reflection overhead.

Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2026-05-14 14:20:52 +05:30
95463230cb feat: sign webhooks for API channel and agentbots (#13892)
Account webhooks sign outgoing payloads with HMAC-SHA256, but agent bot
and API inbox webhooks were delivered unsigned. This PR adds the same
signing to both.

Each model gets a dedicated `secret` column rather than reusing the
agent bot's `access_token` (for API auth back into Chatwoot) or the API
inbox's `hmac_token` (for inbound contact identity verification). These
serve different trust boundaries and shouldn't be coupled — rotating a
signing secret shouldn't invalidate API access or contact verification.

The existing `Webhooks::Trigger` already signs when a secret is present,
so the backend change is just passing `secret:` through to the jobs.
Shared token logic is extracted into a `WebhookSecretable` concern
included by `Webhook`, `AgentBot`, and `Channel::Api`. The frontend
reuses the existing `AccessToken` component for secret display. Secrets
are admin-only and excluded from enterprise audit logs.

### How to test

Point an agent bot or API inbox webhook URL at a request inspector. Send
a message and verify `X-Chatwoot-Signature` and `X-Chatwoot-Timestamp`
headers are present. Reset the secret from settings and confirm
subsequent deliveries use the new value.

---------

Co-authored-by: Sojan Jose <sojan@pepalo.com>
2026-04-06 15:28:25 +05:30
a452ce9e84 feat(whatsapp): add webhook registration and status endpoints (#13551)
## Description

Adds webhook configuration management for WhatsApp Cloud API channels,
allowing administrators to check webhook status and register webhooks
directly from Chatwoot without accessing Meta Business Manager.

## Type of change

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


## Screenshots

<img width="1130" height="676" alt="Screenshot 2026-03-05 at 7 04 18 PM"
src="https://github.com/user-attachments/assets/f5dcd9dd-8827-42c5-a52b-1024012703c2"
/>
<img width="1101" height="651" alt="Screenshot 2026-03-05 at 7 04 29 PM"
src="https://github.com/user-attachments/assets/e0bd59f9-2a90-4f24-87c0-b79f21e721ee"
/>



## 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>
2026-03-16 12:48:16 +05:30
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>
2026-01-13 16:32:02 +04:00
2bd8e76886 feat: Add backend changes for whatsapp csat template (#12984)
This PR add the backend changes for the feature [sending CSAT surveys
via WhatsApp message templates
](https://github.com/chatwoot/chatwoot/pull/12787)

---------

Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com>
2025-12-11 16:36:37 +05:30
66cfef9298 feat: Add WhatsApp health monitoring and self-service registration completion (#12556)
Fixes
https://linear.app/chatwoot/issue/CW-5692/whatsapp-es-numbers-stuck-in-pending-due-to-premature-registration


###  Problem  
Multiple customers reported that their WhatsApp numbers remain stuck in
**Pending** in WhatsApp Manager even after successful onboarding.

- Our system triggers a **registration call**
(`/<PHONE_NUMBER_ID>/register`) as soon as the number is OTP verified.
- In many cases, Meta hasn’t finished **display name
review/provisioning**, so the call fails with:

  ```
  code: 100, error_subcode: 2388001
  error_user_title: "Cannot Create Certificate"
error_user_msg: "Your display name could not be processed. Please edit
your display name and try again."
  ```

- This leaves the number stuck in Pending, no messaging can start until
we manually retry registration.
- Some customers have reported being stuck in this state for **7+
days**.

###  Root cause  
- We only check `code_verification_status = VERIFIED` before attempting
registration.
- We **don’t wait** for display name provisioning (`name_status` /
`platform_type`) to be complete.
- As a result, registration fails prematurely and the number never
transitions out of Pending.

### Solution  

#### 1. Health Status Monitoring  
- Build a backend service to fetch **real-time health data** from Graph
API:
  - `code_verification_status`  
  - `name_status` / `display_name_status`  
  - `platform_type`  
  - `throughput.level`  
  - `messaging_limit_tier`  
  - `quality_rating`  
- Expose health data via API
(`/api/v1/accounts/:account_id/inboxes/:id/health`).
- Display this in the UI as an **Account Health tab** with clear badges
and direct links to WhatsApp Manager.

#### 2. Smarter Registration Logic  
- Update `WebhookSetupService` to include a **dual-condition check**:  
  - Register if:  
    1. Phone is **not verified**, OR  
2. Phone is **verified but provisioning incomplete** (`platform_type =
NOT_APPLICABLE`, `throughput.level = NOT_APPLICABLE`).
- Skip registration if number is already provisioned.  
- Retry registration automatically when stuck.  
- Provide a UI banner with complete registration button so customers can
retry without manual support.

### Screenshot
<img width="2292" height="1344" alt="CleanShot 2025-09-30 at 16 01
03@2x"
src="https://github.com/user-attachments/assets/1c417d2a-b11c-475e-b092-3c5671ee59a7"
/>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
2025-10-02 11:25:48 +05:30
7d6a43fc72 feat: Added the backend support for twilio content templates (#12272)
Added comprehensive Twilio WhatsApp content template support (Phase 1)
enabling text, media, and quick reply templates with proper parameter
conversion, sync capabilities.

 **Template Types Supported**
  - Basic Text Templates: Simple text with variables ({{1}}, {{2}})
  - Media Templates: Image/Video/Document templates with text variables
  - Quick Reply Templates: Interactive button templates
  
 Front end changes is available via #12277

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
2025-08-24 10:05:15 +05:30
ab1ba1c4c7 feat: Add manual WhatsApp templates sync with UI (#12007)
Fixes https://github.com/chatwoot/chatwoot/issues/9600

**Summary**
- Added manual WhatsApp templates sync functionality accessible via UI
- Added refresh button in both inbox settings and template picker modal
- Enhanced template picker to always show for WhatsApp Cloud channels
(even when empty)


**Preview**

<img width="1456" height="798" alt="CleanShot 2025-07-22 at 14 15 28@2x"
src="https://github.com/user-attachments/assets/8a04ff26-61fa-42ee-a1b8-5e06433ae6e0"
/>


<img width="2376" height="1574" alt="CleanShot 2025-07-22 at 14 19
24@2x"
src="https://github.com/user-attachments/assets/1c772034-04ff-484d-88dd-ca8123e93065"
/>

---------

Co-authored-by: iamsivin <iamsivin@gmail.com>
2025-07-23 12:22:51 +04:00
b7f2c151bf feat: Voice channel creation Flow (#11775)
This PR introduces a new channel type for voice conversations.

ref: #11481 

## Changes

- Add database migration for channel_voice table with phone_number and
provider_config
- Create Channel::Voice model with E.164 phone number validation and
Twilio config validation
- Add voice channel association to Account model
- Extend inbox helpers and types to support voice channels
- Add voice channel setup UI with Twilio configuration form
- Include voice channel in channel factory and list components
- Add API routes and store actions for voice channel creation
- Add comprehensive translations for voice channel management

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
2025-06-25 14:21:03 -07:00
d0611cb7f2 feat: Improve CSAT responses (#11485)
# 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>
2025-05-16 14:18:52 +05:30
Tejaswini ChileandGitHub 71837bedf9 feat: Ability to customise the email sender name [CW-1629] (#7345) 2023-07-04 20:46:01 +05:30
f963e00731 fix: capture user and ip details on Inbox delete (#7395)
Fixes: https://linear.app/chatwoot/issue/CW-1772/ip-address-and-user-details-are-missing-in-some-of-the-logs

Co-authored-by: Sojan <sojan@pepalo.com>
2023-06-27 19:49:24 +05:30
Sojan JoseandGitHub e3f4be97c0 fix: Reauthorize when channel settings updated (#7134)
Fixes: https://linear.app/chatwoot/issue/CW-1803/bug-inbox-doesnt-update-reauthorisation-required-automattically
2023-05-19 22:04:34 +05:30
Tejaswini ChileandGitHub e3193dcabc feat: Link help center portal to an Inbox (#6903) 2023-04-24 12:49:52 +05:30
Tejaswini ChileandGitHub 4f936aada5 [CW-1342]: Inbox deletion in background job (#6708) 2023-03-20 13:46:07 +05:30
Pranav Raj SandGitHub 949ddf68ba chore: Refactor the notification service for participants (#6461) 2023-02-15 14:14:56 -08:00
b05d06a28a feat: Ability to lock to single conversation (#5881)
Adds the ability to lock conversation to a single thread for Whatsapp and Sms Inboxes when using outbound messages.

demo: https://www.loom.com/share/c9e1e563c8914837a4139dfdd2503fef

fixes: #4975

Co-authored-by: Nithin David <1277421+nithindavid@users.noreply.github.com>
2022-11-25 13:01:04 +03:00
Aswin Dev P.SandGitHub 9015d83679 chore: Fix sentry issues (#4863)
Fix sentry issues.

Fixes #4815, #4814, #4811, #4809
2022-06-15 16:20:19 +05:30
713fdb44ee feat (ee): APIs to configure an auto assignment limit for inboxes (#4672)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
2022-06-13 20:18:38 +05:30
Pranav Raj SandGitHub 56cd9bc0b8 chore: Add Assignable Agents API (#4722) 2022-05-23 19:24:07 +05:30
Jordan BroughandGitHub c2647a1f27 chore: Use "destroy!" instead of "destroy" when not checking the return value (#4259) 2022-03-24 13:28:25 +05:30
Sojan JoseandGitHub 467f3b9191 chore: Disable fetching new emails after mailbox error (#4176)
- Disabled email fetch job if credentials for the channel isn't working
- notify customers when the email channel isn't working

fixes: https://github.com/chatwoot/chatwoot/issues/4174
2022-03-22 12:14:17 +05:30
Muhsin KelothandGitHub f405572e5c Revert "feat: Custom fields in pre-chat form (#4135)" (#4182)
This reverts commit e730804b48.
2022-03-15 16:54:33 +05:30
Muhsin KelothandGitHub e730804b48 feat: Custom fields in pre-chat form (#4135)
Fixes: #2744
2022-03-14 15:06:56 +05:30
Sojan JoseandGitHub eb0da2026f chore: Bundle update (#4038)
- address the nokogiri security issues
2022-02-22 16:06:04 +05:30
Sojan JoseandGitHub 3d73d8935a feat: Add the ability for a super admin to define account limits (#3946)
Fixes: #3773
2022-02-14 15:55:08 +05:30
Sojan JoseandGitHub cf10f3d03b chore: Provider APIs for SMS Channel - Bandwidth (#3889)
fixes: #3888
2022-02-03 15:22:13 -08:00
Aswin Dev P.SandGitHub 7ee7062843 feat: Toggle to disallow users to send messages after a conversation is resolved (#3605) 2022-01-11 00:32:03 -08:00
Tejaswini ChileandGitHub 76e8acd3c6 Fix: Editable attrs presence check for the channel class (#3630) 2021-12-20 19:38:38 +05:30
Tejaswini ChileandGitHub 9984edd3ef Feat: Manage conversation for tweets based on the tweet flag (#3353)
Add tweet conversation only if tweets are enabled.

Fixes #1961
2021-12-16 00:24:50 +05:30
Aswin Dev P.SandGitHub 24e6a92297 feat: IMAP Email Channel (#3298)
This change allows the user to configure both IMAP and SMTP for an email inbox. IMAP enables the user to see emails in Chatwoot. And user can use SMTP to reply to an email conversation.

Users can use the default settings to send and receive emails for email inboxes if both IMAP and SMTP are disabled.

Fixes #2520
2021-11-19 11:52:27 +05:30
Sojan JoseandGitHub 69f55a25b6 chore: Minor API fixes (#3290)
- Log whether web-hook was successful
- Inbox update shouldn't need channel params
2021-10-28 15:26:20 +05:30
bd7aeba484 chore: Provider API prototype (#3112)
Enabling Support for Whatsapp via 360Dialog as a prototype for the provider APIs. 

Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
2021-10-05 23:35:06 +05:30
Sojan JoseandGitHub 2396b59f11 chore: API fixes (#3014)
- Minor API fixes
- Configuration screen for LINE inbox
2021-09-14 22:44:53 +05:30
Sojan JoseandGitHub 22d1c8baf2 Chore: Inbox Members API improvements (#3008)
- New Inbox Member APIs
- Return JSON errors for Platform APIs
2021-09-14 11:55:02 +05:30
Sojan JoseandGitHub 0a38632f14 feat: Line Channel (#2904)
- Ability to configure line bots as a channel in chatwoot
- Receive a message sent to the line bot in chatwoot
- Ability to reply to line users from chatwoot

fixes: #2738
2021-09-11 01:31:17 +05:30
Sojan JoseandGitHub 671c5c931f feat: Telegram Channel (#2901)
- Ability to configure telegram bots as a channel in chatwoot
- Receive a message sent to the telegram bot in chatwoot
- Ability to reply to telegram users from chatwoot
- Receive attachment messages in chatwoot

fixes: #1843
2021-09-10 00:00:52 +05:30
Sojan JoseandGitHub 2ebd38c3b7 Chore: API Improvements (#2956)
- API to fetch info of a single inbox
- Document passing custom_attributes in the API
- Ability to filter contacts with contact identifier in search API
2021-09-04 17:56:46 +05:30
1ff9939a80 feat: Ability to remove inbox avatar (#2885)
* Delete inbox avatar

1) New API endpoint added for deleting inbox avatar.
2) Delete avatar button in the inbox settings page.

Co-authored-by: Sojan Jose <sojan@pepalo.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2021-08-31 15:12:05 +05:30
Muhsin KelothandGitHub 48127e00d7 feat: Enable/disable CSAT in web widget settings (#2531) 2021-07-05 11:07:02 +05:30
534acfbf96 chore: Ensure privilege validations for API endpoints (#2224)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
2021-06-11 11:44:31 +05:30
Muhsin KelothandGitHub b9e40d1452 feat: Add an option to enable/disable email collect box (#2399)
* add email collect enabled migration

* migrations

* expose enable_email_collect field

* add select for email collect

* add enable_email condition on new conversation

* add default value true for enable_email_collect

* add specs for email collect enabled

* rereun migration

* code cleanup

* update token life span to 2 months

* revert uuid column
2021-06-10 02:34:03 -07:00
Sojan JoseandGitHub 22965be6dc feat: Add AgentBot APIs (#2323) 2021-06-01 22:34:25 +05:30
Sojan JoseandGitHub b89cc9cf57 feat: Add APIs for Campaigns (#2175) 2021-04-29 22:23:32 +05:30
Sojan JoseandGitHub 4635e5bb44 feat: Assignable agents API (#2131)
`inboxes/id/assignable_agents` returns all users that have permission to a conversation happening in that inbox.
2021-04-20 13:46:20 +05:30
Sojan JoseandGitHub 0e721653e5 feat: Business hour Inbox APIs (#1821)
* feat: Business hour Inbox APIs
2021-02-23 12:11:15 +05:30
Pranav Raj SandGitHub 1706199a0e feat: Add pre_chat_form_settings in inbox settings page (#1776) 2021-02-16 00:58:57 +05:30
f214c9c47c feat: Add Contacts page (#1335)
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: Pranav Raj Sreepuram <pranavrajs@gmail.com>
2020-11-10 15:25:26 +05:30