Skip to content

[bug] WhatsApp LID addressing: outgoing messages with remoteJid@lid are silently dropped #19

@dvlexp

Description

@dvlexp

Summary

When an external IA/bot sends a reply via Evolution API (e.g., our Aurora assistant), the webhook delivers messages.upsert with remoteJid: "<id>@lid" and addressingMode: "lid" instead of @s.whatsapp.net. WhatsApp's new "LID addressing mode" (2024+ privacy feature) is used for bot/multi-device sessions.

Whatsapp::EvolutionHandlers::MessagesUpsert#message_processable? returns false if jid_type != 'user'. jid_type in helpers.rb returns 'lid' for @lid JIDs. Result: the message is silently dropped — no logs beyond Processing message X (fromMe: true), no contact/conversation/message created. Only human messages sent from inside the CRM appear; any external bot/IA outgoing is lost.

Repro

  1. Connect an Instagram/WhatsApp inbox that has an AI/automation sending replies via Evolution API directly
  2. User sends inbound message → appears in CRM (jid has @s.whatsapp.net, OK)
  3. External IA replies → webhook arrives with remoteJid: "<numeric>@lid" → DROPPED

Root cause

# app/services/whatsapp/evolution_handlers/messages_upsert.rb
def message_processable?
  return false if jid_type != 'user'   # <-- blocks 'lid'
  # ...
end

# app/services/whatsapp/evolution_handlers/helpers.rb
def jid_type
  case server
  when 's.whatsapp.net', 'c.us' then 'user'
  when 'g.us' then 'group'
  when 'lid' then 'lid'  # <-- not accepted downstream
  end
end

Suggested fix

Resolve LID → phone via Evolution API's POST /chat/fetchProfile/{instance} with {number: "<lid>@lid"}. Response includes wuid: "<phone>@s.whatsapp.net" — use that for contact matching. Cache in Redis (we use 7d TTL).

Implementation sketch:

def jid_type
  raw = @raw_message[:remoteJid] || @raw_message.dig(:key, :remoteJid)
  if raw.is_a?(String) && raw.end_with?('@lid')
    phone_jid = resolve_lid_via_evolution(raw.split('@').first)
    if phone_jid
      @raw_message[:key][:remoteJid] = phone_jid
      return 'user'
    end
  end
  # ... existing logic
end

def resolve_lid_via_evolution(lid_digits)
  # POST api_url/chat/fetchProfile/{instance} with {number: "<lid_digits>@lid"}
  # Cache result in Redis
end

Without resolution, messages land on a phantom contact with LID digits as phone number (e.g., +196043866161337 instead of +5511986515426), causing duplicate contacts that need manual merging.

Impact

Full message loss for external bot flows. Any Instagram/WhatsApp inbox using an AI for replies cannot mirror conversations to the CRM.

Our workaround

Rails initializer aliases jid_type to detect @lid, calls POST /chat/fetchProfile, caches in Redis 7d, rewrites remoteJid in place before downstream processing. RXP patch #11. Happy to PR.

Identified in image evoapicloud/evo-ai-crm-community:latest dated 2026-04-25.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions