feat: decrypt secret-encrypted message edits - #161
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 WhatsApp secretEncryptedMessage MESSAGE_EDIT events using whatsmeow’s official primitive and rewrites them into the canonical cleartext protocolMessage/editedMessage shape so webhook consumers see the actual edit content when possible, while failing open when decryption is not possible. Sequence diagram for decrypting secretEncryptedMessage MESSAGE_EDIT before webhook forwardingsequenceDiagram
participant WhatsApp
participant MyClient
participant WAClient
participant Webhook
WhatsApp->>MyClient: events.Message (secretEncryptedMessage MESSAGE_EDIT)
MyClient->>MyClient: myEventHandler
MyClient->>MyClient: resolveSecretEncryptedEdit(evt)
alt enc is MESSAGE_EDIT
MyClient->>WAClient: DecryptSecretEncryptedMessage(context, evt)
alt decryption succeeds
WAClient-->>MyClient: decrypted waE2E.Message
alt decrypted has ProtocolMessage MESSAGE_EDIT with editedMessage
MyClient->>MyClient: evt.Message = decrypted
else fallback shape
MyClient->>MyClient: evt.Message = new waE2E.Message{ProtocolMessage MESSAGE_EDIT, EditedMessage: decrypted}
end
else decryption fails
WAClient-->>MyClient: error
MyClient->>MyClient: keep original evt.Message (encrypted)
end
else not a secretEncryptedMessage edit
MyClient->>MyClient: return without changes
end
MyClient->>Webhook: postMap[event="Message"], evt.Message (possibly rewritten)
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
Retargeted to
develop(replaces #128), as requested by @iagocotta in #128 (comment).Note that
mainanddevelophave no common ancestor — the GitHub API refuses to compare them (No common ancestor between main and develop) — so the base branch of the original PR could not simply be edited. This branch was created fromdevelopand the commit cherry-picked onto it.Verified on this branch:
go build ./...andgo vet ./...both pass.Summary by Sourcery
Handle secret-encrypted message edits by decrypting them and normalizing them to the standard cleartext edit event shape before forwarding to webhooks.
New Features: