evolution-api icon indicating copy to clipboard operation
evolution-api copied to clipboard

fix: unify remoteJid filtering using OR with remoteJidAlt

Open rodps opened this issue 1 month ago • 1 comments

📋 Description

Quando sincronizamos o nosso whatsapp com o Evolution, as mensagens ficam salvas com o seguinte formato da propriedade 'key':

{ "id": "AC5D7F832B92FA9393B492D9F9B88C20", "fromMe": true, "remoteJid": "[email protected]" }

porém, quando recebemos novas mensagens nos eventos upsert, as mensagens salvas ficam com o seguinte formato:

{ "id": "AC5D7F832B92FA9393B492D9F9B88C20", "fromMe": true, "remoteJid": "267628186730669@lid", "participant": "", "remoteJidAlt": "[email protected]", "addressingMode": "lid" }

Como é possível observar, o remoteJid é salvo com o endereçamento LID e o JID fica na propriedade remoteJidAlt

A alteração proposta pretende corrigir o filtro de busca de mensagens para considerar tanto o remoteJid quando o remoteJidAlt dentro da cláusula OR da função fetchMessages. Atualmente a busca só funciona filtrando por remoteJid ou remoteJidAlt, e não os dois ao mesmo tempo. Por exemplo, se eu quiser filtrar pela requisição abaixo eu não consigo:

{ "where": { "key": { "remoteJid": "[email protected]" "remoteJidAlt": "[email protected]" } } }

Isso busca somente as mensagens com o remoteJid indicado, e não com o remoteJidAlt também.

O objetivo da modificação seria atribuir uma condição OR das duas propriedades: se existir remoteJid OU remoteJidAlt com o valor especificado.

🔗 Related Issue

Closes #(issue_number)

🧪 Type of Change

  • [X] 🐛 Bug fix (non-breaking change which fixes an issue)
  • [ ] ✨ New feature (non-breaking change which adds functionality)
  • [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • [ ] 📚 Documentation update
  • [ ] 🔧 Refactoring (no functional changes)
  • [ ] ⚡ Performance improvement
  • [ ] 🧹 Code cleanup
  • [ ] 🔒 Security fix

🧪 Testing

  • [X] Manual testing completed
  • [X] Functionality verified in development environment
  • [X] No breaking changes introduced
  • [ ] Tested with different connection types (if applicable)

📸 Screenshots (if applicable)

✅ Checklist

  • [X] My code follows the project's style guidelines
  • [X] I have performed a self-review of my code
  • [ ] I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation
  • [X] My changes generate no new warnings
  • [ X I have manually tested my changes thoroughly
  • [X] I have verified the changes work with different scenarios
  • [ ] Any dependent changes have been merged and published

📝 Additional Notes

Summary by Sourcery

Bug Fixes:

  • Fix message queries that failed to return results when filtering simultaneously by remoteJid and remoteJidAlt by consolidating these conditions into one OR clause.

rodps avatar Nov 23 '25 22:11 rodps

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts WhatsApp Baileys message fetching so remoteJid and remoteJidAlt are handled together via a single OR condition instead of separate filters, ensuring messages can be retrieved regardless of whether the JID is stored in remoteJid or remoteJidAlt.

Sequence diagram for unified remoteJid/remoteJidAlt message fetching

sequenceDiagram
    actor "Client"
    participant "API Server"
    participant "BaileysStartupService"
    participant "Database"

    "Client"->>"API Server": "HTTP request: fetchMessages with keyFilters { remoteJid, remoteJidAlt }"
    "API Server"->>"BaileysStartupService": "call fetchMessages(keyFilters)"

    "BaileysStartupService"->>"BaileysStartupService": "build where clause with AND conditions (id, fromMe, participant, etc.)"
    "BaileysStartupService"->>"BaileysStartupService": "add OR condition for key.remoteJid and key.remoteJidAlt using the same filter value"

    "BaileysStartupService"->>"Database": "query messages with combined OR filter on key.remoteJid and key.remoteJidAlt"
    "Database"-->>"BaileysStartupService": "return messages matching remoteJid OR remoteJidAlt"
    "BaileysStartupService"-->>"API Server": "return unified result set"
    "API Server"-->>"Client": "HTTP response with messages from both addressing modes"

Flow diagram for building unified remoteJid/remoteJidAlt filter

flowchart TD
    A[Start building fetchMessages filters] --> B{Is keyFilters.id defined?}
    B -->|"Yes"| C(["Add AND condition: key.path ['id'] equals keyFilters.id"])
    B -->|"No"| D[Skip id filter]

    C --> E{Is keyFilters.fromMe defined?}
    D --> E

    E -->|"Yes"| F(["Add AND condition: key.path ['fromMe'] equals keyFilters.fromMe"])
    E -->|"No"| G[Skip fromMe filter]

    F --> H{Is keyFilters.participant defined?}
    G --> H

    H -->|"Yes"| I(["Add AND condition: key.path ['participant'] equals keyFilters.participant"])
    H -->|"No"| J[Skip participant filter]

    I --> K{Is keyFilters.remoteJid or keyFilters.remoteJidAlt defined?}
    J --> K

    K -->|"Yes"| L(["Add OR condition: (key.path ['remoteJid'] equals value) OR (key.path ['remoteJidAlt'] equals value)"])
    K -->|"No"| M[Skip remoteJid/remoteJidAlt filters]

    L --> N[Execute database query with constructed AND and OR filters]
    M --> N

    N --> O[Return messages matching remoteJid OR remoteJidAlt when provided]

File-Level Changes

Change Details Files
Unify key.remoteJid and key.remoteJidAlt filtering under a shared OR clause in fetchMessages queries so callers can search by either field with a single value.
  • Remove the standalone AND-level filter on key.remoteJid in the message fetch query construction.
  • Rely on the existing OR block that compares the provided JID value against both key.remoteJid and key.remoteJidAlt, ensuring either field can satisfy the condition.
  • Apply the same change to both query paths that build filters for fetching messages, keeping their behavior consistent.
src/api/integrations/channel/whatsapp/whatsapp.baileys.service.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

  • Contact our support team for questions or feedback.
  • Visit our documentation for detailed guides and information.
  • Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.

sourcery-ai[bot] avatar Nov 23 '25 22:11 sourcery-ai[bot]