Skip to content

Fix LID direct chats in Manager - #37

Open
tdeckers wants to merge 3 commits into
evolution-foundation:mainfrom
tdeckers:codex/lid-chat-aliases
Open

Fix LID direct chats in Manager#37
tdeckers wants to merge 3 commits into
evolution-foundation:mainfrom
tdeckers:codex/lid-chat-aliases

Conversation

@tdeckers

@tdeckers tdeckers commented Sep 1, 2026

Copy link
Copy Markdown

Summary

  • show direct @lid chats in the Contacts sidebar
  • load persisted chat history through both key.remoteJid and key.remoteJidAlt, merging duplicate message IDs
  • accept realtime events when either JID identity matches the open conversation
  • add focused, dependency-free identity tests and TypeScript React editor recommendations

Scope

This is a Manager-only fix. It does not change Evolution API, Baileys, database persistence, Docker images, charts, or package dependencies.

The primary history lookup remains authoritative. If an API does not support the alternate-JID filter, that lookup degrades to an empty result rather than blanking current history.

Verification

  • npm test — 12 passing tests
  • npm run lint:check — passes with 11 pre-existing warnings outside this change
  • npm run type-check
  • npm run build
  • live read-only Evolution API v2.3.7 probe: both where.key.remoteJid and where.key.remoteJidAlt returned HTTP 200

Summary by Sourcery

Fix Manager chat identity handling so LID conversations display complete persisted and realtime message histories.

New Features:

  • Display direct LID chats in the Contacts sidebar.
  • Load and combine chat history across primary and alternate JID identities.
  • Accept realtime messages associated with either identity of the open conversation.

Bug Fixes:

  • Prevent persisted messages with missing payloads from breaking chat rendering by showing a fallback.
  • Avoid duplicate messages when history queries return the same message through both JID identities.

Enhancements:

  • Centralize chat identity and message-payload handling for consistent conversation matching and response normalization.

Documentation:

  • Add recommended VS Code extensions and TypeScript editor settings.

Tests:

  • Add dependency-free tests covering direct-chat detection, alternate-JID matching, response normalization, message merging, and missing payload handling.

@tdeckers
tdeckers marked this pull request as ready for review September 1, 2026 13:16
Copilot AI lite review requested due to automatic review settings September 1, 2026 13:16
@sourcery-ai

sourcery-ai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Reviewer's Guide

Fixes Manager-only direct-chat handling by treating phone and LID JIDs as equivalent conversation identities for sidebar filtering, persisted history lookup, and realtime updates, with resilient response merging and focused identity tests.

Sequence diagram for LID-aware chat history loading

sequenceDiagram
    participant Chat as Chat UI
    participant Query as findMessages
    participant API as Evolution API
    participant Identity as identity utilities

    Chat->>Query: findMessages(instanceName, remoteJid)
    par Primary JID lookup
        Query->>API: POST findMessages where.key.remoteJid
        API-->>Query: Primary response
    and Alternate JID lookup
        Query->>API: POST findMessages where.key.remoteJidAlt
        API-->>Query: Alternate response or failure
    end
    Query->>Identity: messageRecordsFromResponse(primary, alternate)
    Identity-->>Query: Normalized records
    Query->>Identity: mergeMessagesByKeyId(groups)
    Identity-->>Query: Deduplicated messages
    Query-->>Chat: Combined message history
Loading

Sequence diagram for realtime messages matching either chat identity

sequenceDiagram
    participant Events as Realtime events
    participant Messages as Messages UI
    participant Identity as identity utilities

    Events->>Messages: Message event with key
    Messages->>Identity: messageMatchesConversation(key, selectedJid)
    alt remoteJid or remoteJidAlt matches
        Identity-->>Messages: true
        Messages-->>Messages: Update open conversation
    else Neither identity matches
        Identity-->>Messages: false
        Messages-->>Messages: Ignore event
    end
Loading

File-Level Changes

Change Details Files
Centralize direct-chat and dual-JID identity handling.
  • Recognize both phone-based and LID direct-chat JIDs.
  • Match realtime messages through either primary or alternate remote JID.
  • Add optional alternate JID support to message keys.
src/lib/chat/identity.ts
src/pages/instance/Chat/index.tsx
src/pages/instance/Chat/messages.tsx
src/types/evolution.types.ts
Load and merge persisted history across both conversation identities.
  • Query primary and alternate JID filters concurrently.
  • Normalize raw and nested API response shapes.
  • Treat alternate-filter failures as empty results while preserving primary history.
  • De-duplicate records by nonempty message key ID.
