diff --git a/app/controllers/twilio/callback_controller.rb b/app/controllers/twilio/callback_controller.rb index ff16e9386..455828228 100644 --- a/app/controllers/twilio/callback_controller.rb +++ b/app/controllers/twilio/callback_controller.rb @@ -27,7 +27,10 @@ class Twilio::CallbackController < ApplicationController *Array.new(10) { |i| :"MediaUrl#{i}" }, *Array.new(10) { |i| :"MediaContentType#{i}" }, :MessagingServiceSid, - :NumMedia + :NumMedia, + :Latitude, + :Longitude, + :MessageType ) end end diff --git a/app/jobs/webhooks/twilio_events_job.rb b/app/jobs/webhooks/twilio_events_job.rb index 5f44d981b..87fdfadfb 100644 --- a/app/jobs/webhooks/twilio_events_job.rb +++ b/app/jobs/webhooks/twilio_events_job.rb @@ -2,10 +2,16 @@ class Webhooks::TwilioEventsJob < ApplicationJob queue_as :low def perform(params = {}) - # Skip processing if Body parameter or MediaUrl0 is not present + # Skip processing if Body parameter, MediaUrl0, or location data is not present # This is to skip processing delivery events being delivered to this endpoint - return if params[:Body].blank? && params[:MediaUrl0].blank? + return if params[:Body].blank? && params[:MediaUrl0].blank? && !valid_location_message?(params) ::Twilio::IncomingMessageService.new(params: params).perform end + + private + + def valid_location_message?(params) + params[:MessageType] == 'location' && params[:Latitude].present? && params[:Longitude].present? + end end diff --git a/app/services/twilio/incoming_message_service.rb b/app/services/twilio/incoming_message_service.rb index c38577599..a11b99744 100644 --- a/app/services/twilio/incoming_message_service.rb +++ b/app/services/twilio/incoming_message_service.rb @@ -17,6 +17,7 @@ class Twilio::IncomingMessageService source_id: params[:SmsSid] ) attach_files + attach_location if location_message? @message.save! end @@ -155,4 +156,17 @@ class Twilio::IncomingMessageService Rails.logger.info "Error downloading attachment from Twilio: #{e.message}: Skipping" nil end + + def location_message? + params[:MessageType] == 'location' && params[:Latitude].present? && params[:Longitude].present? + end + + def attach_location + @message.attachments.new( + account_id: @message.account_id, + file_type: :location, + coordinates_lat: params[:Latitude].to_f, + coordinates_long: params[:Longitude].to_f + ) + end end diff --git a/spec/jobs/webhooks/twilio_events_job_spec.rb b/spec/jobs/webhooks/twilio_events_job_spec.rb index f42caf675..aad70c68b 100644 --- a/spec/jobs/webhooks/twilio_events_job_spec.rb +++ b/spec/jobs/webhooks/twilio_events_job_spec.rb @@ -79,4 +79,25 @@ RSpec.describe Webhooks::TwilioEventsJob do described_class.perform_now(params_with_media) end end + + context 'when location message is present' do + let(:params_with_location) do + { + From: 'whatsapp:+1234567890', + To: 'whatsapp:+0987654321', + MessageType: 'location', + Latitude: '12.160894393921', + Longitude: '75.265205383301', + AccountSid: 'AC123', + SmsSid: 'SM123' + } + end + + it 'processes the location message' do + service = double + expect(Twilio::IncomingMessageService).to receive(:new).with(params: params_with_location).and_return(service) + expect(service).to receive(:perform) + described_class.perform_now(params_with_location) + end + end end diff --git a/spec/services/twilio/incoming_message_service_spec.rb b/spec/services/twilio/incoming_message_service_spec.rb index c8812e45d..94fc3fdbf 100644 --- a/spec/services/twilio/incoming_message_service_spec.rb +++ b/spec/services/twilio/incoming_message_service_spec.rb @@ -260,5 +260,27 @@ describe Twilio::IncomingMessageService do expect(conversation.reload.messages.last.attachments.map(&:file_type)).to contain_exactly('image', 'image') end end + + context 'when a location message is received' do + let(:params_with_location) do + { + SmsSid: 'SMxx', + From: '+12345', + AccountSid: 'ACxxx', + MessagingServiceSid: twilio_channel.messaging_service_sid, + MessageType: 'location', + Latitude: '12.160894393921', + Longitude: '75.265205383301' + } + end + + it 'creates a message with location attachment' do + described_class.new(params: params_with_location).perform + + message = conversation.reload.messages.last + expect(message.attachments.count).to eq(1) + expect(message.attachments.first.file_type).to eq('location') + end + end end end