From ec6cfc317d7d09c239587909b477c702d4173e65 Mon Sep 17 00:00:00 2001 From: Rodrigo Borba Date: Sat, 28 Feb 2026 17:47:33 -0300 Subject: [PATCH 1/2] =?UTF-8?q?fix(whatsapp):=20restaura=20attachment=5Fpa?= =?UTF-8?q?rams=20no=20PayloadParser=20para=20m=C3=ADdia=20funcionar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O refactoring c48047ba5 removeu attachment_params acidentalmente sem mover para outro lugar, quebrando o download de áudio, imagem, vídeo e documento. O método é chamado por incoming_message_wuzapi_service.rb#attach_files. Co-Authored-By: Claude Sonnet 4.6 --- .../providers/wuzapi/payload_parser.rb | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/app/services/whatsapp/providers/wuzapi/payload_parser.rb b/app/services/whatsapp/providers/wuzapi/payload_parser.rb index 680a0bf46..a3ef884ab 100644 --- a/app/services/whatsapp/providers/wuzapi/payload_parser.rb +++ b/app/services/whatsapp/providers/wuzapi/payload_parser.rb @@ -105,6 +105,29 @@ class Whatsapp::Providers::Wuzapi::PayloadParser params.dig(:event, :Info, :IsGroup) || params.dig(:event, :IsGroup) end + def attachment_params + media_key = case message_type + when :image then :imageMessage + when :audio then :audioMessage + when :video then :videoMessage + when :document then :documentMessage + when :sticker then :stickerMessage + end + return nil unless media_key + + msg = unwrap_ephemeral_message(params.dig(:event, :Message)) + data = msg[media_key] + return nil unless data.is_a?(Hash) + + { + external_url: data['URL'], + file_name: data['fileName'] || "file_#{external_id}", + mimetype: data['mimetype'], + thumbnail: data['JPEGThumbnail'], + media_key: data['mediaKey'] + } + end + def text_content # Direct text field (some WuzAPI versions) return params.dig(:event, :Text) if params.dig(:event, :Text).present? From 5d3ce4e5653ee27135e3caa89ebb5a0992220db1 Mon Sep 17 00:00:00 2001 From: Rodrigo Borba Date: Sat, 28 Feb 2026 18:40:06 -0300 Subject: [PATCH 2/2] =?UTF-8?q?fix(whatsapp):=20corrige=20content-type=20a?= =?UTF-8?q?udio/opus=20e=20extens=C3=A3o=20para=20OGG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MediaHandler: adiciona sanitize_content_type que normaliza audio/opus → audio/ogg - MediaHandler: detect_extension retorna .ogg (não .mp3) para áudios WhatsApp - MediaHandler: final_filename força extensão .ogg em áudios que chegam com .mp3 - Attachment: normalize_opus_blob_content_type! agora verifica apenas content_type (remove checagem de extensão de filename que impedia normalização de blobs .mp3) - Attachment: audio_metadata chama normalize_opus_blob_content_type! para corrigir blobs existentes na primeira vez que são acessados (lazy fix) WhatsApp envia áudio como container OGG/Opus (bytes OggS = 4f 67 67 53), mas declarava mimetype audio/opus. Browsers não conseguem reproduzir container OGG via MIME audio/opus — precisam de audio/ogg. Co-Authored-By: Claude Sonnet 4.6 --- app/models/attachment.rb | 9 +++++---- app/services/whatsapp/wuzapi/media_handler.rb | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/models/attachment.rb b/app/models/attachment.rb index ac937e88e..1dbc2a3f9 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -114,6 +114,7 @@ class Attachment < ApplicationRecord end def audio_metadata + normalize_opus_blob_content_type! audio_file_data = base_data.merge(file_metadata) audio_file_data.merge( { @@ -205,12 +206,12 @@ class Attachment < ApplicationRecord { host: host, protocol: uri.scheme } end - # Marcel gem may detect OGG/Opus files as audio/opus instead of audio/ogg. - # Lazily normalize existing blobs so presigned URLs serve the correct Content-Type. - # Only applies to .ogg files — .opus files legitimately use audio/opus. + # WhatsApp audio arrives as OGG/Opus container. Some paths save it as audio/opus + # (raw Opus MIME type) which browsers cannot play via