mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-31 02:57:57 +00:00 
			
		
		
		
	feat: Add WhatsApp profile for contact name resolution (#12123)
Fixes https://linear.app/chatwoot/issue/CW-4397/whatsapp-contacts-name-update-after-responsd-to-template
This commit is contained in:
		| @@ -92,6 +92,9 @@ class Whatsapp::IncomingMessageBaseService | ||||
|  | ||||
|     @contact_inbox = contact_inbox | ||||
|     @contact = contact_inbox.contact | ||||
|  | ||||
|     # Update existing contact name if ProfileName is available and current name is just phone number | ||||
|     update_contact_with_profile_name(contact_params) | ||||
|   end | ||||
|  | ||||
|   def set_conversation | ||||
| @@ -171,4 +174,21 @@ class Whatsapp::IncomingMessageBaseService | ||||
|       ) | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def update_contact_with_profile_name(contact_params) | ||||
|     profile_name = contact_params.dig(:profile, :name) | ||||
|     return if profile_name.blank? | ||||
|     return if @contact.name == profile_name | ||||
|  | ||||
|     # Only update if current name exactly matches the phone number or formatted phone number | ||||
|     return unless contact_name_matches_phone_number? | ||||
|  | ||||
|     @contact.update!(name: profile_name) | ||||
|   end | ||||
|  | ||||
|   def contact_name_matches_phone_number? | ||||
|     phone_number = "+#{@processed_params[:messages].first[:from]}" | ||||
|     formatted_phone_number = TelephoneNumber.parse(phone_number).international_number | ||||
|     @contact.name == phone_number || @contact.name == formatted_phone_number | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -371,5 +371,100 @@ describe Whatsapp::IncomingMessageService do | ||||
|         Redis::Alfred.delete(key) | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     context 'when profile name is available for contact updates' do | ||||
|       let(:wa_id) { '1234567890' } | ||||
|       let(:phone_number) { "+#{wa_id}" } | ||||
|  | ||||
|       it 'updates existing contact name when current name matches phone number' do | ||||
|         # Create contact with phone number as name | ||||
|         existing_contact = create(:contact, | ||||
|                                   account: whatsapp_channel.inbox.account, | ||||
|                                   name: phone_number, | ||||
|                                   phone_number: phone_number) | ||||
|         create(:contact_inbox, | ||||
|                contact: existing_contact, | ||||
|                inbox: whatsapp_channel.inbox, | ||||
|                source_id: wa_id) | ||||
|  | ||||
|         params = { | ||||
|           'contacts' => [{ 'profile' => { 'name' => 'Jane Smith' }, 'wa_id' => wa_id }], | ||||
|           'messages' => [{ 'from' => wa_id, 'id' => 'message123', 'text' => { 'body' => 'Hello' }, | ||||
|                            'timestamp' => '1633034394', 'type' => 'text' }] | ||||
|         }.with_indifferent_access | ||||
|  | ||||
|         described_class.new(inbox: whatsapp_channel.inbox, params: params).perform | ||||
|         existing_contact.reload | ||||
|         expect(existing_contact.name).to eq('Jane Smith') | ||||
|       end | ||||
|  | ||||
|       it 'does not update contact name when current name is different from phone number' do | ||||
|         # Create contact with human name | ||||
|         existing_contact = create(:contact, | ||||
|                                   account: whatsapp_channel.inbox.account, | ||||
|                                   name: 'John Doe', | ||||
|                                   phone_number: phone_number) | ||||
|         create(:contact_inbox, | ||||
|                contact: existing_contact, | ||||
|                inbox: whatsapp_channel.inbox, | ||||
|                source_id: wa_id) | ||||
|  | ||||
|         params = { | ||||
|           'contacts' => [{ 'profile' => { 'name' => 'Jane Smith' }, 'wa_id' => wa_id }], | ||||
|           'messages' => [{ 'from' => wa_id, 'id' => 'message123', 'text' => { 'body' => 'Hello' }, | ||||
|                            'timestamp' => '1633034394', 'type' => 'text' }] | ||||
|         }.with_indifferent_access | ||||
|  | ||||
|         described_class.new(inbox: whatsapp_channel.inbox, params: params).perform | ||||
|         existing_contact.reload | ||||
|         expect(existing_contact.name).to eq('John Doe') # Should not change | ||||
|       end | ||||
|  | ||||
|       it 'updates contact name when current name matches formatted phone number' do | ||||
|         formatted_number = TelephoneNumber.parse(phone_number).international_number | ||||
|  | ||||
|         # Create contact with formatted phone number as name | ||||
|         existing_contact = create(:contact, | ||||
|                                   account: whatsapp_channel.inbox.account, | ||||
|                                   name: formatted_number, | ||||
|                                   phone_number: phone_number) | ||||
|         create(:contact_inbox, | ||||
|                contact: existing_contact, | ||||
|                inbox: whatsapp_channel.inbox, | ||||
|                source_id: wa_id) | ||||
|  | ||||
|         params = { | ||||
|           'contacts' => [{ 'profile' => { 'name' => 'Alice Johnson' }, 'wa_id' => wa_id }], | ||||
|           'messages' => [{ 'from' => wa_id, 'id' => 'message123', 'text' => { 'body' => 'Hello' }, | ||||
|                            'timestamp' => '1633034394', 'type' => 'text' }] | ||||
|         }.with_indifferent_access | ||||
|  | ||||
|         described_class.new(inbox: whatsapp_channel.inbox, params: params).perform | ||||
|         existing_contact.reload | ||||
|         expect(existing_contact.name).to eq('Alice Johnson') | ||||
|       end | ||||
|  | ||||
|       it 'does not update when profile name is blank' do | ||||
|         # Create contact with phone number as name | ||||
|         existing_contact = create(:contact, | ||||
|                                   account: whatsapp_channel.inbox.account, | ||||
|                                   name: phone_number, | ||||
|                                   phone_number: phone_number) | ||||
|         create(:contact_inbox, | ||||
|                contact: existing_contact, | ||||
|                inbox: whatsapp_channel.inbox, | ||||
|                source_id: wa_id) | ||||
|  | ||||
|         params = { | ||||
|           'contacts' => [{ 'profile' => { 'name' => '' }, 'wa_id' => wa_id }], | ||||
|           'messages' => [{ 'from' => wa_id, 'id' => 'message123', 'text' => { 'body' => 'Hello' }, | ||||
|                            'timestamp' => '1633034394', 'type' => 'text' }] | ||||
|         }.with_indifferent_access | ||||
|  | ||||
|         described_class.new(inbox: whatsapp_channel.inbox, params: params).perform | ||||
|         existing_contact.reload | ||||
|         expect(existing_contact.name).to eq(phone_number) # Should not change | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Muhsin Keloth
					Muhsin Keloth