feat: Add Instagram Channel (#2955)
This commit is contained in:
41
spec/builders/messages/instagram/message_builder_spec.rb
Normal file
41
spec/builders/messages/instagram/message_builder_spec.rb
Normal file
@@ -0,0 +1,41 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ::Messages::Instagram::MessageBuilder do
|
||||
subject(:instagram_message_builder) { described_class }
|
||||
|
||||
let!(:account) { create(:account) }
|
||||
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!(:dm_params) { build(:instagram_message_create_event).with_indifferent_access }
|
||||
let(:fb_object) { double }
|
||||
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') }
|
||||
|
||||
describe '#perform' do
|
||||
it 'creates contact and message for the facebook inbox' do
|
||||
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://via.placeholder.com/250x250.png'
|
||||
}.with_indifferent_access
|
||||
)
|
||||
messaging = dm_params[:entry][0]['messaging'][0]
|
||||
contact_inbox
|
||||
instagram_message_builder.new(messaging, instagram_inbox).perform
|
||||
|
||||
instagram_inbox.reload
|
||||
|
||||
expect(instagram_inbox.conversations.count).to be 1
|
||||
expect(instagram_inbox.messages.count).to be 1
|
||||
|
||||
contact = instagram_channel.inbox.contacts.first
|
||||
message = instagram_channel.inbox.messages.first
|
||||
|
||||
expect(contact.name).to eq('Jane Dae')
|
||||
expect(message.content).to eq('This is the first message from the customer')
|
||||
end
|
||||
end
|
||||
end
|
||||
10
spec/factories/channel/insatgram_channel.rb
Normal file
10
spec/factories/channel/insatgram_channel.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :channel_instagram_fb_page, class: 'Channel::FacebookPage' do
|
||||
page_access_token { SecureRandom.uuid }
|
||||
user_access_token { SecureRandom.uuid }
|
||||
page_id { SecureRandom.uuid }
|
||||
account
|
||||
end
|
||||
end
|
||||
58
spec/factories/instagram/instagram_message_create_event.rb
Normal file
58
spec/factories/instagram/instagram_message_create_event.rb
Normal file
@@ -0,0 +1,58 @@
|
||||
FactoryBot.define do
|
||||
factory :instagram_message_create_event, class: Hash do
|
||||
entry do
|
||||
[
|
||||
{
|
||||
'id': 'instagram-message-id-123',
|
||||
'time': '2021-09-08T06:34:04+0000',
|
||||
'messaging': [
|
||||
{
|
||||
'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 message from the customer'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
end
|
||||
initialize_with { attributes }
|
||||
end
|
||||
|
||||
factory :instagram_test_text_event, class: Hash do
|
||||
entry do
|
||||
[
|
||||
{
|
||||
'id': 'instagram-message-id-123',
|
||||
'time': '2021-09-08T06:34:04+0000',
|
||||
'changes': [
|
||||
{
|
||||
'field': 'messages',
|
||||
'value': {
|
||||
'event_type': 'TEXT',
|
||||
'event_timestamp': '1527459824',
|
||||
'event_data': {
|
||||
'message_id': 'vcvacopiufqwehfawdnb',
|
||||
'sender': {
|
||||
'username': 'sender_username'
|
||||
},
|
||||
'recipient': {
|
||||
'thread_id': 'faeoqiehrkbfadsfawd'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
end
|
||||
initialize_with { attributes }
|
||||
end
|
||||
end
|
||||
31
spec/factories/instagram_message/incoming_messages.rb
Normal file
31
spec/factories/instagram_message/incoming_messages.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :incoming_ig_text_message, class: Hash do
|
||||
messaging do
|
||||
[
|
||||
{
|
||||
'id': 'instagram-message-id-123',
|
||||
'time': '2021-09-08T06:34:04+0000',
|
||||
'messaging': [
|
||||
{
|
||||
'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 message from the customer'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
initialize_with { attributes }
|
||||
end
|
||||
end
|
||||
54
spec/jobs/webhooks/instagram_events_job_spec.rb
Normal file
54
spec/jobs/webhooks/instagram_events_job_spec.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
require 'rails_helper'
|
||||
require 'webhooks/twitter'
|
||||
|
||||
describe Webhooks::InstagramEventsJob do
|
||||
subject(:instagram_webhook) { described_class }
|
||||
|
||||
let!(:account) { create(:account) }
|
||||
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!(:dm_params) { build(:instagram_message_create_event).with_indifferent_access }
|
||||
let!(:test_params) { build(:instagram_test_text_event).with_indifferent_access }
|
||||
let(:fb_object) { double }
|
||||
|
||||
describe '#perform' do
|
||||
context 'with direct_message params' do
|
||||
it 'creates incoming 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(
|
||||
{
|
||||
name: 'Jane',
|
||||
id: 'Sender-id-1',
|
||||
account_id: instagram_inbox.account_id,
|
||||
profile_pic: 'https://via.placeholder.com/250x250.png'
|
||||
}.with_indifferent_access
|
||||
)
|
||||
instagram_webhook.perform_now(dm_params[:entry])
|
||||
|
||||
instagram_inbox.reload
|
||||
|
||||
expect(instagram_inbox.contacts.count).to be 1
|
||||
expect(instagram_inbox.conversations.count).to be 1
|
||||
expect(instagram_inbox.messages.count).to be 1
|
||||
end
|
||||
|
||||
it 'creates test text 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(
|
||||
{
|
||||
name: 'Jane',
|
||||
id: 'Sender-id-1',
|
||||
account_id: instagram_inbox.account_id,
|
||||
profile_pic: 'https://via.placeholder.com/250x250.png'
|
||||
}.with_indifferent_access
|
||||
)
|
||||
instagram_webhook.perform_now(test_params[:entry])
|
||||
|
||||
instagram_inbox.reload
|
||||
|
||||
expect(instagram_inbox.messages.count).to be 1
|
||||
expect(instagram_inbox.messages.last.content).to eq('This is a test message from facebook.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
45
spec/services/instagram/send_on_instagram_service_spec.rb
Normal file
45
spec/services/instagram/send_on_instagram_service_spec.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Instagram::SendOnInstagramService do
|
||||
subject(:send_reply_service) { described_class.new(message: message) }
|
||||
|
||||
before do
|
||||
create(:message, message_type: :incoming, inbox: instagram_inbox, account: account, conversation: conversation)
|
||||
end
|
||||
|
||||
let!(:account) { create(:account) }
|
||||
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!(:contact) { create(:contact, account: account) }
|
||||
let(:contact_inbox) { create(:contact_inbox, contact: contact, inbox: instagram_inbox) }
|
||||
let(:conversation) { create(:conversation, contact: contact, inbox: instagram_inbox, contact_inbox: contact_inbox) }
|
||||
let(:response) { double }
|
||||
|
||||
describe '#perform' do
|
||||
context 'with reply' do
|
||||
before do
|
||||
allow(Facebook::Messenger::Configuration::AppSecretProofCalculator).to receive(:call).and_return('app_secret_key', 'access_token')
|
||||
allow(HTTParty).to receive(:post).and_return(
|
||||
{
|
||||
body: { recipient: { id: contact_inbox.source_id } }
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'if message is sent from chatwoot and is outgoing' do
|
||||
message = create(:message, message_type: 'outgoing', inbox: instagram_inbox, account: account, conversation: conversation)
|
||||
response = ::Instagram::SendOnInstagramService.new(message: message).perform
|
||||
expect(response).to eq({ recipient: { id: contact_inbox.source_id } })
|
||||
end
|
||||
|
||||
it 'if message with attachment is sent from chatwoot and is outgoing' do
|
||||
message = build(:message, message_type: 'outgoing', inbox: instagram_inbox, account: account, conversation: conversation)
|
||||
attachment = message.attachments.new(account_id: message.account_id, file_type: :image)
|
||||
attachment.file.attach(io: File.open(Rails.root.join('spec/assets/avatar.png')), filename: 'avatar.png', content_type: 'image/png')
|
||||
message.save!
|
||||
response = ::Instagram::SendOnInstagramService.new(message: message).perform
|
||||
expect(response).to eq({ recipient: { id: contact_inbox.source_id } })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user