Repository navigation
fix(baileys): media guard in getBase64FromMediaMessage misfires on protobuf instances (captioned documents never uploaded) - #2763
Open
patrickmetzner wants to merge 1 commit into
Conversation
…4FromMediaMessage protobufjs declares every field on the prototype, so 'messageContextInfo' in msg.message is true for any Baileys message and the guard skipped every message left with one own key after the MessageSubtype unwrap. A captioned document (documentWithCaptionMessage) was therefore never uploaded to S3 and, in messages.upsert, never reached the webhook.
Contributor
Reviewer's guide (collapsed on small PRs)Reviewer's GuideFixes a false-positive media guard caused by Baileys protobuf fields living on the prototype. By requiring Sequence diagram for captioned document media processingsequenceDiagram
participant Baileys
participant MediaGuard
participant S3
participant Webhook
Baileys->>MediaGuard: getBase64FromMediaMessage
MediaGuard->>MediaGuard: unwrap documentWithCaptionMessage
alt messageContextInfo is an own property and only key
MediaGuard-->>Baileys: return null
else real media content
MediaGuard->>S3: upload media
S3-->>Baileys: mediaUrl
Baileys->>Webhook: MESSAGES_UPSERT
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
This branch has not been deployed
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.
📋 Description
getBase64FromMediaMessagereturnsnullfor any message that has exactly one own key. The guard is meant to skip messages that hold nothing butmessageContextInfo:msg.messageis a Baileys protobuf instance, and protobufjs's generated code declares every field on the prototype (Message.prototype.messageContextInfo = nullinbaileys/WAProto/index.js, from 7.0.0-rc.9 through rc14). So'messageContextInfo' in msg.messageistruefor every message, and the guard reduces to "has exactly one own key".That is the case right after the
MessageSubtypeunwrap a few lines above. A captioned document arrives as{ documentWithCaptionMessage: { message: { documentMessage } }, messageContextInfo }. The unwrap replacesmsg.messagewith the inner{ documentMessage }, which has one own key, and the guard returnsnull. Inmessages.upsertthe S3 block then logsNo valid media to upload (messageContextInfo only), skipping MinIOatverboseandreturns. The document is never uploaded and gets noMediarow ormediaUrl, and itsMESSAGES_UPSERTwebhook is never sent. An uncaptioned document is{ documentMessage, messageContextInfo }(two own keys), so it passes, which is why this shows up only with a caption.The fix checks for an own property, the same way
hasValidMediaContentinchannel.service.tsalready does:A message that really holds only
messageContextInfois still skipped, as #2273 intended.This is the other half of #2684 / #2720, not a duplicate. Those PRs stop the S3 block's
returnfrom dropping the webhook. With only them merged, a captioned document would reach the webhook, but it would still never be uploaded and would carry nomediaUrl, because this guard still returnsnull. With only this PR merged, captioned documents are uploaded and delivered, and videos withS3_SAVE_VIDEO=falseare still dropped. ThefromMeLID echoes measured in #2720 (Message contains only messageContextInfologged for real media) look like the same false positive.🔗 Related Issue
Related: #2273 (introduced the
return null, v2.3.7), #2684, #2720, #2396🧪 Type of Change
🧪 Testing
Observed in production on v2.3.7 (
S3_ENABLED=true,DATABASE_SAVE_DATA_NEW_MESSAGE=true, group chats). Two captioned documents sent from WhatsApp Web were saved inMessagewith noMediarow, and no webhook was posted (nothing reached the receiving endpoint, and no log line atERROR,WARN,INFO). Seven uncaptioned documents in the same groups, five of them from WhatsApp Web, were uploaded and delivered.Reproduced offline with the image's own
baileys7.0.0-rc.9 (also checked against rc13,develop's pin). Each shape is encoded and decoded withproto.Message, as on receipt, then put through the same unwrap and the guard:The same change, applied to v2.3.7's compiled
dist/main.js, makes captioned documents upload and arrive with theirmediaUrl.✅ Checklist
📝 Additional Notes
The same guard is reached from the S3 block of the API send path (
sendMessageWithTyping). That is not measured here, but a captioned document sent through the API would go through the same unwrap.Summary by Sourcery
Bug Fixes: