Skip to content

fix: canonicalize JIDs in GetAvatar, DeleteMessageEveryone and EditMessage - #130

Open
FlavioPulli wants to merge 1 commit into
evolution-foundation:mainfrom
FlavioPulli:fix/canonical-jid-avatar-revoke-edit
Open

fix: canonicalize JIDs in GetAvatar, DeleteMessageEveryone and EditMessage#130
FlavioPulli wants to merge 1 commit into
evolution-foundation:mainfrom
FlavioPulli:fix/canonical-jid-avatar-revoke-edit

Conversation

@FlavioPulli

@FlavioPulli FlavioPulli commented Jul 24, 2026

Copy link
Copy Markdown

CreateJID intentionally prefixes phone numbers with + (+55...@s.whatsapp.net). Message sending tolerates it because whatsmeow normalizes the JID during usync/device resolution, and the raw-node paths (typing, receipts, reactions) already strip it via utils.CanonicalJID — but three paths still use the prefixed JID as-is:

  • GetAvatar: GetProfilePictureInfo runs a usync IQ against the JID, querying a nonexistent +... user and timing out after ~75s (info query timed out) instead of returning the picture.
  • DeleteMessageEveryone / EditMessage: the JID lands inside the protocolMessage Key of the revoke/edit, so receiving devices look up a chat named +... that doesn't exist and silently ignore the operation.

Apply utils.CanonicalJID right after ParseJID in all three, matching what the send/receipt paths already do. No-op for group and @lid JIDs (their CreateJID paths never add the prefix).

Summary by Sourcery

Canonicalize user JIDs before invoking avatar retrieval and message revoke/edit operations to ensure they target the correct chat and user.

Bug Fixes:

  • Fix GetAvatar so profile picture queries use canonical JIDs and no longer time out when phone numbers include a "+" prefix.
  • Ensure DeleteMessageEveryone uses canonical JIDs so revoke protocol messages are applied to the correct chat instead of being ignored.
  • Ensure EditMessage uses canonical JIDs so edit protocol messages are applied to the correct chat instead of being ignored.

…ssage

CreateJID intentionally prefixes phone numbers with "+"
(+55...@s.whatsapp.net). Message sending tolerates it because whatsmeow
normalizes the JID during usync/device resolution, and the raw-node
paths (typing, receipts, reactions) already strip it via
utils.CanonicalJID — but three paths still use the prefixed JID as-is:

- GetAvatar: GetProfilePictureInfo runs a usync IQ against the JID,
  querying a nonexistent "+..." user and timing out after ~75s
  ("info query timed out") instead of returning the picture.
- DeleteMessageEveryone / EditMessage: the JID lands inside the
  protocolMessage Key of the revoke/edit, so receiving devices look up
  a chat named "+..." that doesn't exist and silently ignore the
  operation.

Apply utils.CanonicalJID right after ParseJID in all three, matching
what the send/receipt paths already do. No-op for group and @lid JIDs
(their CreateJID paths never add the prefix).
@sourcery-ai

sourcery-ai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Canonicalize user chat JIDs using utils.CanonicalJID in DeleteMessageEveryone, EditMessage, and GetAvatar so that downstream WhatsApp operations address valid, normalized users instead of +-prefixed JIDs that are ignored or time out.

Sequence diagram for canonicalizing JIDs in DeleteMessageEveryone/EditMessage/GetAvatar

sequenceDiagram
  participant messageService
  participant userService
  participant utils
  participant client
  participant whatsappServer

  rect rgb(230,230,250)
    messageService->>utils: CanonicalJID(recipient)
    utils-->>messageService: recipient

    messageService->>client: SendMessage(DeleteMessageEveryone with protocolMessage Key recipient)
    client->>whatsappServer: Send revoke message
    whatsappServer-->>client: Ack revoke
  end

  rect rgb(230,250,230)
    messageService->>utils: CanonicalJID(recipient)
    utils-->>messageService: recipient

    messageService->>client: SendMessage(EditMessage with protocolMessage Key recipient)
    client->>whatsappServer: Send edit message
    whatsappServer-->>client: Ack edit
  end

  rect rgb(250,230,230)
    userService->>utils: CanonicalJID(jid)
    utils-->>userService: jid

    userService->>client: GetProfilePictureInfo(jid, preview)
    client->>whatsappServer: usync IQ for avatar
    whatsappServer-->>client: Avatar info
    client-->>userService: Avatar info
  end
Loading

File-Level Changes

Change Details Files
Normalize recipient JIDs in message revoke and edit flows to ensure protocolMessage keys reference valid chats.
  • After validating the phone number and creating the recipient JID, apply utils.CanonicalJID to the recipient in DeleteMessageEveryone before logging and sending the revoke
  • After validating the phone number and creating the recipient JID, apply utils.CanonicalJID to the recipient in EditMessage before sending the edit protocol message
  • Document in comments that non-canonical JIDs cause recipients to ignore revoke/edit operations because they reference +-prefixed chats
pkg/message/service/message_service.go
Normalize JIDs before fetching avatars so GetProfilePictureInfo queries the correct user and avoids long timeouts.
  • After ParseJID succeeds, apply utils.CanonicalJID to jid in GetAvatar before calling GetProfilePictureInfo
  • Add comments explaining that +-prefixed JIDs cause GetProfilePictureInfo usync IQ requests to query nonexistent users and time out
pkg/user/service/user_service.go

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 left some high level feedback:

  • Since ParseJID is now immediately followed by utils.CanonicalJID in multiple places, consider extracting a small helper (e.g., ParseCanonicalJID) to centralize this pattern and reduce duplication in the services.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Since `ParseJID` is now immediately followed by `utils.CanonicalJID` in multiple places, consider extracting a small helper (e.g., `ParseCanonicalJID`) to centralize this pattern and reduce duplication in the services.

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.

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