Repository navigation
fix(chatwoot): make LID contact lookup work and ignore LID digits stored as phone - #2754
Open
gobeyondpty wants to merge 1 commit into
Open
gobeyondpty wants to merge 1 commit into
gobeyondpty wants to merge 1 commit into
Conversation
…red as phone findContactByIdentifier called client.get() and client.post(), which do not exist on ChatwootClient, so every call threw "TypeError: get is not a function". resolveLidToPhone swallowed it as "Error resolving LID from database", and the 422 recovery path in createContact rethrew it. Use client.contacts.search and the contacts/filter request already used by findContact, and accept only an exact identifier match because search is a substring match across several fields. Contacts created from a LID carry the LID digits as phone_number. Skip those in resolveLidToPhone so a LID is never mapped to <lid digits>@s.whatsapp.net. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
Reviewer's GuideFixes Chatwoot LID contact resolution by using the SDK's supported APIs, requiring exact identifier matches to avoid substring-search false positives, and rejecting placeholder phone numbers that contain only the LID digits. Sequence diagram for exact Chatwoot LID contact resolutionsequenceDiagram
participant Resolver as ChatwootService
participant SDK as ChatwootClient
participant API as ChatwootAPI
Resolver->>SDK: contacts.search(accountId, q)
SDK->>API: Search contacts
API-->>SDK: payload
SDK-->>Resolver: search result
alt exact identifier match
Resolver-->>Resolver: return contact
else no exact match
Resolver->>API: chatwootRequest(POST contacts/filter)
API-->>Resolver: filtered payload
alt exact identifier match
Resolver-->>Resolver: return contact
else no match
Resolver-->>Resolver: return null
end
end
Flow diagram for rejecting LID placeholder phone numbersflowchart TD
A[Resolve LID contact] --> B[Read contact phone_number]
B --> C[Remove non-digits]
C --> D{Phone digits equal LID digits?}
D -->|Yes| E[Do not resolve]
D -->|No| F[Build WhatsApp JID]
F --> G[Save LID mapping]
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Contributor
There was a problem hiding this comment.
Hey - I've reviewed your changes and they look great!
Sourcery assessment
Needs a human reviewer. If the exact-match lookup or LID-versus-phone comparison is wrong, the service could persist an incorrect WhatsApp mapping and route messages to the wrong phone number. Reverting stops the new behavior, but any messages already sent externally and mappings already saved would require separate remediation.
This branch has not been deployed
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.
📋 Description
ChatwootService.findContactByIdentifiercallsclient.get('contacts/search', …)andclient.post('contacts/filter', …).ChatwootClientfrom@figuro/chatwoot-sdkhas noget/postmethods (it exposes resource namespaces such asclient.contacts.search), so every call throws:Two callers are affected:
resolveLidToPhonestep 3 (lookup in Chatwoot) can never succeed; the error is swallowed and logged.createContact("Checking if it already exists...") rethrows theTypeErrorinstead of returning the existing contact.This PR:
client.contacts.searchand the samecontacts/filterrequestfindContactalready uses.identifiermatch. Chatwoot's contact search is a substring match across name, email, phone and identifier, so returningpayload[0]can pick the wrong contact.resolveLidToPhone, ignores aphone_numberthat is just the LID digits.createContactstores+<lid digits>asphone_numberfor contacts created from a LID, so once the lookup works those contacts would otherwise resolve to<lid digits>@s.whatsapp.net, which is not a WhatsApp number.Point 3 matters in practice: on our instance 692 of 828 contacts with an
@lididentifier have the LID digits as their phone number.🔗 Related Issue
Overlaps with #2747, which rewrites the same function as part of a larger LID change. This PR is limited to the broken lookup and adds the exact-match and LID-digits guards, which #2747 does not have (it falls back to
payload[0]).🧪 Type of Change
🧪 Testing
Checked read-only against a production Chatwoot from inside a running 2.4.0 container, using the same SDK calls:
@lidcontact whose phone is the LID digits@lidcontact with a real phone number@lidThe same script confirms
typeof client.get === 'undefined'andtypeof client.contacts.search === 'function'.eslint --ext .tspasses on the file.tsc --noEmitreports the same errors before and after (Prisma client not generated in my checkout); none are in the changed lines. I have not run a full build or an end-to-end message flow with this exact source build.✅ Checklist
🤖 Generated with Claude Code
Summary by Sourcery
Fix Chatwoot LID contact resolution and avoid treating stored LID digits as real phone numbers.
Bug Fixes: