fix(contacts): stop incoming messages from reverting manually set contact names - #508
Open
bambinounos wants to merge 1 commit into
Open
Conversation
Contact.ProfileName is both the name WhatsApp reports and the name users edit in the UI. GetOrCreateContact runs on every inbound message and overwrote it whenever it differed from the WhatsApp profile name -- which is precisely the case after a user renames a contact. The rename survived until the contact's next message, then silently reverted. Reactions, coexistence contact sync and campaign jobs hit the same path. Add Contact.NameManuallySet, set it when a name is written deliberately (UpdateContact, CreateContact, CSV import) and skip the webhook refresh when it is true. Contacts that were never renamed keep syncing their name from WhatsApp as before; clearing the name in the UI hands control back. Also de-duplicate the refresh logic, which was copy-pasted across the normalized and +prefix lookup branches.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Renaming a contact in the UI does not stick. The new name survives until that contact sends their next message, then silently reverts to the name from their WhatsApp profile. Reproduced repeatedly on a live deployment.
Contact.ProfileNameserves double duty: it is both the name WhatsApp reports and the name users edit.GetOrCreateContactruns on every inbound message and refreshes it:The condition
contact.ProfileName != profileNameis true exactly when someone has renamed the contact, so the rename is what triggers its own reversion. The same path is reached from incoming messages (chatbot_processor.go), reactions, coexistence contact sync (webhook.go) and campaign jobs (worker.go), so a single emoji reaction is enough to undo an edit.This also quietly affects CSV imports: names imported from a CRM are overwritten as soon as each contact writes in.
Fix
Add
Contact.NameManuallySetand use it to distinguish a name WhatsApp supplied from one a user chose:truewhere a name is written deliberately —UpdateContact,CreateContact, and CSV import when the row carriesprofile_name;GetOrCreateContactskips the refresh when it istrue.Contacts that were never renamed keep syncing their name from WhatsApp exactly as before. Clearing the name field in the UI sets the flag back to
false, handing control to WhatsApp again — an intentional escape hatch rather than a one-way door.The refresh logic was copy-pasted across the normalized and
+prefixlookup branches; it is now a singlerefreshProfileNamehelper, so the guard cannot drift between the two.The importer gained a small
NormalizeRecordhook, called for both the create and update-on-duplicate paths, since the existingBeforeCreatehook only runs on create.Tests
internal/contactutil/contactutil_test.go:TestGetOrCreateContact_PreservesManuallySetName— a renamed contact keeps its name when a message arrives under a different WhatsApp profile name.TestGetOrCreateContact_PreservesManuallySetNamePlusPrefix— same guard on the+prefixbranch.The existing
TestGetOrCreateContact_UpdatesProfileNameis unchanged and still passes, pinning the auto-sync behaviour for contacts nobody has renamed.The new column is additive with a
falsedefault, so existing rows keep the current behaviour until a name is edited. Deployments that already imported names from a CRM can opt those rows in with a one-offUPDATE contacts SET name_manually_set = true WHERE ...if they want the imported names protected retroactively.