feat: implement event dispatching for incoming WhatsApp messages (#230)

* feat: implement event dispatching for incoming WhatsApp messages

* refactor: remove unused dispatcher instance variable in event dispatching context
This commit is contained in:
Gabriel Jablonski 2026-02-28 12:06:24 -03:00 committed by GitHub
parent 56c5609ca0
commit 88c2688553
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 62 additions and 0 deletions

View File

@ -2,8 +2,23 @@
# https://developers.facebook.com/docs/whatsapp/api/media/
class Whatsapp::IncomingMessageWhatsappCloudService < Whatsapp::IncomingMessageBaseService
include Events::Types
def perform
return if processed_params.blank?
Rails.configuration.dispatcher.dispatch(PROVIDER_EVENT_RECEIVED, Time.zone.now, inbox: inbox, event: whatsapp_cloud_event_type,
payload: processed_params)
super
end
private
def whatsapp_cloud_event_type
params.dig(:entry, 0, :changes, 0, :field) || 'unknown'
end
def processed_params
@processed_params ||= params[:entry].try(:first).try(:[], 'changes').try(:first).try(:[], 'value')
end

View File

@ -107,6 +107,53 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
end
end
context 'when dispatching provider events' do
let(:message_params) do
{
phone_number: whatsapp_channel.phone_number,
object: 'whatsapp_business_account',
entry: [{
changes: [{
field: 'messages',
value: {
contacts: [{ profile: { name: 'Sojan Jose' }, wa_id: '2423423243' }],
messages: [{
from: '2423423243',
text: { body: 'Hello' },
timestamp: '1664799904', type: 'text'
}]
}
}]
}]
}.with_indifferent_access
end
before do
allow(Rails.configuration.dispatcher).to receive(:dispatch)
end
it 'dispatches provider_event_received with the webhook field as event type' do
described_class.new(inbox: whatsapp_channel.inbox, params: message_params).perform
expect(Rails.configuration.dispatcher).to have_received(:dispatch).with(
'provider.event_received',
anything,
hash_including(
inbox: whatsapp_channel.inbox,
event: 'messages',
payload: message_params[:entry][0][:changes][0][:value]
)
)
end
it 'does not dispatch when processed_params is blank' do
empty_params = { phone_number: whatsapp_channel.phone_number, object: 'whatsapp_business_account', entry: {} }.with_indifferent_access
described_class.new(inbox: whatsapp_channel.inbox, params: empty_params).perform
expect(Rails.configuration.dispatcher).not_to have_received(:dispatch).with('provider.event_received', anything, anything)
end
end
context 'when message is a reply (has context)' do
let(:reply_params) do
{