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
|
||||
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
|
||||
|
||||
def create_new_conversation
|
||||
|
||||
@ -114,7 +114,7 @@ class Whatsapp::IncomingMessageBaseService
|
||||
def set_conversation
|
||||
# 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
|
||||
@contact_inbox.conversations.last
|
||||
@inbox.conversations.where(contact_id: @contact_inbox.contact_id).last
|
||||
else
|
||||
@contact_inbox.conversations
|
||||
.where.not(status: :resolved).last
|
||||
|
||||
@ -44,8 +44,8 @@ describe ConversationBuilder do
|
||||
end
|
||||
|
||||
it 'returns last from existing sms conversations when existing conversation is not present' do
|
||||
create(:conversation, contact_inbox: contact_sms_inbox)
|
||||
existing_conversation = 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, contact: contact, inbox: sms_inbox)
|
||||
conversation = described_class.new(
|
||||
contact_inbox: contact_sms_inbox,
|
||||
params: {}
|
||||
@ -70,8 +70,8 @@ describe ConversationBuilder do
|
||||
end
|
||||
|
||||
it 'returns last from existing api conversations when existing conversation is not present' do
|
||||
create(:conversation, contact_inbox: contact_api_inbox)
|
||||
existing_conversation = 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, contact: contact, inbox: api_inbox)
|
||||
conversation = described_class.new(
|
||||
contact_inbox: contact_api_inbox,
|
||||
params: {}
|
||||
@ -80,5 +80,23 @@ describe ConversationBuilder do
|
||||
expect(conversation.id).to eq(existing_conversation.id)
|
||||
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
|
||||
|
||||
@ -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
|
||||
whatsapp_channel.inbox.update!(lock_to_single_conversation: true)
|
||||
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')
|
||||
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
||||
# 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'
|
||||
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
|
||||
|
||||
describe '#process_received_callback' do
|
||||
|
||||
Loading…
Reference in New Issue
Block a user