From da3ea21e72359235cdcd1feb8154e9b0e837ef4d Mon Sep 17 00:00:00 2001 From: Flavio Pulli Date: Fri, 24 Jul 2026 11:11:30 -0300 Subject: [PATCH] fix: canonicalize JIDs in GetAvatar, DeleteMessageEveryone and EditMessage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- pkg/message/service/message_service.go | 7 +++++++ pkg/user/service/user_service.go | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/pkg/message/service/message_service.go b/pkg/message/service/message_service.go index f8f13920..77f6318d 100644 --- a/pkg/message/service/message_service.go +++ b/pkg/message/service/message_service.go @@ -477,6 +477,10 @@ func (m *messageService) DeleteMessageEveryone(data *MessageStruct, instance *in m.loggerWrapper.GetLogger(instance.Id).LogError("[%s] Error validating message fields", instance.Id) return "", "", errors.New("invalid phone number") } + // The chat JID lands inside the revoke's protocolMessage Key: with the "+" + // prefix CreateJID adds, receiving devices look up a chat that doesn't + // exist and silently ignore the revoke. See utils.CanonicalJID. + recipient = utils.CanonicalJID(recipient) m.loggerWrapper.GetLogger(instance.Id).LogInfo("Revoking message %s from %s", data.MessageID, recipient) @@ -505,6 +509,9 @@ func (m *messageService) EditMessage(data *EditMessageStruct, instance *instance m.loggerWrapper.GetLogger(instance.Id).LogError("[%s] Error validating message fields", instance.Id) return "", "", errors.New("invalid phone number") } + // Same as DeleteMessageEveryone: the JID lands inside the edit's + // protocolMessage Key, so the "+" prefix makes recipients ignore it. + recipient = utils.CanonicalJID(recipient) resp, err := client.SendMessage( context.Background(), diff --git a/pkg/user/service/user_service.go b/pkg/user/service/user_service.go index f3011606..db3f6039 100644 --- a/pkg/user/service/user_service.go +++ b/pkg/user/service/user_service.go @@ -335,6 +335,10 @@ func (u *userService) GetAvatar(data *GetAvatarStruct, instance *instance_model. if !ok { return nil, errors.New("invalid phone number") } + // GetProfilePictureInfo runs a usync IQ against the JID as-is; the "+" + // prefix CreateJID adds to phone numbers makes it query a nonexistent user + // and time out (~75s). See utils.CanonicalJID. + jid = utils.CanonicalJID(jid) u.loggerWrapper.GetLogger(instance.Id).LogInfo("[%s] Requesting avatar for JID: %s, Preview: %v", instance.Id, jid, data.Preview)