Skip to content

Baileys engine: @lid -> phone never resolves (senderPhone / contacts/:id/phone always null); #263 feature non-functional on Baileys #362

@ulises2k

Description

@ulises2k

Summary

The @lid → phone resolution added in #263 (RESOLVE_LID_TO_PHONE, senderPhone on message.received, and GET /sessions/:id/contacts/:contactId/phone) works on the whatsapp-web.js adapter but is effectively non-functional on the Baileys engine: senderPhone and the on-demand endpoint return null even for known/saved contacts.

Environment

  • OpenWA v0.4.3 (current main)
  • Engine: Baileys
  • RESOLVE_LID_TO_PHONE=true

Symptoms

Inbound message from an @lid sender the account has interacted with before (the same contact previously appeared by phone number, before WhatsApp's LID migration):

  • message.received payload: isLidSender: true but senderPhone: null
  • GET /api/sessions/:sid/contacts/<id>@lid/phone{ "contactId": "<id>@lid", "phone": null }

So isLidSender (engine-neutral detection) works, but the resolution (adapter-specific) never returns a number on Baileys — even after the contact sends a fresh message.

Root cause

The Baileys resolution only consults two in-memory maps and has no server-query / lidMapping fallback, unlike the wwebjs adapter which uses getContactLidAndPhone() (the server-query fallback that was the whole point in #263).

src/engine/adapters/baileys.adapter.ts:

async resolveContactPhone(contactId: string): Promise<string | null> {
  this.ensureReady();
  return this.sessionStore.resolvePhone(contactId);
}

src/engine/adapters/baileys-session-store.ts:

resolvePhone(id: string): string | null {
  if (id.endsWith('@s.whatsapp.net')) return this.userPart(id);
  if (id.endsWith('@lid')) {
    const pn = this.lidToPn.get(id);
    if (pn) return this.userPart(pn);
    const contactPhone = this.contacts.get(id)?.phoneNumber;
    return contactPhone ? this.userPart(contactPhone) : null;   // null when not pre-cached
  }
  return null;
}

If the lid → pn mapping isn't already in lidToPn / contacts, it returns null with no attempt to resolve. In practice those maps aren't populated for an inbound @lid sender (a fresh inbound message still yields null), so the feature never fires on Baileys.

Contrast — src/engine/adapters/whatsapp-web-js.adapter.ts uses client.getContactLidAndPhone([id]), which does a server-side query and resolves contacts even when not locally cached.

Suggested fix

Give the Baileys resolvePhone a real fallback, e.g.:

  1. Populate lidToPn from inbound message metadata — Baileys exposes the PN alongside the LID (message key senderPn / participantPn, and the lid-mapping.update event / messages.upsert lid info).
  2. Query Baileys' LID mapping store as a fallback: sock.signalRepository.lidMapping.getPNForLID(lid) (and/or a USync / onWhatsApp lookup), mirroring the server-query fallback the wwebjs adapter gets from getContactLidAndPhone.

Happy to test a patch on a live Baileys session.

Repro

  1. Baileys session, RESOLVE_LID_TO_PHONE=true.
  2. Receive a message from a contact WhatsApp now addresses as @lid (one you've messaged before).
  3. Observe senderPhone: null on the payload and null from GET .../contacts/<lid>/phone.

Related: #263.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions