fix(whatsapp): update conversation lookup to handle multiple contact inboxes in single conversation mode (#197)
* fix(whatsapp): update conversation lookup to handle multiple contact inboxes in single conversation mode * fix(whatsapp): update conversation retrieval logic to ensure correct conversation is reopened
This commit is contained in:
parent
b5d3250a2a
commit
b1aaf58097
@ -10,7 +10,7 @@ class ConversationBuilder
|
|||||||
def look_up_exising_conversation
|
def look_up_exising_conversation
|
||||||
return unless @contact_inbox.inbox.lock_to_single_conversation?
|
return unless @contact_inbox.inbox.lock_to_single_conversation?
|
||||||
|
|
||||||
@contact_inbox.conversations.last
|
@contact_inbox.inbox.conversations.where(contact_id: @contact_inbox.contact_id).last
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_new_conversation
|
def create_new_conversation
|
||||||
|
|||||||
@ -114,7 +114,7 @@ class Whatsapp::IncomingMessageBaseService
|
|||||||
def set_conversation
|
def set_conversation
|
||||||
# if lock to single conversation is disabled, we will create a new conversation if previous conversation is resolved
|
# if lock to single conversation is disabled, we will create a new conversation if previous conversation is resolved
|
||||||
@conversation = if @inbox.lock_to_single_conversation
|
@conversation = if @inbox.lock_to_single_conversation
|
||||||
@contact_inbox.conversations.last
|
@inbox.conversations.where(contact_id: @contact_inbox.contact_id).last
|
||||||
else
|
else
|
||||||
@contact_inbox.conversations
|
@contact_inbox.conversations
|
||||||
.where.not(status: :resolved).last
|
.where.not(status: :resolved).last
|
||||||
|
|||||||
@ -44,8 +44,8 @@ describe ConversationBuilder do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'returns last from existing sms conversations when existing conversation is not present' do
|
it 'returns last from existing sms conversations when existing conversation is not present' do
|
||||||
create(:conversation, contact_inbox: contact_sms_inbox)
|
create(:conversation, contact_inbox: contact_sms_inbox, contact: contact, inbox: sms_inbox)
|
||||||
existing_conversation = create(:conversation, contact_inbox: contact_sms_inbox)
|
existing_conversation = create(:conversation, contact_inbox: contact_sms_inbox, contact: contact, inbox: sms_inbox)
|
||||||
conversation = described_class.new(
|
conversation = described_class.new(
|
||||||
contact_inbox: contact_sms_inbox,
|
contact_inbox: contact_sms_inbox,
|
||||||
params: {}
|
params: {}
|
||||||
@ -70,8 +70,8 @@ describe ConversationBuilder do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'returns last from existing api conversations when existing conversation is not present' do
|
it 'returns last from existing api conversations when existing conversation is not present' do
|
||||||
create(:conversation, contact_inbox: contact_api_inbox)
|
create(:conversation, contact_inbox: contact_api_inbox, contact: contact, inbox: api_inbox)
|
||||||
existing_conversation = create(:conversation, contact_inbox: contact_api_inbox)
|
existing_conversation = create(:conversation, contact_inbox: contact_api_inbox, contact: contact, inbox: api_inbox)
|
||||||
conversation = described_class.new(
|
conversation = described_class.new(
|
||||||
contact_inbox: contact_api_inbox,
|
contact_inbox: contact_api_inbox,
|
||||||
params: {}
|
params: {}
|
||||||
@ -80,5 +80,23 @@ describe ConversationBuilder do
|
|||||||
expect(conversation.id).to eq(existing_conversation.id)
|
expect(conversation.id).to eq(existing_conversation.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when lock_to_single_conversation is true for whatsapp inbox with multiple contact_inboxes' do
|
||||||
|
let!(:whatsapp_channel) { create(:channel_whatsapp, account: account, sync_templates: false, validate_provider_config: false) }
|
||||||
|
let!(:whatsapp_inbox) { whatsapp_channel.inbox }
|
||||||
|
let(:contact_with_phone) { create(:contact, account: account, phone_number: '+5511912345678') }
|
||||||
|
|
||||||
|
before { whatsapp_inbox.update!(lock_to_single_conversation: true) }
|
||||||
|
|
||||||
|
it 'finds conversation from different contact_inbox with same contact' do
|
||||||
|
lid_contact_inbox = create(:contact_inbox, contact: contact_with_phone, inbox: whatsapp_inbox, source_id: '12345678')
|
||||||
|
existing_conversation = create(:conversation, contact_inbox: lid_contact_inbox, inbox: whatsapp_inbox, contact: contact_with_phone)
|
||||||
|
phone_contact_inbox = create(:contact_inbox, contact: contact_with_phone, inbox: whatsapp_inbox, source_id: '5511912345678')
|
||||||
|
|
||||||
|
conversation = described_class.new(contact_inbox: phone_contact_inbox, params: {}).perform
|
||||||
|
|
||||||
|
expect(conversation.id).to eq(existing_conversation.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -44,7 +44,7 @@ describe Whatsapp::IncomingMessageService do
|
|||||||
it 'reopen last conversation if last conversation is resolved and lock to single conversation is enabled' do
|
it 'reopen last conversation if last conversation is resolved and lock to single conversation is enabled' do
|
||||||
whatsapp_channel.inbox.update!(lock_to_single_conversation: true)
|
whatsapp_channel.inbox.update!(lock_to_single_conversation: true)
|
||||||
contact_inbox = create(:contact_inbox, inbox: whatsapp_channel.inbox, source_id: params[:messages].first[:from])
|
contact_inbox = create(:contact_inbox, inbox: whatsapp_channel.inbox, source_id: params[:messages].first[:from])
|
||||||
last_conversation = create(:conversation, inbox: whatsapp_channel.inbox, contact_inbox: contact_inbox)
|
last_conversation = create(:conversation, inbox: whatsapp_channel.inbox, contact_inbox: contact_inbox, contact: contact_inbox.contact)
|
||||||
last_conversation.update!(status: 'resolved')
|
last_conversation.update!(status: 'resolved')
|
||||||
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
||||||
# no new conversation should be created
|
# no new conversation should be created
|
||||||
|
|||||||
@ -541,6 +541,61 @@ describe Whatsapp::ZapiHandlers::ReceivedCallback do
|
|||||||
it_behaves_like 'routes messages to the new conversation', first_msg_id: 'msg_003', second_msg_id: 'msg_004'
|
it_behaves_like 'routes messages to the new conversation', first_msg_id: 'msg_003', second_msg_id: 'msg_004'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'single conversation mode' do
|
||||||
|
let(:phone) { '5511912345678' }
|
||||||
|
let(:lid) { '12345678' }
|
||||||
|
|
||||||
|
before { inbox.update!(lock_to_single_conversation: true) }
|
||||||
|
|
||||||
|
def build_params(message_id:, text:)
|
||||||
|
{
|
||||||
|
type: 'ReceivedCallback',
|
||||||
|
messageId: message_id,
|
||||||
|
momment: Time.current.to_i * 1000,
|
||||||
|
fromMe: false,
|
||||||
|
phone: phone,
|
||||||
|
chatLid: "#{lid}@lid",
|
||||||
|
chatName: 'John Doe',
|
||||||
|
text: { message: text }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'reopens resolved conversation when contact sends new message' do
|
||||||
|
Whatsapp::IncomingMessageZapiService.new(inbox: inbox, params: build_params(message_id: 'msg_1', text: 'First')).perform
|
||||||
|
conversation = Conversation.last
|
||||||
|
conversation.update!(status: :resolved)
|
||||||
|
|
||||||
|
expect { Whatsapp::IncomingMessageZapiService.new(inbox: inbox, params: build_params(message_id: 'msg_2', text: 'Second')).perform }
|
||||||
|
.not_to change(Conversation, :count)
|
||||||
|
|
||||||
|
expect(conversation.reload.status).to eq('open')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'migrates phone source_id to LID and routes to existing conversation' do
|
||||||
|
contact = create(:contact, account: inbox.account, phone_number: "+#{phone}")
|
||||||
|
contact_inbox = create(:contact_inbox, inbox: inbox, contact: contact, source_id: phone)
|
||||||
|
conversation = create(:conversation, inbox: inbox, contact: contact, contact_inbox: contact_inbox)
|
||||||
|
|
||||||
|
Whatsapp::IncomingMessageZapiService.new(inbox: inbox, params: build_params(message_id: 'msg_3', text: 'Response')).perform
|
||||||
|
|
||||||
|
expect(contact_inbox.reload.source_id).to eq(lid)
|
||||||
|
expect(conversation.messages.count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds conversation via ConversationBuilder when agent creates new contact_inbox with phone' do
|
||||||
|
Whatsapp::IncomingMessageZapiService.new(inbox: inbox, params: build_params(message_id: 'msg_4', text: 'Hello')).perform
|
||||||
|
first_conversation = Conversation.last
|
||||||
|
first_conversation.update!(status: :resolved)
|
||||||
|
|
||||||
|
contact = Contact.last
|
||||||
|
phone_contact_inbox = ContactInboxBuilder.new(contact: contact, inbox: inbox, source_id: nil).perform
|
||||||
|
|
||||||
|
conversation = ConversationBuilder.new(params: ActionController::Parameters.new({}), contact_inbox: phone_contact_inbox).perform
|
||||||
|
|
||||||
|
expect(conversation.id).to eq(first_conversation.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#process_received_callback' do
|
describe '#process_received_callback' do
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user