From ee7187d2ed8af51a0af9afcbb7ba45fc6fd45886 Mon Sep 17 00:00:00 2001 From: Tanmay Deep Sharma <32020192+tds-1@users.noreply.github.com> Date: Wed, 14 Jan 2026 18:00:12 +0530 Subject: [PATCH 1/2] fix: prevent deserialization error on deletion (#13264) --- app/listeners/action_cable_listener.rb | 7 +++++-- app/models/contact.rb | 16 ++++++++++------ spec/listeners/action_cable_listener_spec.rb | 5 +++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/listeners/action_cable_listener.rb b/app/listeners/action_cable_listener.rb index 48b7a3aa9..61aa4f535 100644 --- a/app/listeners/action_cable_listener.rb +++ b/app/listeners/action_cable_listener.rb @@ -159,8 +159,11 @@ class ActionCableListener < BaseListener end def contact_deleted(event) - contact, account = extract_contact_and_account(event) - broadcast(account, [account_token(account)], CONTACT_DELETED, contact.push_event_data) + contact_data = event.data[:contact_data] + account = Account.find_by(id: contact_data[:account_id]) + return if account.blank? + + broadcast(account, [account_token(account)], CONTACT_DELETED, contact_data) end def conversation_mentioned(event) diff --git a/app/models/contact.rb b/app/models/contact.rb index 0dc92b51e..3badf478d 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -179,11 +179,9 @@ class Contact < ApplicationRecord end def self.resolved_contacts(use_crm_v2: false) - if use_crm_v2 - where(contact_type: 'lead') - else - where("contacts.email <> '' OR contacts.phone_number <> '' OR contacts.identifier <> ''") - end + return where(contact_type: 'lead') if use_crm_v2 + + where("contacts.email <> '' OR contacts.phone_number <> '' OR contacts.identifier <> ''") end def discard_invalid_attrs @@ -243,7 +241,13 @@ class Contact < ApplicationRecord end def dispatch_destroy_event - Rails.configuration.dispatcher.dispatch(CONTACT_DELETED, Time.zone.now, contact: self) + # Pass serialized data instead of ActiveRecord object to avoid DeserializationError + # when the async EventDispatcherJob runs after the contact has been deleted + Rails.configuration.dispatcher.dispatch( + CONTACT_DELETED, + Time.zone.now, + contact_data: push_event_data.merge(account_id: account_id) + ) end end Contact.include_mod_with('Concerns::Contact') diff --git a/spec/listeners/action_cable_listener_spec.rb b/spec/listeners/action_cable_listener_spec.rb index 61f818da1..1aecc3779 100644 --- a/spec/listeners/action_cable_listener_spec.rb +++ b/spec/listeners/action_cable_listener_spec.rb @@ -117,13 +117,14 @@ describe ActionCableListener do describe '#contact_deleted' do let(:event_name) { :'contact.deleted' } let!(:contact) { create(:contact, account: account) } - let!(:event) { Events::Base.new(event_name, Time.zone.now, contact: contact) } + let(:contact_data) { contact.push_event_data.merge(account_id: contact.account_id) } + let!(:event) { Events::Base.new(event_name, Time.zone.now, contact_data: contact_data) } it 'sends message to account admins, inbox agents' do expect(ActionCableBroadcastJob).to receive(:perform_later).with( ["account_#{account.id}"], 'contact.deleted', - contact.push_event_data.merge(account_id: account.id) + contact_data ) listener.contact_deleted(event) end From 8eb0558b0a7c4a0a95100d7fc1adae27450aa44b Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Wed, 14 Jan 2026 17:33:02 +0400 Subject: [PATCH 2/2] fix: Case-insensitive language matching for WhatsApp template messages (#13269) Fixes https://github.com/chatwoot/chatwoot/issues/13257 When sending WhatsApp template messages via API with `processed_params`, users receiving error `(#132000) Number of parameters does not match the expected number of params` from WhatsApp. The find template method performed case-sensitive string comparison on language codes. If a user sent `language: "ES"` but the template was stored as `language: "es"`, the template wouldn't be found, resulting in empty `components: []` being sent to WhatsApp. --- app/services/whatsapp/template_processor_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/whatsapp/template_processor_service.rb b/app/services/whatsapp/template_processor_service.rb index 4a89d684a..0aaca2fb1 100644 --- a/app/services/whatsapp/template_processor_service.rb +++ b/app/services/whatsapp/template_processor_service.rb @@ -20,7 +20,9 @@ class Whatsapp::TemplateProcessorService def find_template channel.message_templates.find do |t| - t['name'] == template_params['name'] && t['language'] == template_params['language'] && t['status']&.downcase == 'approved' + t['name'] == template_params['name'] && + t['language']&.downcase == template_params['language']&.downcase && + t['status']&.downcase == 'approved' end end