src/lib/queries/chat/findMessages.ts
src/lib/chat/identity.ts
Add focused identity behavior coverage and wire it into project verification.
  • Add dependency-free tests for JID classification, conversation matching, response normalization, and message merging.
  • Compile tests with a dedicated TypeScript configuration and run them through the default test script.
tests/chat-identity.test.ts
tests/tsconfig.json
package.json

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="package.json" line_range="49" />
<code_context>
     "preview": "vite preview",
-    "test": "echo \"No tests specified\" && exit 0",
+    "test": "npm run test:identity",
+    "test:identity": "tsc -p tests/tsconfig.json && node --test /tmp/evolution-manager-v2-identity-test/tests/chat-identity.test.js",
     "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
     "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\""
</code_context>
<issue_to_address>
**issue (testing):** The identity test command hard-codes the compiled output directory to `/tmp/evolution-manager-v2-identity-test` and invokes that Unix-specific path directly, so `npm test` fails on Windows and in environments without a writable `/tmp` directory before the tests run.

**Triggers:** When the Manager is tested on Windows or in an environment where `/tmp` is unavailable or not writable.

**Suggested fix:** Use a repository-local temporary output directory or construct the output and test paths with a cross-platform Node script.

```suggestion
    "test:identity": "tsc -p tests/tsconfig.json --outDir .tmp/evolution-manager-v2-identity-test && node --test .tmp/evolution-manager-v2-identity-test/tests/chat-identity.test.js",
```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: package.json:49


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread package.json Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Manager direct-chat handling when conversations can be identified by either phone-based JIDs (@s.whatsapp.net) or LID JIDs (@lid), so contacts, persisted history, and realtime updates remain consistent across both identities.

Changes:

  • Add chat-identity utilities to detect direct chats, match messages to the open conversation via remoteJid/remoteJidAlt, normalize API response shapes, and deduplicate merged history by message key id.
  • Update chat UI filtering and websocket event acceptance to include LID direct chats and to match events via either JID identity.
  • Add a dependency-free Node test suite for the identity helpers and include VS Code editor recommendations.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/tsconfig.json Adds a dedicated TS build config for identity tests.
tests/chat-identity.test.ts Adds Node test-runner coverage for identity utilities (direct chat detection, matching, normalization, dedupe).
src/types/evolution.types.ts Extends Key with optional remoteJidAlt for alternate identity matching.
src/pages/instance/Chat/messages.tsx Uses identity matching helper to accept realtime events for either JID identity.
src/pages/instance/Chat/index.tsx Expands Contacts filtering to include direct @lid chats.
src/lib/queries/chat/findMessages.ts Merges message history fetched by primary remoteJid and alternate remoteJidAlt.
src/lib/chat/identity.ts Introduces shared, dependency-free identity utilities used by UI and queries.
package.json Wires npm test to run the identity test suite.
.vscode/settings.json Adds recommended ESLint save-actions configuration.
.vscode/extensions.json Recommends ESLint and Prettier extensions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread package.json Outdated
Comment on lines +48 to +49
"test": "npm run test:identity",
"test:identity": "tsc -p tests/tsconfig.json && node --test /tmp/evolution-manager-v2-identity-test/tests/chat-identity.test.js",

@tdeckers tdeckers Sep 1, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accepted and fixed in 9dc5e65: the test command no longer depends on a hard-coded /tmp path.

Comment on lines +19 to +34
export const findMessages = async ({ instanceName, remoteJid }: IParams): Promise<Message[]> => {
const url = `/chat/findMessages/${instanceName}`;
const primaryRequest = api.post(url, {
where: { key: { remoteJid } },
});
if (response.data?.messages?.records) {
return response.data.messages.records;
}
return response.data;
const alternateRequest = api
.post(url, {
where: { key: { remoteJidAlt: remoteJid } },
})
.then((response) => messageRecordsFromResponse(response.data) as Message[])
.catch(() => [] as Message[]);

const [primaryResponse, alternateRecords] = await Promise.all([primaryRequest, alternateRequest]);
const primaryRecords = messageRecordsFromResponse(primaryResponse.data) as Message[];

return mergeMessagesByKeyId([primaryRecords, alternateRecords]);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accepted and fixed in 9dc5e65: the alternate lookup now runs only for direct JIDs and its records are filtered against the selected conversation before merging.

Comment thread tests/tsconfig.json
Comment on lines +9 to +12
"types": ["node"],
"rootDir": "..",
"outDir": "/tmp/evolution-manager-v2-identity-test",
"noEmitOnError": true

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

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.

2 participants