diff --git a/app/jobs/webhooks/facebook_events_job.rb b/app/jobs/webhooks/facebook_events_job.rb new file mode 100644 index 000000000..8d212d686 --- /dev/null +++ b/app/jobs/webhooks/facebook_events_job.rb @@ -0,0 +1,8 @@ +class Webhooks::FacebookEventsJob < ApplicationJob + queue_as :default + + def perform(message) + response = ::Integrations::Facebook::MessageParser.new(message) + ::Integrations::Facebook::MessageCreator.new(response).perform + end +end diff --git a/config/initializers/facebook_messenger.rb b/config/initializers/facebook_messenger.rb index f4f80a457..ad7e5ab1f 100644 --- a/config/initializers/facebook_messenger.rb +++ b/config/initializers/facebook_messenger.rb @@ -25,9 +25,7 @@ Rails.application.reloader.to_prepare do end Facebook::Messenger::Bot.on :message do |message| - Rails.logger.info "MESSAGE_RECIEVED #{message}" - response = ::Integrations::Facebook::MessageParser.new(message) - ::Integrations::Facebook::MessageCreator.new(response).perform + Webhooks::FacebookEventsJob.perform_later(message.to_json) end Facebook::Messenger::Bot.on :delivery do |delivery| @@ -42,8 +40,6 @@ Rails.application.reloader.to_prepare do end Facebook::Messenger::Bot.on :message_echo do |message| - Rails.logger.info "MESSAGE_ECHO #{message}" - response = ::Integrations::Facebook::MessageParser.new(message) - ::Integrations::Facebook::MessageCreator.new(response).perform + Webhooks::FacebookEventsJob.perform_later(message.to_json) end end diff --git a/lib/integrations/facebook/message_creator.rb b/lib/integrations/facebook/message_creator.rb index a77c4d805..3b71460b1 100644 --- a/lib/integrations/facebook/message_creator.rb +++ b/lib/integrations/facebook/message_creator.rb @@ -22,6 +22,7 @@ class Integrations::Facebook::MessageCreator private def agent_message_via_echo? + # TODO : check and remove send_from_chatwoot_app if not working response.echo? && !response.sent_from_chatwoot_app? # this means that it is an agent message from page, but not sent from chatwoot. # User can send from fb page directly on mobile / web messenger, so this case should be handled as agent message diff --git a/lib/integrations/facebook/message_parser.rb b/lib/integrations/facebook/message_parser.rb index 9832fd7c0..e53438d70 100644 --- a/lib/integrations/facebook/message_parser.rb +++ b/lib/integrations/facebook/message_parser.rb @@ -2,45 +2,47 @@ class Integrations::Facebook::MessageParser def initialize(response_json) - @response = response_json + @response = JSON.parse(response_json) end def sender_id - @response.sender['id'] + @response.dig 'messaging', 'sender', 'id' end def recipient_id - @response.recipient['id'] + @response.dig 'messaging', 'recipient', 'id' end def time_stamp - @response.sent_at + @response.dig 'messaging', 'timestamp' end def content - @response.text + @response.dig 'messaging', 'message', 'text' end def sequence - @response.seq + @response.dig 'messaging', 'message', 'seq' end def attachments - @response.attachments + @response.dig 'messaging', 'message', 'attachments' end def identifier - @response.id + @response.dig 'messaging', 'message', 'mid' end def echo? - @response.echo? + @response.dig 'messaging', 'message', 'is_echo' end + # TODO : i don't think the payload contains app_id. if not remove def app_id - @response.app_id + @response.dig 'messaging', 'message', 'app_id' end + # TODO : does this work ? def sent_from_chatwoot_app? app_id && app_id == ENV['FB_APP_ID'].to_i end diff --git a/spec/builders/messages/facebook/message_builder_spec.rb b/spec/builders/messages/facebook/message_builder_spec.rb index dbfdb0c3d..e21c5c10e 100644 --- a/spec/builders/messages/facebook/message_builder_spec.rb +++ b/spec/builders/messages/facebook/message_builder_spec.rb @@ -4,7 +4,7 @@ describe ::Messages::Facebook::MessageBuilder do subject(:message_builder) { described_class.new(incoming_fb_text_message, facebook_channel.inbox).perform } let!(:facebook_channel) { create(:channel_facebook_page) } - let!(:message_object) { JSON.parse(build(:incoming_fb_text_message).to_json, object_class: OpenStruct) } + let!(:message_object) { build(:incoming_fb_text_message).to_json } let!(:incoming_fb_text_message) { Integrations::Facebook::MessageParser.new(message_object) } let(:fb_object) { double } diff --git a/spec/factories/facebook_message/incoming_fb_text_message.rb b/spec/factories/facebook_message/incoming_fb_text_message.rb index 35e4bf073..83d516f09 100644 --- a/spec/factories/facebook_message/incoming_fb_text_message.rb +++ b/spec/factories/facebook_message/incoming_fb_text_message.rb @@ -2,10 +2,11 @@ FactoryBot.define do factory :incoming_fb_text_message, class: Hash do - sender { { id: '3383290475046708' } } - recipient { { id: '117172741761305' } } - message { { mid: 'm_KXGKDUpO6xbVdAmZFBVpzU1AhKVJdAIUnUH4cwkvb_K3iZsWhowDRyJ_DcowEpJjncaBwdCIoRrixvCbbO1PcA', text: 'facebook message' } } - text { 'facebook message' } + messaging do + { sender: { id: '3383290475046708' }, + recipient: { id: '117172741761305' }, + message: { mid: 'm_KXGKDUpO6xbVdAmZFBVpzU1AhKVJdAIUnUH4cwkvb_K3iZsWhowDRyJ_DcowEpJjncaBwdCIoRrixvCbbO1PcA', text: 'facebook message' } } + end initialize_with { attributes } end diff --git a/spec/jobs/webhooks/facebook_events_job_spec.rb b/spec/jobs/webhooks/facebook_events_job_spec.rb new file mode 100644 index 000000000..8223953ba --- /dev/null +++ b/spec/jobs/webhooks/facebook_events_job_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' + +RSpec.describe Webhooks::FacebookEventsJob, type: :job do + subject(:job) { described_class.perform_later(params) } + + let!(:params) { { test: 'test' } } + + it 'enqueues the job' do + expect { job }.to have_enqueued_job(described_class) + .with(params) + .on_queue('default') + end + + context 'when called with params' do + it 'calls MessagePArsed and do message create' do + parser = double + creator = double + allow(::Integrations::Facebook::MessageParser).to receive(:new).and_return(parser) + allow(::Integrations::Facebook::MessageCreator).to receive(:new).and_return(creator) + allow(creator).to receive(:perform).and_return(true) + expect(::Integrations::Facebook::MessageParser).to receive(:new).with(params) + expect(::Integrations::Facebook::MessageCreator).to receive(:new).with(parser) + expect(creator).to receive(:perform) + described_class.perform_now(params) + end + end +end