33 Commits
Author SHA1 Message Date
8aee518149 fix(integrations): restrict Linear/Notion/Shopify hook deletion to admins (#15126)
Non-admin agents could delete an account's Linear, Notion, or Shopify
integration through the dedicated integration endpoints, which — unlike
the generic hooks endpoint — never checked the caller's role. This
restores the intended admin-only boundary for removing an integration.

## Closes
- https://linear.app/chatwoot/issue/CW-7383
- https://linear.app/chatwoot/issue/CW-7384
- https://linear.app/chatwoot/issue/CW-7189

## How to reproduce
As a non-admin **agent**, `DELETE
/api/v1/accounts/:id/integrations/{linear,notion,shopify}` returned
`200` and removed the account-wide integration. After this change it
returns `401` and the integration is preserved; administrators can still
remove it.

## What changed
- Route integration-hook deletion through `HookPolicy` (admin-only) via
a shared `Integrations::BaseController`, matching the generic hooks
controller.

Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
2026-07-22 17:53:25 +05:30
74db16158d feat: migrate dyte integration to cloudflare realtimekit (#14752)
Dyte is sunsetting its existing infrastructure after the Cloudflare
acquisition, so this migrates Chatwoot’s video call integration to
Cloudflare RealtimeKit.

The integration now uses Cloudflare Account ID, RealtimeKit App ID, and
a Cloudflare API token with Realtime Admin permissions. Meeting creation
and participant token generation now call Cloudflare’s RealtimeKit APIs,
while the existing Chatwoot call experience remains unchanged for agents
and customers.

This also adds setup-time credential validation, so admins get clearer
errors when the API token is invalid, the Cloudflare account or
permissions are incorrect, or the RealtimeKit App ID does not belong to
the selected account.

Fixes
https://linear.app/chatwoot/issue/PLA-176/migrate-dyte-integration-to-cloudflare-realtimekit

**How to test**

1. Go to Settings → Integrations → Cloudflare RealtimeKit.
2. Add a Cloudflare Account ID, RealtimeKit App ID, and API token with
Realtime Admin permissions.
3. Confirm the integration saves successfully with valid credentials.
4. Try invalid credentials and confirm the error identifies whether the
token, account/permissions, or app ID is wrong.
5. Start a video call from a conversation and confirm the RealtimeKit
meeting opens.

---------

Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
Co-authored-by: Sony Mathew <sony@chatwoot.com>
2026-06-24 11:04:08 +04:00
27404b4a27 fix: redact sensitive integration secrets from API responses (#14147)
## Summary

The `GET /api/v1/accounts/:id/integrations/apps` endpoint returns raw
secret values (OpenAI API keys, Google service account private keys,
Linear refresh tokens, etc.) in hook settings within the JSON response.
Although gated behind an administrator check, these secrets are visible
in the browser network tab.

This PR filters hook settings through the existing `visible_properties`
whitelist defined in `config/integration/apps.yml`, and adds explicit
whitelists to integrations that were missing them.

Closes #14042

## Bug reproduction

**Setup:** Created an OpenAI integration hook with a fake API key
(`sk-test-secret-12345`).

**Step 1 — Browser Network tab shows raw secrets:**

<img width="1676" height="869" alt="Screenshot 2026-04-24 at 14 32 28"
src="https://github.com/user-attachments/assets/6fc69463-365e-458b-b216-98a7390bf528"
/>


Navigate to Settings > Integrations as an admin. Open DevTools Network
tab and observe the response from `GET
/api/v1/accounts/:id/integrations/apps`. The hook settings contain the
full API key in plaintext:

```json
"hooks": [
  {
    "id": 1,
    "app_id": "openai",
    "settings": {
      "api_key": "sk-test-secret-12345",
      "label_suggestion": false
    }
  }
]
```

**Step 2 — API call confirms the leak:**

```bash
curl -s "http://localhost:3000/api/v1/accounts/2/integrations/apps" \
  -H "access-token: <token>" \
  -H "client: <client>" \
  -H "uid: user@test.com" \
  | jq '.payload[] | select(.id == "openai") | {id, name, hooks: [.hooks[] | {id, app_id, settings}]}'
```

Response:

```json
{
  "id": "openai",
  "name": "OpenAI",
  "hooks": [
    {
      "id": 1,
      "app_id": "openai",
      "settings": {
        "api_key": "sk-test-secret-12345",
        "label_suggestion": false
      }
    }
  ]
}
```

Any admin user can extract the raw API key from the response. The same
applies to other integrations — Dialogflow exposes full Google service
account credentials, Linear exposes refresh tokens, etc.

## After fix

After applying this change, the GET
/api/v1/accounts/:id/integrations/apps endpoint no longer returns
sensitive secret values in hook settings. Instead, the response is
filtered using each integration’s visible_properties whitelist, ensuring
only safe, user-facing fields are exposed. For example, OpenAI
integrations return non-sensitive fields like label_suggestion while
excluding raw API keys. This prevents secrets from being exposed in the
browser network tab or API responses, even for authenticated admin
users.

```bash
curl -X GET "http://localhost:3000/api/v1/accounts/2/integrations/apps" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer eyJhY2Nlc3MtdG9rZW4iOiJqZG5jOWg4TnljaWFJa3JlZkxGQzRnIiwidG9rZW4tdHlwZSI6IkJlYXJlciIsImNsaWVudCI6Ik81bjVnTDFEOVVhbGpwbWxjaHZNanciLCJleHBpcnkiOiIxNzgyMzMyNTA4IiwidWlkIjoidXNlckB0ZXN0LmNvbSJ9" \
  -H "access-token: jdnc9h8NyciaIkrefLFC4g" \
  -H "client: O5n5gL1D9UaljpmlchvMjw" \
  -H "uid: user@test.com" \
  | jq '.payload[] | select(.id == "openai") | {id, name, hooks: [.hooks[] | {id, app_id, settings}]}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 10174  100 10174    0     0  33232      0 --:--:-- --:--:-- --:--:-- 33357
{
  "id": "openai",
  "name": "OpenAI",
  "hooks": [
    {
      "id": 1,
      "app_id": "openai",
      "settings": {
        "label_suggestion": false
      }
    }
  ]
}
```

## What changed

- Added `visible_properties` accessor to `Integrations::App` model to
expose the whitelist from config
- Updated `_hook.json.jbuilder` to filter `resource.settings` through
the associated app's `visible_properties` instead of returning the full
hash
- Added `visible_properties` to integrations that were missing it:
  - Linear: `[]` (settings contain refresh_token)
  - Notion: `[]` (OAuth-based, no user-facing settings)
- Slack: `['channel_name']` (UI needs this to display connected channel)
  - Shopify: `[]` (no settings)

App config metadata (`_app.json.jbuilder`) is left unchanged —
hook_type, settings_form_schema, etc. are not secrets and the frontend
depends on them.

## How to test

1. Create an OpenAI integration hook with an API key
2. As an admin, call `GET /api/v1/accounts/:id/integrations/apps`
3. Verify hook settings include `api_key` (whitelisted) but not raw
credential objects
4. For Dialogflow hooks, verify `credentials` (private key JSON) is
excluded while `project_id` is included
5. For Slack hooks, verify `channel_name` is still returned
6. For Linear hooks, verify `refresh_token` is not returned

---------

Co-authored-by: Botshelo Nokoane (Konstruktors) <botshelo@entersekt.com>
Co-authored-by: Sony Mathew <sony@chatwoot.com>
Co-authored-by: Sony Mathew <2040199+sony-mathew@users.noreply.github.com>
2026-06-14 06:53:13 +05:30
3253e863ed fix: validate OpenAI hook credentials (#14068)
# Pull Request Template

## Description

- Validates openai key while configuring hooks
- added backfill logic

Fixes # (issue)

## Type of change

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


## 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.
locally

<img width="1710" height="1234" alt="CleanShot 2026-04-15 at 16 15
02@2x"
src="https://github.com/user-attachments/assets/3d319fe0-19f9-4fd0-9308-74987daac2e1"
/>

<img width="2884" height="1136" alt="CleanShot 2026-05-11 at 19 22
53@2x"
src="https://github.com/user-attachments/assets/5eae8650-985b-4c4a-af42-35f7175ff52d"
/>



## 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
- [x] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
2026-05-18 14:08:57 +05:30
Muhsin KelothandGitHub 01acbe3cda feat: Add user attribution to Linear integration with actor authorization (#11774)
- Add `actor=app` parameter to Linear OAuth authorization URL for
consistent app-level authorization
https://linear.app/developers/oauth-actor-authorization
- Implement user attribution for Linear issue creation and linking using
`createAsUser` and `displayIconUrl` parameters
- Enhance Linear integration to properly attribute actions to specific
Chatwoot agents

**Note**
- The displayIconUrl parameter is being sent correctly to Linear's
GraphQL API (verified through testing), but there is an issues with icon
is not attaching properly.
- We might need to disconnect the integration connect again.
2025-07-01 16:49:26 +05:30
Muhsin KelothandGitHub 14ba73fc63 fix: Revoke Linear OAuth token when integration is deleted (#11838)
When users delete the Linear integration from their Chatwoot dashboard,
the access token remains valid in Linear's system. This causes the
integration to still appear as connected in Linear's UI, even though
it's been removed from Chatwoot. Users need to manually disconnect from
Linear's side to fully remove the integration.


https://www.loom.com/share/5c102cbdf02e49bcb7a6fa6d409b531a?sid=0c664250-c867-4fc8-b44d-e1c1165337a7
2025-07-01 13:31:02 +05:30
Muhsin KelothandGitHub f4381e3b5d feat: Add activity messages for linear actions (#11654) 2025-06-13 11:57:11 +05:30
Sojan JoseandGitHub 10363e77ad chore: Add region option to Dialogflow integration (#11510)
## Summary
- support region option when configuring Dialogflow integration
- connect to region endpoint when set
- use session identification based on the region

Fixes: https://github.com/chatwoot/chatwoot/issues/4129
2025-06-05 20:01:17 -05:00
Sivin VargheseandGitHub ccb3672ff8 fix: Status not updating when creating a Linear issue (#11523) 2025-05-20 16:04:56 +05:30
b34c526c51 feat(apps): Shopify Integration (#11101)
This PR adds native integration with Shopify. No more dashboard apps.
The support agents can view the orders, their status and the link to the
order page on the conversation sidebar.

This PR does the following: 
- Create an integration with Shopify (a new app is added in the
integrations tab)
- Option to configure it in SuperAdmin
- OAuth endpoint and the callbacks.
- Frontend component to render the orders. (We might need to cache it in
the future)
---------

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>
2025-03-19 15:37:55 -07:00
12134f9391 feat: Linear OAuth 2.0 (#10851)
Fixes https://linear.app/chatwoot/issue/CW-3417/oauth-20-authentication
We are planning to publish the Chatwoot app in the Linear [integration
list](https://linear.app/docs/integration-directory). While we currently
use token-based authentication, Linear recommends OAuth2 authentication.
This PR implements OAuth2 support.

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2025-02-27 18:15:53 +05:30
11a7414dc0 feat: Upgrade Dyte apis to v2 (#10706)
# Pull Request Template

## Description

Dyte V1 API's are soon going to be deprecated, hence making sure we
update Chatwoot before that happens

Fixes #10704

## Type of change

Please delete options that are not relevant.

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

## How Has This Been Tested?

1. Open a new or existing conversation from the inbox
2. Press the video call icon on the message composer
3. Verify that the message dialog shows up with the join video call
button
4. Verify that clicking on join call does join the call

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings
- [ ] New and existing unit tests pass locally with my changes (Unable
to run this locally)

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-02-19 14:47:48 -08:00
d070743383 feat(ee): Add Captain features (#10665)
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>
2025-01-14 16:15:47 -08:00
PranavandGitHub 10a0333980 feat(ee): Add copilot integration (v1) to the conversation sidebar (#10566) 2024-12-10 15:36:48 -08:00
Shivam MishraandGitHub 97d7b9d754 feat(ee): Setup @chatwoot/captain NPM library (#10389)
--- 
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: Pranav <pranavrajs@gmail.com>
2024-11-11 17:39:09 -08:00
Muhsin KelothandGitHub 429d281501 fix: Handle OpenAI API errors (#9560) 2024-08-22 10:24:13 +05:30
PranavandGitHub 8696a4c135 chore: Use installation config URL for captain app URL (#9874)
Use `InstallationConfig.where(name: 'CAPTAIN_APP_URL')` instead of
`ENV.fetch('CAPTAIN_APP_URL', '')`
2024-08-02 13:17:55 +05:30
829bb842fd feat: Generate SSO URL in Chatwoot, move Captain to primary tab (#9871)
- Generate SSO URL in Chatwoot, move Captain to the primary tab

Co-authored-by: Pranav <pranavrajs@gmail.com>
2024-08-01 19:22:34 -07:00
0331815cc5 feat: Integration with Captain (alpha) (#9834)
- Integration with captain (alpha)

Co-authored-by: Pranav <pranavrajs@gmail.com>
2024-07-25 14:24:04 -07:00
Muhsin KelothandGitHub 023b3ad507 feat: Add APIs for linear integration (#9346) 2024-05-22 13:37:58 +05:30
Sojan JoseandGitHub 7ab7bac6bf chore: Enable the new Rubocop rules (#7122)
fixes: https://linear.app/chatwoot/issue/CW-1574/renable-the-disabled-rubocop-rules
2023-05-19 14:37:10 +05:30
92fa9c4fdc feat: Ability to improve drafts in the editor using GPT integration (#6957)
ref: https://github.com/chatwoot/chatwoot/issues/6436
fixes: https://linear.app/chatwoot/issue/CW-1552/ability-to-rephrase-text-in-the-editor-using-gpt-integration

---------

Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com>
2023-04-24 23:52:23 +05:30
Pranav Raj SandGitHub 9e8eb293e9 fix: Allow integration apps to be listed by an agent (#6587)
* fix: Allow integration apps to be listed by an agent

* Fix rubocop
2023-03-02 13:02:21 +05:30
Pranav Raj SandGitHub cbfbe6dbad feat: Add backend APIs for Dyte integration (#6197)
- The backend changes required for Dyte Integration.
2023-01-09 12:37:18 +05:30
Sojan JoseandGitHub 4187428729 chore: Update dependencies to the latest versions (#5033) 2022-07-15 09:51:59 +07:00
Akhil G KrishnanandGitHub 84df9c807d chore: Add climate-control gem for handling the test ENV vars (#3267) 2021-10-25 13:13:25 +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
Sojan JoseandGitHub bb1c028926 fix: Slack integration redirect url missing the client ID (#2309)
Fixes: #2304
2021-05-21 00:03:09 +05:30
Sojan JoseandGitHub 46356d0bf9 docs: Add documentation for integration APIs (#2300) 2021-05-20 20:46:45 +05:30
Sojan JoseandGitHub d5215fea93 feat: APIs for Integration Hooks (#2250)
- Introduces JSON Schema validations via JSONSchemer
- Add CRUD APIs for integration hooks
2021-05-17 10:32:59 +05:30
Sojan JoseandGitHub 4f83d5451e Chore: Routine Bugfixes and enhancements (#979)
- Fix slack scopes
- Docs for authentication
Fixes: #704 , #973
2020-06-25 23:35:16 +05:30
1ef8d03e18 Feature: Slack - receive messages, create threads, send replies (#974)
Co-authored-by: Pranav Raj S <pranav@thoughtwoot.com>
2020-06-22 13:19:26 +05:30
Subin T PandGitHub ed1c871633 Feature: Slack integration (#783)
- Integrations architecture
- Slack integration
2020-06-12 23:12:47 +05:30