feat: decrypt secret-encrypted message edits#128
Open
FlavioPulli wants to merge 1 commit into
Open
Conversation
When a phone edits a message in a @lid-addressed chat, WhatsApp delivers the edit as secretEncryptedMessage (MESSAGE_EDIT), encrypted with the original message's "message secret" — which this whatsmeow session already holds. Today the encrypted event is forwarded to the webhook as-is, so consumers learn that an edit happened but not what changed. Decrypt it with whatsmeow's official primitive (Client.DecryptSecretEncryptedMessage, native EncSecretMessageEdit support) and rewrite the event into the canonical cleartext shape (protocolMessage MESSAGE_EDIT + editedMessage) — the same shape BuildEdit produces — so webhook consumers handle phone edits and app edits identically. Fail-open: if the secret is missing (message predates the pairing) the event passes through unchanged. Battle-tested in production since 2026-07-21 against real phone edits.
Reviewer's GuideDecrypts secret-encrypted message edits from phones and rewrites them into the canonical cleartext MESSAGE_EDIT shape before forwarding to webhooks, while failing open when decryption is not possible. Sequence diagram for decrypting secret-encrypted MESSAGE_EDIT before webhook forwardingsequenceDiagram
actor Phone
participant WhatsAppServer
participant MyClient
participant WAClient
participant WebhookConsumer
Phone->>WhatsAppServer: secretEncryptedMessage MESSAGE_EDIT
WhatsAppServer->>MyClient: events.Message (secretEncryptedMessage)
MyClient->>MyClient: myEventHandler(rawEvt)
MyClient->>MyClient: resolveSecretEncryptedEdit(evt)
MyClient->>WAClient: DecryptSecretEncryptedMessage(ctx, evt)
alt [decryption succeeds]
WAClient-->>MyClient: decrypted waE2E.Message
MyClient->>MyClient: rewrite evt.Message to protocolMessage MESSAGE_EDIT + editedMessage
else [decryption fails or unsupported]
WAClient-->>MyClient: error
MyClient->>MyClient: leave evt.Message as secretEncryptedMessage
end
MyClient->>WebhookConsumer: forward Message event (cleartext when available)
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="pkg/whatsmeow/service/secret_edit.go" line_range="34-35" />
<code_context>
+// failure (missing secret, unsupported type, …) the event passes through
+// untouched — behavior falls back to what it was before this change (webhook
+// receives the encrypted payload).
+func (mycli *MyClient) resolveSecretEncryptedEdit(evt *events.Message) {
+ enc := evt.Message.GetSecretEncryptedMessage()
+ if enc == nil || enc.GetSecretEncType() != waE2E.SecretEncryptedMessage_MESSAGE_EDIT {
+ return
</code_context>
<issue_to_address>
**issue (bug_risk):** Guard against a nil targetMessageKey before logging its ID
Both log lines call enc.GetTargetMessageKey().GetID() without confirming targetMessageKey is non-nil. If a payload is missing targetMessageKey, this will panic while attempting to log. Please add a nil check and either skip logging the ID or use a safe placeholder to avoid crashes on malformed inputs.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Comment on lines
+34
to
+35
| func (mycli *MyClient) resolveSecretEncryptedEdit(evt *events.Message) { | ||
| enc := evt.Message.GetSecretEncryptedMessage() |
There was a problem hiding this comment.
issue (bug_risk): Guard against a nil targetMessageKey before logging its ID
Both log lines call enc.GetTargetMessageKey().GetID() without confirming targetMessageKey is non-nil. If a payload is missing targetMessageKey, this will panic while attempting to log. Please add a nil check and either skip logging the ID or use a safe placeholder to avoid crashes on malformed inputs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a phone edits a message in a
@lid-addressed chat, WhatsApp delivers the edit assecretEncryptedMessage(MESSAGE_EDIT): the new content is encrypted with the message secret of the original message — a secret the whatsmeow session already holds (it arrived inside the original message). Today the encrypted event is forwarded to the webhook as-is, so consumers learn that an edit happened but not what changed.This decrypts it with whatsmeow's official primitive (
Client.DecryptSecretEncryptedMessage, nativeEncSecretMessageEditsupport) and rewrites the event into the canonical cleartext shape (protocolMessageMESSAGE_EDIT +editedMessage) — the same shapeBuildEditproduces — so webhook consumers handle phone edits and app edits identically.Fail-open by design: if the secret is missing (message predates the pairing) the event passes through unchanged. Self-contained file plus a one-line call-site to keep review/rebase easy. Battle-tested in our production since 2026-07-21.
Summary by Sourcery
Decrypt secret-encrypted message edit events and normalize them into the standard cleartext edit shape before forwarding to webhooks.
New Features:
Enhancements: