Commit Graph

5596 Commits

Author SHA1 Message Date
Giuseppe Di Giorno
aa21c15d0e fix: hide linear card when not enabled (#12918)
The Linear card now only appears in conversation sidebar when:

- The linear_integration feature flag is enabled for the account
- LINEAR_CLIENT_ID is configured (inferred from the integration existing
in the store)

This matches the backend behavior: if LINEAR_CLIENT_ID is not set, the
integration is filtered out of the API response, so it won't exist in
the store.

In addition, I discovered that Settings/Integrations page showed Linear
card even if it was disabled but Linear client_id set. Now the Linear
card shows only if both conditions are met.

Fixes #12909 

## How Has This Been Tested?

#### Before


https://github.com/user-attachments/assets/cd21b881-5332-48f8-b230-662abc256ba2


#### After



https://github.com/user-attachments/assets/d794cc2e-19d6-4545-b2ef-3af054c2ac81



---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2025-12-08 20:49:50 +05:30
Tanmay Deep Sharma
3051da1e44 fix: add renewal identification for credit flow (#12999) 2025-12-08 18:35:33 +05:30
Sivin Varghese
399c91adaa feat: Standardize rich editor across all channels (#12600)
# Pull Request Template

## Description

This PR includes,

1. **Channel-specific formatting and menu options** for the rich reply
editor.
2. **Removal of the plain reply editor** and full **standardization** on
the rich reply editor across all channels.
3. **Fix for multiple canned responses insertion:**
* **Before:** The plain editor only allowed inserting canned responses
at the beginning of a message, making it impossible to combine multiple
canned responses in a single reply. This caused inconsistent behavior
across the app.
* **Solution:** Replaced the plain reply editor with the rich
(ProseMirror) editor to ensure a unified experience. Agents can now
insert multiple canned responses at any cursor position.
4. **Floating editor menu** for the reply box to improve accessibility
and overall user experience.
5. **New Strikethrough formatting option** added to the editor menu.

---

**Editor repo PR**:
https://github.com/chatwoot/prosemirror-schema/pull/36

Fixes https://github.com/chatwoot/chatwoot/issues/12517,
[CW-5924](https://linear.app/chatwoot/issue/CW-5924/standardize-the-editor),
[CW-5679](https://linear.app/chatwoot/issue/CW-5679/allow-inserting-multiple-canned-responses-in-a-single-message)

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

### Screenshot
**Dark**
<img width="850" height="345" alt="image"
src="https://github.com/user-attachments/assets/47748e6c-380f-44a3-9e3b-c27e0c830bd0"
/>

**Light**
<img width="850" height="345" alt="image"
src="https://github.com/user-attachments/assets/6746cf32-bf63-4280-a5bd-bbd42c3cbe84"
/>


## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com>
2025-12-08 14:43:45 +05:30
Tanmay Deep Sharma
eb759255d8 perf: update the logic to purchase credits (#12998)
## Description

- Replaces Stripe Checkout session flow with direct card charging for AI
credit top-ups
- Adds a two-step confirmation modal (select package → confirm purchase)
for better UX
- Creates Stripe invoice directly and charges the customer's default
payment method immediately

## Type of change

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

## How Has This Been Tested?

- Using the specs
- UI manual test cases

<img width="945" height="580" alt="image"
src="https://github.com/user-attachments/assets/52bdad46-cd0e-4927-b13f-54c6b6353bcc"
/>

<img width="945" height="580" alt="image"
src="https://github.com/user-attachments/assets/231bc7e9-41ac-440d-a93d-cba45a4d3e3e"
/>


## 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: Shivam Mishra <scm.mymail@gmail.com>
2025-12-08 10:52:17 +05:30
Sojan Jose
cc86b8c7f1 fix: stream attachment handling in workers (#12870)
We’ve been watching Sidekiq workers climb from ~600 MB at boot to
1.4–1.5 GB after an hour whenever attachment-heavy jobs run. This PR is
an experiment to curb that growth by streaming attachments instead of
loading the whole blob into Ruby: reply-mailer inline attachments,
Telegram uploads, and audio transcriptions now read/write in chunks. If
this keeps RSS stable in production we’ll keep it; otherwise we’ll roll
it back and keep digging
2025-12-05 13:02:53 -08:00
Shivam Mishra
a971ff00f8 fix: ruby_llm version conflicts with ai-agents (#13011)
Co-authored-by: aakashb95 <aakash@chatwoot.com>
2025-12-05 10:52:13 +05:30
Aakash Bakhle
67dc21ea5f fix: Hardcoded 500 in AI api error response(#13005)
## 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 false new relic alerts set due to hardcoding an error code

## Type of change


Bug fix (non-breaking change which fixes an issue)
## 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.

Before
<img width="776" height="666" alt="image"
src="https://github.com/user-attachments/assets/f086890d-eaf1-4e83-b383-fe3675b24159"
/>

the 500 was hardcoded. 
RubyLLM doesn't send any error codes, so i removed the error code
argument and just pass the error message

Langfuse gets just the error message

<img width="883" height="700" alt="image"
src="https://github.com/user-attachments/assets/fc8c3907-b9a5-4c87-bfc6-8e05cfe9c8b0"
/>

local logs only show error
<img width="1434" height="200" alt="image"
src="https://github.com/user-attachments/assets/716c6371-78f0-47b8-88a4-03e4196c0e9a"
/>

Better fix is to handle each case and show the user wherever necessary

## 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: aakashb95 <aakash@chatwoot.com>
2025-12-04 20:32:46 +05:30
Muhsin Keloth
efc3b5e7d4 fix: Handle Instagram API error codes properly in message processing (#13002)
### Problem

Instagram webhook processing was failing with:

> TypeError: no implicit conversion of String into Integer

This occurred when handling **echo messages** (outgoing messages) that:

* Contained `unsupported_type` attachments, and
* Were sent to a recipient user that could **not** be fetched via the
Instagram API.

In these cases, the webhook job crashed while trying to create or find
the contact for the recipient.

### Root Cause

The Instagram message service does not correctly handle Instagram API
error code **100**:

> "Object with ID does not exist, cannot be loaded due to missing
permissions, or does not support this operation"

When this error occurred during `fetch_instagram_user`:

1. The method fell through to exception tracking without an explicit
return.
2. `ChatwootExceptionTracker.capture_exception` returned `true`.
3. As a result, `fetch_instagram_user` effectively returned `true`
instead of a hash or empty hash.
4. `ensure_contact` then called `find_or_create_contact(true)` because
`true.present?` is `true`.
5. `find_or_create_contact` crashed when it tried to access
`true['id']`.

So the chain was:

```txt
fetch_instagram_user -> returns true
ensure_contact -> find_or_create_contact(true)
find_or_create_contact -> true['id'] -> TypeError
```

**Example Webhook Payload**

```
{
  "object": "instagram",
  "entry": [{
    "time": 1764822592663,
    "id": "17841454414819988",
    "messaging": [{
      "sender": { "id": "17841454414819988" },     // Business account
      "recipient": { "id": "1170166904857608" },   // User that can't be fetched
      "timestamp": 1764822591874,
      "message": {
        "attachments": [{
          "type": "unsupported_type",
          "payload": { "url": "https://..." }
        }],
        "is_echo": true
      }
    }]
  }]
}
```

**Corresponding Instagram API error:**

```
{
  "error": {
    "message": "The requested user cannot be found.",
    "type": "IGApiException",
    "code": 100,
    "error_subcode": 2534014
  }
}
```

**Debug Logs (Before Fix)**

```
[InstagramUserFetchError]: Unsupported get request. Object with ID '17841454414819988' does not exist... 100
[DEBUG] result: true
[DEBUG] result.present?: true
[DEBUG] find_or_create_contact called
[DEBUG] user: true
[DEBUG] Invalid user parameter - expected hash with id, got TrueClass: true
```

### Solution

### 1\. Handle Error Code 100 Explicitly

We now treat Instagram API error code **100** as a valid case for
creating an “unknown” contact, similar to how we already handle error
code `9010`:

```
# Handle error code 100: Object doesn't exist or missing permissions
# This typically occurs when trying to fetch a user that doesn't exist
# or has privacy restrictions. We can safely create an unknown contact.
return unknown_user(ig_scope_id) if error_code == 100
```

This ensures:

* `fetch_instagram_user` returns a valid hash for unknown users.
* `ensure_contact` can proceed safely without crashing.

### 2\. Prevent Exception Tracker Results from Leaking Through

For any **unhandled** error codes, we now explicitly return an empty
hash after logging the exception:

```
exception = StandardError.new(
  "#{error_message} (Code: #{error_code}, IG Scope ID: #{ig_scope_id})"
)
ChatwootExceptionTracker.new(exception, account: @inbox.account).capture_exception

# Explicitly return empty hash for any unhandled error codes
# This prevents the exception tracker result (true/false) from being returned.
{}
```

This guarantees that `fetch_instagram_user` always returns either:

* A valid user hash,
* An “unknown” user hash
* An empty hash
Fixes
https://linear.app/chatwoot/issue/CW-6068/typeerror-no-implicit-conversion-of-string-into-integer-typeerror
2025-12-04 18:53:50 +05:30
Aakash Bakhle
eed2eaceb0 feat: Migrate ruby llm captain (#12981)
Co-authored-by: aakashb95 <aakash@chatwoot.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2025-12-04 18:26:10 +05:30
Muhsin Keloth
0a17976913 fix: Filter out unsupported ephemeral message attachments (#13003)
Fixes
https://linear.app/chatwoot/issue/CW-6070/argumenterror-ephemeral-is-not-a-valid-file-type-argumenterror

**Problem**
The instagram webhooks containing ephemeral (disappearing) message were
causing ArgumentError exceptions because this attachment type is not
supported and was not in the enum validation.

**Solution**
- Added ephemeral to the unsupported_file_type? filter
- Ephemeral attachments are now silently filtered out before processing,
following the same pattern as existing unsupported types (template,
unsupported_type)
2025-12-04 16:09:04 +05:30
Shivam Mishra
57904a56a0 chore: update vulnerable packages (#12996)
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-12-04 15:28:12 +05:30
Vishnu Narayanan
728a5a6710 fix: handle missing AccountUser in inbox_member API (#12993)
Fixes
https://linear.app/chatwoot/issue/CW-6065/actionviewtemplateerror-undefined-method-availability-status-for-nil
2025-12-04 13:32:51 +05:30
Aakash Bakhle
87fe1e9ad7 feat: migrate editor to ruby-llm (#12961)
Co-authored-by: aakashb95 <aakash@chatwoot.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2025-12-04 12:51:35 +05:30
Muhsin Keloth
5c3b85334b feat: Add support for shared post and story attachment types in Instagram messages (#12997)
When users share Instagram posts or stories via DM, Instagram sends
webhooks with type `ig_post` and `ig_story` attachments. The system was
failing on these types because they weren't defined in the file_types.
This PR fixes the issue by handling all shared types and rendering them
on the front end.

**Shared post**

<img width="2154" height="1828" alt="CleanShot 2025-12-03 at 16 29
14@2x"
src="https://github.com/user-attachments/assets/7e731171-4904-43a6-abeb-b1db2c262742"
/>

**Shared status**
<img width="1702" height="1676" alt="CleanShot 2025-12-03 at 16 10
25@2x"
src="https://github.com/user-attachments/assets/6a151233-ce47-429d-b7c2-061514b20e05"
/>


Fixes
https://linear.app/chatwoot/issue/CW-5441/argumenterror-ig-story-is-not-a-valid-file-type-argumenterror
2025-12-04 05:20:47 +05:30
Muhsin Keloth
e6a7e836a0 fix: Add support for ig_post attachment type in Instagram messages (#12992)
Fixes
https://linear.app/chatwoot/issue/CW-6055/argumenterror-ig-post-is-not-a-valid-file-type-argumenterror

This PR fixes an issue where Instagram sends webhooks with both "type":
"share" and "type": "ig_post" attachments when users share Instagram
posts in direct messages. The system was failing on the ig_post type
because it wasn't defined, causing ArgumentError exceptions.


https://github.com/user-attachments/assets/577b8ebd-80e3-4c11-95f5-d8a8c3e16534
2025-12-03 10:27:16 +05:30
Tanmay Deep Sharma
b269cca0bf feat: Add AI credit topup flow for Stripe (#12988)
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
2025-12-02 17:53:44 -08:00
Sivin Varghese
1df5fd513a fix: Reduce unnecessary label suggestion API calls (#12978) 2025-12-01 13:36:34 +05:30
Muhsin Keloth
4627aad56d fix: Enable reply editor for API channels with templates (#12973) 2025-12-01 10:13:38 +05:30
Sivin Varghese
f23d95e004 feat: Add Pinia support and relocate store factory (#12854)
Co-authored-by: Vinay Keerthi <11478411+stonecharioteer@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
2025-11-28 16:31:59 +05:30
Aakash Bakhle
1ef945de7b feat: Instrument captain (#12949)
Co-authored-by: aakashb95 <aakash@chatwoot.com>
2025-11-28 15:12:55 +05:30
Sivin Varghese
92fc286ecb fix: Resolve z-index issue in assistant switcher (#12969) 2025-11-27 10:35:42 +05:30
Sivin Varghese
dedb0426fb chore: Improve pagination with compact number formatting and pluralization (#12962) 2025-11-27 10:32:34 +05:30
Vinay Keerthi
eb0410af53 fix: handle string return values in MailPresenter#from method (#12966) 2025-11-27 10:31:56 +05:30
Aakash Bakhle
3ded13c8d5 chore(revert): switch label suggestions back gpt 4 mini (#12959)
Co-authored-by: aakashb95 <aakash@chatwoot.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-11-27 10:27:11 +05:30
Vinay Keerthi
f1079574e3 fix: Disable SSL verification for LINE webhooks in development (#12960)
## Summary

- Fixes SSL certificate verification errors when testing LINE webhooks
in development environments
- Configures the LINE Bot API client to skip SSL verification only in
development mode

## Background

When testing LINE webhooks locally on macOS, the LINE Bot SDK was
failing with:
```
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get certificate CRL)
```

This occurs because the LINE Bot SDK tries to fetch user profiles via
HTTPS, and OpenSSL on macOS development environments may not have proper
access to Certificate Revocation Lists (CRLs).

## Changes

- Added `http_options` configuration to the LINE Bot client in
`Channel::Line#client`
- Sets `verify_mode: OpenSSL::SSL::VERIFY_NONE` only when
`Rails.env.development?` is true
- Production environments continue to use full SSL verification for
security

## Test Plan

- [x] Send a LINE message to trigger webhook in development
- [x] Verify webhook is processed without SSL errors
- [x] Confirm change only applies in development mode

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-11-26 22:38:26 +05:30
Muhsin Keloth
73ad27e94c fix: Show WhatsApp templates only for inboxes with templates (#12965)
Fixed the logic to show WhatsApp templates option only for inboxes that have templates available.
2025-11-26 21:01:31 +05:30
Muhsin Keloth
6a83cad69d fix: Prevent WhatsApp campaign duplicate messages by updating status immediately (#12955)
Fixes
https://linear.app/chatwoot/issue/CW-5918/whatsapp-campaigns-running-in-parallel-and-duplicating-messages
2025-11-26 15:25:49 +05:30
Gabriel Jablonski
7e0507e3b5 fix: invalid language tag in heatmap component in reports page (#12952)
## Description

This PR fixes a `RangeError: Invalid language tag` that occurs in the
Heatmap report when using locales with underscores (e.g., `pt_BR`,
`zh_TW`).

The issue was caused by passing the raw locale string from `vue-i18n`
(which uses underscores for some regions) directly to
`Intl.DateTimeFormat`. The `Intl` API expects BCP 47 language tags which
use hyphens (e.g., `pt-BR`).

This change sanitizes the locale string by replacing underscores with
hyphens before creating the `DateTimeFormat` instance.

Fixes #12951
2025-11-26 13:24:29 +05:30
Vinay Keerthi
94a9e4e067 chore: Add custom RuboCop cop to enforce one class per file (#12947) 2025-11-26 12:53:04 +05:30
Shivam Mishra
7b20ecd27b chore: Revert pagination formatting and pluralization (#12954) 2025-11-25 21:36:13 +05:30
Gabriel Jablonski
e635122ff6 fix: add presence validation for account name (#12636)
## Description

When a user tries creating a new account through the Super Admin
dashboard, and they forget to fill in the account name, they're faced
with an ugly error (generic "Something went wrong" on production).

This PR simply adds the `validates :name, presence: true` model
validation on `Account` model, which is translated as a proper error
message on the Super Admin UI.
2025-11-25 20:11:15 +05:30
Aakash Bakhle
fa07b9158a fix: switch label suggestions to gpt-5-nano (#12945) 2025-11-25 19:36:47 +05:30
Sivin Varghese
46eb6f39f3 fix: Resolve z-index issue in assistant switcher (#12940) 2025-11-25 18:47:31 +05:30
Sivin Varghese
f0538b25ed fix: Reactive assistantId issue in Captain Inbox after route changes (#12939) 2025-11-25 18:47:18 +05:30
Shivam Mishra
389b864020 fix: click event for billing support (#12942) 2025-11-25 14:53:27 +05:30
Sivin Varghese
26778156dc chore: Improve pagination with compact number formatting and pluralization (#12921)
# Pull Request Template

## Description

This PR enhances the pagination component with standardized number
formatting and improved i18n handling.

**Includes:**

* Added `formatCompactNumber` and `formatFullNumber` helpers using
`Intl.NumberFormat`.
    * `< 1,000`: show exact value (e.g., `999`)
    * `1,000–999,999`: show compact format (`1k`, `1k+`)
    * `1,000,000+`: show in millions with one decimal (e.g., `1.2M`)
* Updated `PaginationFooter` to use the new formatters for all displayed
numbers.
  * Added proper pluralization to pagination i18n strings.

Fixes
https://linear.app/chatwoot/issue/CW-5999/better-display-of-numbers

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

### Screenshoots

**Before**
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/9fcf8baa-ae32-4a8a-85b0-24002fd863db"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/3d7138b7-133e-4ae6-b55f-67eff73ff1cc"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/1bbf7070-0681-492d-9308-a33874052d28"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/4e441672-26aa-4e66-965e-9edb807eaa72"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/11836702-1b74-4834-8932-31c20adc2db8"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/d37971bc-09af-4238-8601-ccc2ae69dbe7"
/>


**After**
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/8eaf2a23-beea-486b-b555-37f8b36ab904"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/f44f508a-e39d-45cb-afd8-98deb26920f8"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/d3b90711-bd7e-44ee-8bb3-48e45b799420"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/30dca6cd-f2be-4dcb-8596-924326ebf8c0"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/58896699-1f05-46c9-88cb-908318e71476"
/>
<img width="991" height="69" alt="image"
src="https://github.com/user-attachments/assets/ea0d91b0-077b-4d72-81a7-d38d17742da6"
/>




## 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
2025-11-24 17:49:24 -08:00
Sojan Jose
48627da0f9 feat: outbound voice call essentials (#12782)
- Enables outbound voice calls in voice channel . We are only caring
about wiring the logic to trigger outgoing calls to the call button
introduced in previous PRs. We will connect it to call component in
subsequent PRs

ref: #11602 

## Screens

<img width="2304" height="1202" alt="image"
src="https://github.com/user-attachments/assets/b91543a8-8d4e-4229-bd80-9727b42c7b0f"
/>

<img width="2304" height="1200" alt="image"
src="https://github.com/user-attachments/assets/1a1dad2a-8cb2-4aa2-9702-c062416556a7"
/>

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
2025-11-24 17:47:00 -08:00
Sivin Varghese
6a712b7592 fix: Update Arcade embed aspect ratio (#12923) 2025-11-24 20:22:27 +05:30
Aakash Bakhle
e9c60aec04 feat: Add support for Langfuse LLM Tracing via OTEL (#12905)
This PR adds LLM instrumentation on langfuse for ai-editor feature

## Type of change
New feature (non-breaking change which adds functionality)

Needs langfuse account and env vars to be set

## How Has This Been Tested?

I configured personal langfuse credentials and instrumented the app,
traces can be seen in langfuse.
each conversation is one session. 
<img width="1683" height="714" alt="image"
src="https://github.com/user-attachments/assets/3fcba1c9-63cf-44b9-a355-fd6608691559"
/>
<img width="1446" height="172" alt="image"
src="https://github.com/user-attachments/assets/dfa6e98f-4741-4e04-9a9e-078d1f01e97b"
/>


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

---------

Co-authored-by: aakashb95 <aakash@chatwoot.com>
Co-authored-by: Vishnu Narayanan <iamwishnu@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
2025-11-21 16:31:45 -08:00
Vishnu Narayanan
a8e9acfae9 fix: shopify and leadsquared specs in ci (#12926)
fix: shopify and leadsquared specs in ci
2025-11-21 17:01:03 +05:30
Vishnu Narayanan
f5908b0f8a fix: test failures due to parallelisation in ci (#12924) 2025-11-21 16:33:29 +05:30
Sivin Varghese
45fa697885 chore: Hide pagination for empty company list (#12920) 2025-11-21 12:23:01 +05:30
Sivin Varghese
51fbf583b6 fix: Companies card pluralization issue (#12919) 2025-11-21 12:22:02 +05:30
Sivin Varghese
38d6ee6dd2 chore: Save company list sorting preferences in UI settings (#12916)
# Pull Request Template

## Description

This PR saves the company list sorting preferences (field and order) in
the user’s UI settings. The sort state is initialized from the stored
preferences when the component mounts, defaulting to `-created_at` if
none exist.

Fixes
https://linear.app/chatwoot/issue/CW-5992/save-sort-filter-to-ui-settings

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


## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
2025-11-20 16:51:27 -08:00
Vishnu Narayanan
a547c28c8d fix: reduce sidekiq memorymax to 1.2gb (#12915)
- reduce sidekiq memorymax to 1.2GB to ensure OOM restarts work on a 2GB
machine
2025-11-20 21:20:42 +05:30
Rob Coenen
5608f5a1a2 fix: Widget shows 'away' on initial load despite agents being online (#12869)
## Description

Fixes #12868

This PR fixes a Vue 3 reactivity bug that causes the widget to display
"We are away at the moment" on initial page load, even when agents are
online and the API correctly returns their availability.

## Problem

The widget welcome screen shows "We are away" on first render, only
updating to show correct agent status after navigating to the
conversation view and back. This misleads visitors into thinking no
agents are available.

**Reproduction:** Open website with widget in fresh incognito window,
click bubble immediately → shows "away" despite agents being online.

## Root Cause

Vue 3 reactivity chain breaks in the `useAvailability` composable:

**Before (broken):**
```javascript
// AvailabilityContainer.vue
const { isOnline } = useAvailability(props.agents); // Passes VALUE

// useAvailability.js  
const availableAgents = toRef(agents); // Creates ref from VALUE, doesn't track changes
```

When the API responds and updates the Vuex store, the parent component's
computed `props.agents` updates correctly, but the composable's
`toRef()` doesn't know about the change because it was created from a
static value, not a reactive source.

## Solution

**After (fixed):**
```javascript
// AvailabilityContainer.vue
const { isOnline } = useAvailability(toRef(props, 'agents')); // Passes REACTIVE REF

// useAvailability.js
const availableAgents = computed(() => unref(agents)); // Unwraps ref and tracks changes
```

Now when `props.agents` updates after the API response, the `computed()`
re-evaluates and all downstream reactive properties (`hasOnlineAgents`,
`isOnline`) update correctly.

## Testing

-  Initial page load shows correct agent status immediately
-  Status changes via WebSocket update correctly  
-  No configuration changes or workarounds needed
-  Tested with network monitoring (Puppeteer) confirming API returns
correct data

## Files Changed

1.
`app/javascript/widget/components/Availability/AvailabilityContainer.vue`
   - Pass `toRef(props, 'agents')` instead of `props.agents`

2. `app/javascript/widget/composables/useAvailability.js`
   - Use `computed(() => unref(agents))` instead of `toRef(agents)`
   - Added explanatory comments

## Related Issues

- #5918 - Similar symptoms, closed with workaround (business hours
toggle) rather than fixing root cause
- #5763 - Different issue (mobile app presence)

This is a genuine Vue 3 reactivity bug affecting all widgets,
independent of business hours configuration.

Co-authored-by: rcoenen <rcoenen@users.noreply.github.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2025-11-20 20:27:44 +05:30
Shivam Mishra
da4110a495 feat: add retry loadWithRetry composable (#12873) 2025-11-20 19:40:20 +05:30
Vinay Keerthi
9a2136caf1 fix: Change messages.source_id to text column (#12908)
## Summary
Changes `messages.source_id` from `string` (255 char limit) to `text`
(20,000 char limit) to support long email Message-ID headers.

## Changes
- Migration to change column type from string to text
- Added spec tests for source_id length validation

## Related
Fixes
https://linear.app/chatwoot/issue/CW-5961/activerecordrecordinvalid-validation-failed-source-is-too-long-maximum
2025-11-20 11:41:41 +05:30
Shivam Mishra
a44192bbe7 feat: remove captain v2 from chatwoot internal list (#12903) 2025-11-19 17:49:47 +05:30
Vishnu Narayanan
5a5b30fe1e chore: increment CW version (#12902)
fixes https://github.com/chatwoot/chatwoot/issues/12889
2025-11-19 17:10:01 +05:30