feat: extending lock to single conversation to meta inbox (#9104)
This change introduces the ability to lock conversations to a single thread for Instagram and facebook messages within the Meta inbox, mirroring existing functionality in WhatsApp and SMS inboxes. Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6b7a707fef
commit
e21d7552d3
@@ -53,7 +53,23 @@ class Messages::Facebook::MessageBuilder < Messages::Messenger::MessageBuilder
|
||||
end
|
||||
|
||||
def conversation
|
||||
@conversation ||= Conversation.find_by(conversation_params) || build_conversation
|
||||
@conversation ||= set_conversation_based_on_inbox_config
|
||||
end
|
||||
|
||||
def set_conversation_based_on_inbox_config
|
||||
if @inbox.lock_to_single_conversation
|
||||
Conversation.where(conversation_params).order(created_at: :desc).first || build_conversation
|
||||
else
|
||||
find_or_build_for_multiple_conversations
|
||||
end
|
||||
end
|
||||
|
||||
def find_or_build_for_multiple_conversations
|
||||
# If lock to single conversation is disabled, we will create a new conversation if previous conversation is resolved
|
||||
last_conversation = Conversation.where(conversation_params).where.not(status: :resolved).order(created_at: :desc).first
|
||||
return build_conversation if last_conversation.nil?
|
||||
|
||||
last_conversation
|
||||
end
|
||||
|
||||
def build_conversation
|
||||
|
||||
@@ -69,9 +69,28 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder
|
||||
end
|
||||
|
||||
def conversation
|
||||
@conversation ||= Conversation.where(conversation_params).find_by(
|
||||
"additional_attributes ->> 'type' = 'instagram_direct_message'"
|
||||
) || build_conversation
|
||||
@conversation ||= set_conversation_based_on_inbox_config
|
||||
end
|
||||
|
||||
def instagram_direct_message_conversation
|
||||
Conversation.where(conversation_params)
|
||||
.where("additional_attributes ->> 'type' = 'instagram_direct_message'")
|
||||
end
|
||||
|
||||
def set_conversation_based_on_inbox_config
|
||||
if @inbox.lock_to_single_conversation
|
||||
instagram_direct_message_conversation.order(created_at: :desc).first || build_conversation
|
||||
else
|
||||
find_or_build_for_multiple_conversations
|
||||
end
|
||||
end
|
||||
|
||||
def find_or_build_for_multiple_conversations
|
||||
last_conversation = instagram_direct_message_conversation.where.not(status: :resolved).order(created_at: :desc).first
|
||||
|
||||
return build_conversation if last_conversation.nil?
|
||||
|
||||
last_conversation
|
||||
end
|
||||
|
||||
def message_content
|
||||
|
||||
@@ -589,7 +589,9 @@ export default {
|
||||
return this.inbox.name;
|
||||
},
|
||||
canLocktoSingleConversation() {
|
||||
return this.isASmsInbox || this.isAWhatsAppChannel;
|
||||
return (
|
||||
this.isASmsInbox || this.isAWhatsAppChannel || this.isAFacebookInbox
|
||||
);
|
||||
},
|
||||
inboxNameLabel() {
|
||||
if (this.isAWebWidgetInbox) {
|
||||
|
||||
@@ -58,5 +58,91 @@ describe Messages::Facebook::MessageBuilder do
|
||||
expect(facebook_channel.inbox.reload.contacts.count).to eq(1)
|
||||
expect(contact.name).to eq(default_name)
|
||||
end
|
||||
|
||||
context 'when lock to single conversation' do
|
||||
subject(:mocked_message_builder) do
|
||||
described_class.new(mocked_incoming_fb_text_message, facebook_channel.inbox).perform
|
||||
end
|
||||
|
||||
let!(:mocked_message_object) { build(:mocked_message_text, sender_id: contact_inbox.source_id).to_json }
|
||||
let!(:mocked_incoming_fb_text_message) { Integrations::Facebook::MessageParser.new(mocked_message_object) }
|
||||
let(:contact) { create(:contact, name: 'Jane Dae') }
|
||||
let(:contact_inbox) { create(:contact_inbox, contact_id: contact.id, inbox_id: facebook_channel.inbox.id) }
|
||||
|
||||
context 'when lock to single conversation is disabled' do
|
||||
before do
|
||||
facebook_channel.inbox.update!(lock_to_single_conversation: false)
|
||||
stub_request(:get, /graph.facebook.com/)
|
||||
end
|
||||
|
||||
it 'creates a new conversation if existing conversation is not present' do
|
||||
inital_count = Conversation.count
|
||||
|
||||
mocked_message_builder
|
||||
|
||||
facebook_channel.inbox.reload
|
||||
|
||||
expect(facebook_channel.inbox.conversations.count).to eq(1)
|
||||
expect(Conversation.count).to eq(inital_count + 1)
|
||||
end
|
||||
|
||||
it 'will not create a new conversation if last conversation is not resolved' do
|
||||
existing_conversation = create(:conversation, account_id: facebook_channel.inbox.account.id, inbox_id: facebook_channel.inbox.id,
|
||||
contact_id: contact.id, contact_inbox_id: contact_inbox.id,
|
||||
status: :open)
|
||||
|
||||
mocked_message_builder
|
||||
|
||||
facebook_channel.inbox.reload
|
||||
|
||||
expect(facebook_channel.inbox.conversations.last.id).to eq(existing_conversation.id)
|
||||
end
|
||||
|
||||
it 'creates a new conversation if last conversation is resolved' do
|
||||
existing_conversation = create(:conversation, account_id: facebook_channel.inbox.account.id, inbox_id: facebook_channel.inbox.id,
|
||||
contact_id: contact.id, contact_inbox_id: contact_inbox.id, status: :resolved)
|
||||
|
||||
inital_count = Conversation.count
|
||||
|
||||
mocked_message_builder
|
||||
|
||||
facebook_channel.inbox.reload
|
||||
|
||||
expect(facebook_channel.inbox.conversations.last.id).not_to eq(existing_conversation.id)
|
||||
expect(Conversation.count).to eq(inital_count + 1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when lock to single conversation is enabled' do
|
||||
before do
|
||||
facebook_channel.inbox.update!(lock_to_single_conversation: true)
|
||||
stub_request(:get, /graph.facebook.com/)
|
||||
end
|
||||
|
||||
it 'creates a new conversation if existing conversation is not present' do
|
||||
inital_count = Conversation.count
|
||||
mocked_message_builder
|
||||
|
||||
facebook_channel.inbox.reload
|
||||
|
||||
expect(facebook_channel.inbox.conversations.count).to eq(1)
|
||||
expect(Conversation.count).to eq(inital_count + 1)
|
||||
end
|
||||
|
||||
it 'reopens last conversation if last conversation exists' do
|
||||
existing_conversation = create(:conversation, account_id: facebook_channel.inbox.account.id, inbox_id: facebook_channel.inbox.id,
|
||||
contact_id: contact.id, contact_inbox_id: contact_inbox.id)
|
||||
|
||||
inital_count = Conversation.count
|
||||
|
||||
mocked_message_builder
|
||||
|
||||
facebook_channel.inbox.reload
|
||||
|
||||
expect(facebook_channel.inbox.conversations.last.id).to eq(existing_conversation.id)
|
||||
expect(Conversation.count).to eq(inital_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -183,4 +183,96 @@ describe Messages::Instagram::MessageBuilder do
|
||||
expect(contact.name).to eq('Jane Dae')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when lock to single conversation is disabled' do
|
||||
before do
|
||||
instagram_inbox.update!(lock_to_single_conversation: false)
|
||||
stub_request(:get, /graph.facebook.com/)
|
||||
end
|
||||
|
||||
it 'creates a new conversation if existing conversation is not present' do
|
||||
inital_count = Conversation.count
|
||||
message = dm_params[:entry][0]['messaging'][0]
|
||||
contact_inbox
|
||||
|
||||
described_class.new(message, instagram_inbox).perform
|
||||
|
||||
instagram_inbox.reload
|
||||
contact_inbox.reload
|
||||
|
||||
expect(instagram_inbox.conversations.count).to eq(1)
|
||||
expect(Conversation.count).to eq(inital_count + 1)
|
||||
end
|
||||
|
||||
it 'will not create a new conversation if last conversation is not resolved' do
|
||||
existing_conversation = create(:conversation, account_id: account.id, inbox_id: instagram_inbox.id, contact_id: contact.id, status: :open,
|
||||
additional_attributes: { type: 'instagram_direct_message', conversation_language: 'en' })
|
||||
|
||||
message = dm_params[:entry][0]['messaging'][0]
|
||||
contact_inbox
|
||||
|
||||
described_class.new(message, instagram_inbox).perform
|
||||
|
||||
instagram_inbox.reload
|
||||
contact_inbox.reload
|
||||
|
||||
expect(instagram_inbox.conversations.last.id).to eq(existing_conversation.id)
|
||||
end
|
||||
|
||||
it 'creates a new conversation if last conversation is resolved' do
|
||||
existing_conversation = create(:conversation, account_id: account.id, inbox_id: instagram_inbox.id, contact_id: contact.id, status: :resolved,
|
||||
additional_attributes: { type: 'instagram_direct_message', conversation_language: 'en' })
|
||||
|
||||
inital_count = Conversation.count
|
||||
message = dm_params[:entry][0]['messaging'][0]
|
||||
contact_inbox
|
||||
|
||||
described_class.new(message, instagram_inbox).perform
|
||||
|
||||
instagram_inbox.reload
|
||||
contact_inbox.reload
|
||||
|
||||
expect(instagram_inbox.conversations.last.id).not_to eq(existing_conversation.id)
|
||||
expect(Conversation.count).to eq(inital_count + 1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when lock to single conversation is enabled' do
|
||||
before do
|
||||
instagram_inbox.update!(lock_to_single_conversation: true)
|
||||
stub_request(:get, /graph.facebook.com/)
|
||||
end
|
||||
|
||||
it 'creates a new conversation if existing conversation is not present' do
|
||||
inital_count = Conversation.count
|
||||
message = dm_params[:entry][0]['messaging'][0]
|
||||
contact_inbox
|
||||
|
||||
described_class.new(message, instagram_inbox).perform
|
||||
|
||||
instagram_inbox.reload
|
||||
contact_inbox.reload
|
||||
|
||||
expect(instagram_inbox.conversations.count).to eq(1)
|
||||
expect(Conversation.count).to eq(inital_count + 1)
|
||||
end
|
||||
|
||||
it 'reopens last conversation if last conversation is resolved' do
|
||||
existing_conversation = create(:conversation, account_id: account.id, inbox_id: instagram_inbox.id, contact_id: contact.id, status: :resolved,
|
||||
additional_attributes: { type: 'instagram_direct_message', conversation_language: 'en' })
|
||||
|
||||
inital_count = Conversation.count
|
||||
|
||||
message = dm_params[:entry][0]['messaging'][0]
|
||||
contact_inbox
|
||||
|
||||
described_class.new(message, instagram_inbox).perform
|
||||
|
||||
instagram_inbox.reload
|
||||
contact_inbox.reload
|
||||
|
||||
expect(instagram_inbox.conversations.last.id).to eq(existing_conversation.id)
|
||||
expect(Conversation.count).to eq(inital_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,6 +11,21 @@ FactoryBot.define do
|
||||
initialize_with { attributes }
|
||||
end
|
||||
|
||||
factory :mocked_message_text, class: Hash do
|
||||
transient do
|
||||
sender_id { '3383290475046708' }
|
||||
end
|
||||
|
||||
initialize_with do
|
||||
{ messaging: { sender: { id: sender_id },
|
||||
recipient: { id: '117172741761305' },
|
||||
message: { mid: 'm_KXGKDUpO6xbVdAmZFBVpzU1AhKVJdAIUnUH4cwkvb_K3iZsWhowDRyJ_DcowEpJjncaBwdCIoRrixvCbbO1PcA',
|
||||
text: 'facebook message' } } }
|
||||
end
|
||||
|
||||
# initialize_with { attributes }
|
||||
end
|
||||
|
||||
factory :message_deliveries, class: Hash do
|
||||
messaging do
|
||||
{ sender: { id: '3383290475046708' },
|
||||
|
||||
Reference in New Issue
Block a user