fix(whatsapp): normalize contact phone numbers to prevent Brazil duplicates

WhatsApp Coexistence echo messages from the native WhatsApp app deliver
Brazilian numbers without the mobile 9th digit. The contact-resolution
layer only deduplicated at the contact_inbox source_id level, so when no
matching contact_inbox existed it fell back to an exact phone_number match
using the un-normalized number, missing the existing contact stored with
the 9th digit and creating a duplicate.

Normalize the phone number used for contact lookup/creation via the
existing Brazil/Argentina normalizers so both formats resolve to the same
contact. Non-affected countries are returned unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Muhsin
2026-06-05 13:03:27 +04:00
co-authored by Claude Opus 4.8
parent 73ba0b26e5
commit fe4ba71cdf
3 changed files with 51 additions and 1 deletions
@@ -257,6 +257,41 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
end
end
end
context 'when an echo (coexistence) message arrives for a Brazil number missing the 9th digit' do
let(:echo_params) do
{
object: 'whatsapp_business_account',
entry: [{
changes: [{
field: 'smb_message_echoes',
value: {
message_echoes: [{
from: whatsapp_channel.phone_number.delete('+'),
to: '551112345678',
id: 'wamid.ECHO_MESSAGE_ID',
timestamp: '1664799904',
text: { body: 'Reply from the WhatsApp app' },
type: 'text'
}]
}
}]
}]
}.with_indifferent_access
end
it 'reuses the existing contact stored with the normalized phone number instead of duplicating it' do
existing_contact = create(:contact, phone_number: '+5511912345678', account: whatsapp_channel.account)
expect do
described_class.new(inbox: whatsapp_channel.inbox, params: echo_params, outgoing_echo: true).perform
end.not_to change(Contact, :count)
conversation = whatsapp_channel.inbox.conversations.last
expect(conversation.contact).to eq(existing_contact)
expect(conversation.messages.last.content).to eq('Reply from the WhatsApp app')
end
end
end
# Métodos auxiliares para reduzir o tamanho do exemplo