fix: Duplicate instagram conversations for echo messages (#7078)

This commit is contained in:
Tejaswini Chile
2023-05-15 16:25:15 +05:30
committed by GitHub
parent 7dd1562b40
commit 65e91f6a6f
5 changed files with 90 additions and 7 deletions

View File

@@ -63,7 +63,9 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder
end end
def conversation def conversation
@conversation ||= Conversation.find_by(conversation_params) || build_conversation @conversation ||= Conversation.where(
"additional_attributes ->> 'type' = 'instagram_direct_message'"
).find_by(conversation_params) || build_conversation
end end
def message_content def message_content
@@ -95,7 +97,8 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder
def build_conversation def build_conversation
@contact_inbox ||= contact.contact_inboxes.find_by!(source_id: message_source_id) @contact_inbox ||= contact.contact_inboxes.find_by!(source_id: message_source_id)
Conversation.create!(conversation_params.merge( Conversation.create!(conversation_params.merge(
contact_inbox_id: @contact_inbox.id contact_inbox_id: @contact_inbox.id,
additional_attributes: { type: 'instagram_direct_message' }
)) ))
end end
@@ -103,10 +106,7 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder
{ {
account_id: @inbox.account_id, account_id: @inbox.account_id,
inbox_id: @inbox.id, inbox_id: @inbox.id,
contact_id: contact.id, contact_id: contact.id
additional_attributes: {
type: 'instagram_direct_message'
}
} }
end end

View File

@@ -14,7 +14,7 @@ class Webhooks::InstagramEventsJob < ApplicationJob
@entries.each do |entry| @entries.each do |entry|
entry = entry.with_indifferent_access entry = entry.with_indifferent_access
entry[:messaging].each do |messaging| messages(entry).each do |messaging|
send(@event_name, messaging) if event_name(messaging) send(@event_name, messaging) if event_name(messaging)
end end
end end
@@ -29,4 +29,8 @@ class Webhooks::InstagramEventsJob < ApplicationJob
def message(messaging) def message(messaging)
::Instagram::MessageText.new(messaging).perform ::Instagram::MessageText.new(messaging).perform
end end
def messages(entry)
(entry[:messaging].presence || entry[:standby])
end
end end

View File

@@ -17,6 +17,14 @@ describe ::Messages::Instagram::MessageBuilder do
let(:fb_object) { double } let(:fb_object) { double }
let(:contact) { create(:contact, id: 'Sender-id-1', name: 'Jane Dae') } let(:contact) { create(:contact, id: 'Sender-id-1', name: 'Jane Dae') }
let(:contact_inbox) { create(:contact_inbox, contact_id: contact.id, inbox_id: instagram_inbox.id, source_id: 'Sender-id-1') } let(:contact_inbox) { create(:contact_inbox, contact_id: contact.id, inbox_id: instagram_inbox.id, source_id: 'Sender-id-1') }
let(:conversation) do
create(:conversation, account_id: account.id, inbox_id: instagram_inbox.id, contact_id: contact.id,
additional_attributes: { type: 'instagram_direct_message', conversation_language: 'en' })
end
let(:message) do
create(:message, account_id: account.id, inbox_id: instagram_inbox.id, conversation_id: conversation.id, message_type: 'outgoing',
source_id: 'message-id-1')
end
describe '#perform' do describe '#perform' do
it 'creates contact and message for the facebook inbox' do it 'creates contact and message for the facebook inbox' do
@@ -45,6 +53,31 @@ describe ::Messages::Instagram::MessageBuilder do
expect(message.content).to eq('This is the first message from the customer') expect(message.content).to eq('This is the first message from the customer')
end end
it 'discard echo message already sent by chatwoot' do
message
expect(instagram_inbox.conversations.count).to be 1
expect(instagram_inbox.messages.count).to be 1
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_return(
{
name: 'Jane',
id: 'Sender-id-1',
account_id: instagram_inbox.account_id,
profile_pic: 'https://chatwoot-assets.local/sample.png'
}.with_indifferent_access
)
messaging = dm_params[:entry][0]['messaging'][0]
contact_inbox
described_class.new(messaging, instagram_inbox, outgoing_echo: true).perform
instagram_inbox.reload
expect(instagram_inbox.conversations.count).to be 1
expect(instagram_inbox.messages.count).to be 1
end
it 'creates message with for reply with story id' do it 'creates message with for reply with story id' do
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object) allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_return( allow(fb_object).to receive(:get_object).and_return(

View File

@@ -26,6 +26,33 @@ FactoryBot.define do
initialize_with { attributes } initialize_with { attributes }
end end
factory :instagram_message_standby_event, class: Hash do
entry do
[
{
'time': '2021-09-08T06:34:04+0000',
'id': 'instagram-message-id-123',
'standby': [
{
'sender': {
'id': 'Sender-id-1'
},
'recipient': {
'id': 'chatwoot-app-user-id-1'
},
'timestamp': '2021-09-08T06:34:04+0000',
'message': {
'mid': 'message-id-1',
'text': 'This is the first standby message from the customer, after 24 hours.'
}
}
]
}
]
end
initialize_with { attributes }
end
factory :instagram_story_reply_event, class: Hash do factory :instagram_story_reply_event, class: Hash do
entry do entry do
[ [

View File

@@ -21,6 +21,7 @@ describe Webhooks::InstagramEventsJob do
let!(:instagram_channel) { create(:channel_instagram_fb_page, account: account, instagram_id: 'chatwoot-app-user-id-1') } let!(:instagram_channel) { create(:channel_instagram_fb_page, account: account, instagram_id: 'chatwoot-app-user-id-1') }
let!(:instagram_inbox) { create(:inbox, channel: instagram_channel, account: account, greeting_enabled: false) } let!(:instagram_inbox) { create(:inbox, channel: instagram_channel, account: account, greeting_enabled: false) }
let!(:dm_params) { build(:instagram_message_create_event).with_indifferent_access } let!(:dm_params) { build(:instagram_message_create_event).with_indifferent_access }
let!(:standby_params) { build(:instagram_message_standby_event).with_indifferent_access }
let!(:test_params) { build(:instagram_test_text_event).with_indifferent_access } let!(:test_params) { build(:instagram_test_text_event).with_indifferent_access }
let!(:unsend_event) { build(:instagram_message_unsend_event).with_indifferent_access } let!(:unsend_event) { build(:instagram_message_unsend_event).with_indifferent_access }
let!(:attachment_params) { build(:instagram_message_attachment_event).with_indifferent_access } let!(:attachment_params) { build(:instagram_message_attachment_event).with_indifferent_access }
@@ -45,6 +46,24 @@ describe Webhooks::InstagramEventsJob do
expect(instagram_inbox.messages.count).to be 1 expect(instagram_inbox.messages.count).to be 1
end end
it 'creates standby message in the instagram inbox' do
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_return(
return_object.with_indifferent_access
)
instagram_webhook.perform_now(standby_params[:entry])
instagram_inbox.reload
expect(instagram_inbox.contacts.count).to be 1
expect(instagram_inbox.contacts.last.additional_attributes['social_profiles']['instagram']).to eq 'some_user_name'
expect(instagram_inbox.conversations.count).to be 1
expect(instagram_inbox.messages.count).to be 1
message = instagram_inbox.messages.last
expect(message.content).to eq('This is the first standby message from the customer, after 24 hours.')
end
it 'creates test text message in the instagram inbox' do it 'creates test text message in the instagram inbox' do
allow(Koala::Facebook::API).to receive(:new).and_return(fb_object) allow(Koala::Facebook::API).to receive(:new).and_return(fb_object)
allow(fb_object).to receive(:get_object).and_return( allow(fb_object).to receive(:get_object).and_return(