diff --git a/app/services/whatsapp/incoming_message_service_helpers.rb b/app/services/whatsapp/incoming_message_service_helpers.rb index e40dc408f..705babbba 100644 --- a/app/services/whatsapp/incoming_message_service_helpers.rb +++ b/app/services/whatsapp/incoming_message_service_helpers.rb @@ -47,6 +47,15 @@ module Whatsapp::IncomingMessageServiceHelpers %w[reaction ephemeral unsupported request_welcome].include?(message_type) end + def argentina_phone_number?(phone_number) + phone_number.match(/^54/) + end + + def normalised_argentina_mobil_number(phone_number) + # Remove 9 before country code + phone_number.sub(/^549/, '54') + end + def processed_waid(waid) Whatsapp::PhoneNumberNormalizationService.new(inbox).normalize_and_find_contact(waid) end diff --git a/app/services/whatsapp/phone_normalizers/argentina_phone_normalizer.rb b/app/services/whatsapp/phone_normalizers/argentina_phone_normalizer.rb new file mode 100644 index 000000000..109a0683f --- /dev/null +++ b/app/services/whatsapp/phone_normalizers/argentina_phone_normalizer.rb @@ -0,0 +1,18 @@ +# Handles Argentina phone number normalization +# +# Argentina phone numbers can appear with or without "9" after country code +# This normalizer removes the "9" when present to create consistent format: 54 + area + number +class Whatsapp::PhoneNormalizers::ArgentinaPhoneNormalizer < Whatsapp::PhoneNormalizers::BasePhoneNormalizer + def normalize(waid) + return waid unless handles_country?(waid) + + # Remove "9" after country code if present (549 → 54) + waid.sub(/^549/, '54') + end + + private + + def country_code_pattern + /^54/ + end +end diff --git a/app/services/whatsapp/phone_number_normalization_service.rb b/app/services/whatsapp/phone_number_normalization_service.rb index b8e416794..cd10db0d0 100644 --- a/app/services/whatsapp/phone_number_normalization_service.rb +++ b/app/services/whatsapp/phone_number_normalization_service.rb @@ -1,5 +1,5 @@ # Service to handle phone number normalization for WhatsApp messages -# Currently supports Brazil phone number format variations +# Currently supports Brazil and Argentina phone number format variations # Designed to be extensible for additional countries in future PRs # # Usage: Whatsapp::PhoneNumberNormalizationService.new(inbox).normalize_and_find_contact(waid) @@ -34,6 +34,7 @@ class Whatsapp::PhoneNumberNormalizationService end NORMALIZERS = [ - Whatsapp::PhoneNormalizers::BrazilPhoneNormalizer + Whatsapp::PhoneNormalizers::BrazilPhoneNormalizer, + Whatsapp::PhoneNormalizers::ArgentinaPhoneNormalizer ].freeze end diff --git a/spec/services/whatsapp/incoming_message_service_spec.rb b/spec/services/whatsapp/incoming_message_service_spec.rb index ede1ba824..6c23e9b71 100644 --- a/spec/services/whatsapp/incoming_message_service_spec.rb +++ b/spec/services/whatsapp/incoming_message_service_spec.rb @@ -341,6 +341,58 @@ describe Whatsapp::IncomingMessageService do end end + describe 'When the incoming waid is an Argentine number with 9 after country code' do + let(:wa_id) { '5491123456789' } + + it 'creates appropriate conversations, message and contacts if contact does not exist' do + described_class.new(inbox: whatsapp_channel.inbox, params: params).perform + expect(whatsapp_channel.inbox.conversations.count).not_to eq(0) + expect(Contact.all.first.name).to eq('Sojan Jose') + expect(whatsapp_channel.inbox.messages.first.content).to eq('Test') + expect(whatsapp_channel.inbox.contact_inboxes.first.source_id).to eq(wa_id) + end + + it 'appends to existing contact if contact inbox exists with normalized format' do + # Normalized format removes the 9 after country code + normalized_wa_id = '541123456789' + contact_inbox = create(:contact_inbox, inbox: whatsapp_channel.inbox, source_id: normalized_wa_id) + last_conversation = create(:conversation, inbox: whatsapp_channel.inbox, contact_inbox: contact_inbox) + described_class.new(inbox: whatsapp_channel.inbox, params: params).perform + # no new conversation should be created + expect(whatsapp_channel.inbox.conversations.count).to eq(1) + # message appended to the last conversation + expect(last_conversation.messages.last.content).to eq(params[:messages].first[:text][:body]) + # should use the normalized wa_id from existing contact + expect(whatsapp_channel.inbox.contact_inboxes.first.source_id).to eq(normalized_wa_id) + end + end + + describe 'When incoming waid is an Argentine number without 9 after country code' do + let(:wa_id) { '541123456789' } + + context 'when a contact inbox exists with the same format' do + it 'appends to existing contact' do + contact_inbox = create(:contact_inbox, inbox: whatsapp_channel.inbox, source_id: wa_id) + last_conversation = create(:conversation, inbox: whatsapp_channel.inbox, contact_inbox: contact_inbox) + described_class.new(inbox: whatsapp_channel.inbox, params: params).perform + # no new conversation should be created + expect(whatsapp_channel.inbox.conversations.count).to eq(1) + # message appended to the last conversation + expect(last_conversation.messages.last.content).to eq(params[:messages].first[:text][:body]) + end + end + + context 'when a contact inbox does not exist' do + it 'creates contact inbox with the incoming waid' do + described_class.new(inbox: whatsapp_channel.inbox, params: params).perform + expect(whatsapp_channel.inbox.conversations.count).not_to eq(0) + expect(Contact.all.first.name).to eq('Sojan Jose') + expect(whatsapp_channel.inbox.messages.first.content).to eq('Test') + expect(whatsapp_channel.inbox.contact_inboxes.first.source_id).to eq(wa_id) + end + end + end + describe 'when message processing is in progress' do it 'ignores the current message creation request' do params = { 'contacts' => [{ 'profile' => { 'name' => 'Kedar' }, 'wa_id' => '919746334593' }],