fix: resolve @lid (LID) to phone number in messages handlers and fix …#2450
fix: resolve @lid (LID) to phone number in messages handlers and fix …#2450jeandgardany wants to merge 4 commits into
Conversation
…QR code loop - messages.upsert: mutate received.key.remoteJid to remoteJidAlt when @lid is detected, ensuring prepareMessage, chatbot emit, contact upsert and all downstream uses receive the correct @s.whatsapp.net JID instead of the LID identifier - messages.update: after finding the stored message by key.id, resolve @lid using remoteJidAlt (fork field) or findMessage.key.remoteJid as fallback; applies to DB status update, webhook to N8N, messageUpdate record and chat unread counter - connectionUpdate: guard against infinite QR code regeneration loop when connection closes before QR is scanned (no wuid, no statusCode) - Dockerfile: use tsup directly instead of npm run build to bypass pre-existing tsc type error on terminateCall; add openssl/libc6-compat to Alpine final stage for Prisma compatibility - docker-compose.yaml: switch from remote image to local build so fixes persist across container recreations Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reviewer's GuideUpdates WhatsApp Baileys service to normalize @lid JIDs to standard phone-number JIDs across message handlers, adds a connection guard to prevent infinite QR regeneration loops, and adjusts Docker/Docker Compose setup to build locally with tsup and additional Alpine dependencies for Prisma. Sequence diagram for resolving @lid JID on messages.upsertsequenceDiagram
actor WhatsAppServer
participant BaileysStartupService
participant MessagePreparer
participant Chatbot
participant ContactStore
WhatsAppServer->>BaileysStartupService: messages.upsert(received)
BaileysStartupService->>BaileysStartupService: normalize messageTimestamp
alt received.key.remoteJid contains @lid and received.key.remoteJidAlt exists
BaileysStartupService->>BaileysStartupService: set received.key.remoteJid = received.key.remoteJidAlt
end
BaileysStartupService->>BaileysStartupService: check settings.groupsIgnore and @g.us
alt not ignored
BaileysStartupService->>MessagePreparer: prepareMessage(received)
MessagePreparer-->>BaileysStartupService: preparedMessage
BaileysStartupService->>Chatbot: emit message event with normalized remoteJid
BaileysStartupService->>ContactStore: upsert contact with normalized remoteJid
end
Sequence diagram for resolving @lid JID on messages.updatesequenceDiagram
actor WhatsAppServer
participant BaileysStartupService
participant MessageStore
participant Webhook
participant ChatUnreadCounter
WhatsAppServer->>BaileysStartupService: messages.update([{ key, update }])
BaileysStartupService->>MessageStore: findMessageByKeyId(key.id)
MessageStore-->>BaileysStartupService: findMessage
alt key.remoteJid contains @lid
BaileysStartupService->>BaileysStartupService: resolvedRemoteJid = key.remoteJidAlt or findMessage.key.remoteJid or key.remoteJid
else
BaileysStartupService->>BaileysStartupService: resolvedRemoteJid = key.remoteJid
end
alt update.message is null and update.status is undefined
BaileysStartupService->>Webhook: sendDataWebhook(MESSAGES_DELETE, message with resolvedRemoteJid)
else update.status is defined and changed
alt not key.fromMe and resolvedRemoteJid exists
BaileysStartupService->>ChatUnreadCounter: mark chat read for resolvedRemoteJid
alt status is READ
BaileysStartupService->>BaileysStartupService: updateMessagesReadedByTimestamp(resolvedRemoteJid, findMessage.messageTimestamp)
end
end
BaileysStartupService->>Webhook: sendDataWebhook(MESSAGES_UPDATE, message with resolvedRemoteJid)
end
Updated class diagram for BaileysStartupService JID normalization and connection guardclassDiagram
class ChannelStartupService {
}
class BaileysStartupService {
- instance
- instanceId
- logger
+ connectionUpdate(connection, lastDisconnect)
+ onMessagesUpsert(received)
+ onMessagesUpdate(key, update)
+ sendDataWebhook(event, payload)
+ updateMessagesReadedByTimestamp(remoteJid, messageTimestamp)
}
ChannelStartupService <|-- BaileysStartupService
class ConnectionUpdateLogic {
+ shouldReconnect(instance, statusCode) bool
}
class JidNormalizer {
+ normalizeRemoteJidOnUpsert(received) string
+ resolveRemoteJidOnUpdate(key, findMessage) string
}
BaileysStartupService ..> ConnectionUpdateLogic : uses
BaileysStartupService ..> JidNormalizer : uses
Flow diagram for connectionUpdate QR loop guardflowchart TD
A[connectionUpdate receives connection close] --> B[Read lastDisconnect error statusCode]
B --> C{instance.wuid exists?}
C -->|yes| D[Proceed to reconnect evaluation]
C -->|no| E{statusCode exists?}
E -->|no| F[Log and return without reconnect to prevent QR loop]
E -->|yes| D
D --> G[Check codesToNotReconnect]
G --> H{shouldReconnect?}
H -->|yes| I[Reconnect to WhatsApp]
H -->|no| J[Do not reconnect]
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The hard-coded
POSTGRES_PASSWORD=090271jdindocker-compose.yamlexposes a real-looking credential; consider reverting to a placeholder or environment-driven secret so sensitive values are not committed. - Switching the Docker build step from
npm run buildto runningtsupdirectly to bypass an existingtscerror may hide real type issues; it would be more robust to fix the underlyingterminateCalltype problem and keep a type-checking step in the build/CI pipeline. - The new
remoteJidAlthandling relies on multiple(key as any)casts; defining a proper type/interface for the message key structure would make this logic safer and easier to maintain.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The hard-coded `POSTGRES_PASSWORD=090271jd` in `docker-compose.yaml` exposes a real-looking credential; consider reverting to a placeholder or environment-driven secret so sensitive values are not committed.
- Switching the Docker build step from `npm run build` to running `tsup` directly to bypass an existing `tsc` error may hide real type issues; it would be more robust to fix the underlying `terminateCall` type problem and keep a type-checking step in the build/CI pipeline.
- The new `remoteJidAlt` handling relies on multiple `(key as any)` casts; defining a proper type/interface for the message key structure would make this logic safer and easier to maintain.
## Individual Comments
### Comment 1
<location path="docker-compose.yaml" line_range="45" />
<code_context>
- 5432:5432
environment:
- - POSTGRES_PASSWORD=PASSWORD
+ - POSTGRES_PASSWORD=090271jd
volumes:
- postgres_data:/var/lib/postgresql/data
</code_context>
<issue_to_address>
**🚨 issue (security):** Hardcoding the Postgres password in docker-compose is a security risk.
Commiting a concrete password in `docker-compose.yaml` increases the risk of secret leakage and complicates rotation. Use an env var, Docker secret, or `.env` file instead (e.g., `POSTGRES_PASSWORD=${POSTGRES_PASSWORD}`) and manage the actual value outside version control.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Replace literal password with \${POSTGRES_PASSWORD} env var reference.
Password must be set in .env file (already gitignored).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…dlers - message-receipt.update: resolve @lid to @s.whatsapp.net before updating read status, ensuring receipts match messages stored with resolved JIDs - contacts.upsert: use lidJidAlt when contact.id contains @lid, so contacts are saved with the correct @s.whatsapp.net JID - contacts.update: same LID resolution for contact updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… LidContact) Addresses Sourcery AI review feedback: introduces LidMessageKey and LidContact interfaces extending Baileys proto types with the LID-specific fields (remoteJidAlt, lidJidAlt), and adds resolveLidJid/resolveLidContact helpers to eliminate all `as any` casts for LID resolution across the codebase. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
b66926f to
b3b2d24
Compare
|
why change the docker compose and docker file? |
|
Hi! As part of our PR triage, we noticed the Check Code Quality workflow has not run on this PR (it requires maintainer approval for first-time external contributors, which we've now enabled). To trigger CI:
Once CI runs and is green I'll re-review for merge. Thanks! |
|
Obrigado pelo trabalho de tipar o tratamento de
Pontos adicionais:
Reabrir depois do rebase e da divisão em 3 PRs focados. |
…QR code loop
messages.upsert: mutate received.key.remoteJid to remoteJidAlt when @lid is detected, ensuring prepareMessage, chatbot emit, contact upsert and all downstream uses receive the correct @s.whatsapp.net JID instead of the LID identifier
messages.update: after finding the stored message by key.id, resolve @lid using remoteJidAlt (fork field) or findMessage.key.remoteJid as fallback; applies to DB status update, webhook to N8N, messageUpdate record and chat unread counter
connectionUpdate: guard against infinite QR code regeneration loop when connection closes before QR is scanned (no wuid, no statusCode)
Dockerfile: use tsup directly instead of npm run build to bypass pre-existing tsc type error on terminateCall; add openssl/libc6-compat to Alpine final stage for Prisma compatibility
docker-compose.yaml: switch from remote image to local build so fixes persist across container recreations
📋 Description
🔗 Related Issue
Closes #(issue_number)
🧪 Type of Change
🧪 Testing
📸 Screenshots (if applicable)
✅ Checklist
📝 Additional Notes
Summary by Sourcery
Handle WhatsApp @lid JIDs consistently in message handlers and prevent QR reconnect loops, while updating container build configuration for local builds and Prisma compatibility.
Bug Fixes:
Build:
Deployment:
Chores: