Skip to content

fix(chat): display LID conversations - #36

Draft
MatiasMinoni wants to merge 1 commit into
evolution-foundation:mainfrom
MatiasMinoni:agent/fix-lid-chats
Draft

fix(chat): display LID conversations#36
MatiasMinoni wants to merge 1 commit into
evolution-foundation:mainfrom
MatiasMinoni:agent/fix-lid-chats

Conversation

@MatiasMinoni

@MatiasMinoni MatiasMinoni commented Aug 13, 2026

Copy link
Copy Markdown

What changed

  • Normalize chat API responses before they enter the UI, using remoteJid when Evolution API returns a null chat id.
  • Model nullable/partial chat responses separately from the normalized Chat used by React.
  • Classify both @s.whatsapp.net and @lid JIDs as contacts while keeping @g.us entries in Groups.
  • Reuse the normalization for single-chat lookups so the selected conversation and list share the same identity.

Root cause

Evolution API 2.4.0-rc2 can return a valid conversation with remoteJid=<linked-id>@lid and id=null when the persisted chat uses the phone JID but its latest message uses the linked ID. The Manager then hid that conversation for two independent reasons: Contacts only accepted @s.whatsapp.net, and consumers expected id to always be a string.

This matches the incoming-message symptom tracked in evolution-foundation/evolution-api#2582 and the broader LID tracking issue evolution-foundation/evolution-api#1872.

Impact

Incoming LID conversations remain visible and selectable in the Manager, and their message history can be opened normally. Groups, broadcasts, and newsletters are not reclassified as contacts.

Validation

  • npm run type-check
  • npm run lint:check (0 errors; 3 existing Fast Refresh warnings)
  • npm run build
  • End-to-end against Evolution API 2.4.0-rc2 using a real response with id: null and remoteJid: 150508622860457@lid: the Manager displayed 1 conversation and rendered its incoming Hi message.

Summary by Sourcery

Normalize chat API responses and JID classification so LID-based conversations are consistently visible and categorized in the chat manager.

New Features:

  • Add normalization of chat responses to synthesize stable chat IDs and default fields for UI consumption.
  • Introduce JID helper utilities to distinguish contact and group conversations based on suffixes.

Bug Fixes:

  • Ensure conversations with null chat IDs but valid LID remoteJids are displayed and selectable in the chat manager.
  • Treat @lid JIDs as contacts alongside @s.whatsapp.net while keeping @g.us JIDs classified as groups.

Enhancements:

  • Reuse shared chat normalization logic for both chat list and single-chat lookups to keep conversation identity consistent across the UI.

@sourcery-ai

sourcery-ai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Normalizes nullable/partial chat API responses and reuses that normalization across chat list and single-chat queries, while updating UI contact/group classification to properly include LID conversations.

Sequence diagram for chat list retrieval and normalization including LID JIDs

sequenceDiagram
  actor User
  participant ChatComponent as Chat
  participant useFindChats
  participant Api as api
  participant Normalizer as normalizeChat

  User->>ChatComponent: select contacts or groups
  ChatComponent->>useFindChats: useFindChats(instanceName)
  useFindChats->>Api: api.post /chat/findChats/{instanceName}
  Api-->>useFindChats: FindChatsApiChat[]
  useFindChats->>Normalizer: normalizeChat(chat) for each
  Normalizer-->>useFindChats: FindChatsResponse[number]
  useFindChats-->>ChatComponent: normalized chats
  ChatComponent->>ChatComponent: filter with isContactJid / isGroupJid
  ChatComponent-->>User: display visible chats (including @lid conversations)
Loading

File-Level Changes

Change Details Files
Normalize chat objects coming from the Evolution API so React always receives a fully populated Chat with a non-null id and defaulted optional fields.
  • Introduced a FindChatsApiChat type representing the partial/nullable API chat payload, allowing id to be string or null while requiring remoteJid.
  • Added a normalizeChat helper that fills in missing fields and derives id from remoteJid when id is null or undefined.
  • Updated findChats to type its API call as returning FindChatsApiChat[], and to map the raw response through normalizeChat before returning it.
src/lib/queries/chat/findChats.ts
Align single-chat lookup behavior with chat list behavior by applying the same normalization logic regardless of whether the API returns one chat or an array.
  • Imported FindChatsApiChat and normalizeChat from the chat list query module.
  • Typed findChat to return a FindChatResponse and accept responses as either FindChatsApiChat[] or FindChatsApiChat.
  • Normalized the returned chat using normalizeChat in both the array and single-object response cases.
src/lib/queries/chat/findChat.ts
Refine contact vs group classification in the chat UI to treat both @s.whatsapp.net and @lid JIDs as contacts while keeping @g.us JIDs as groups.
  • Replaced direct string-contains filtering on remoteJid with helper functions for contact and group JID detection.
  • Updated the visibleChats computation to use isContactJid for contacts and isGroupJid for groups, preserving search behavior.
src/pages/instance/Chat/index.tsx
Centralize WhatsApp JID classification logic in a dedicated utility, adding explicit handling for LID JIDs.
  • Created a new jid utilities module that defines contact JID suffixes (@s.whatsapp.net and @lid) and the group JID suffix (@g.us).
  • Exported isContactJid and isGroupJid helpers that classify JIDs based on their suffix, for reuse across the codebase.
src/lib/whatsapp/jid.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant