Merge pull request #9 from Rodribm10/fix-media-audio-v2
Fix media audio v2
This commit is contained in:
commit
ff52cf23e7
@ -114,6 +114,7 @@ class Attachment < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def audio_metadata
|
def audio_metadata
|
||||||
|
normalize_opus_blob_content_type!
|
||||||
audio_file_data = base_data.merge(file_metadata)
|
audio_file_data = base_data.merge(file_metadata)
|
||||||
audio_file_data.merge(
|
audio_file_data.merge(
|
||||||
{
|
{
|
||||||
@ -205,12 +206,12 @@ class Attachment < ApplicationRecord
|
|||||||
{ host: host, protocol: uri.scheme }
|
{ host: host, protocol: uri.scheme }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Marcel gem may detect OGG/Opus files as audio/opus instead of audio/ogg.
|
# WhatsApp audio arrives as OGG/Opus container. Some paths save it as audio/opus
|
||||||
# Lazily normalize existing blobs so presigned URLs serve the correct Content-Type.
|
# (raw Opus MIME type) which browsers cannot play via <audio> tag.
|
||||||
# Only applies to .ogg files — .opus files legitimately use audio/opus.
|
# Lazily normalise to audio/ogg on first access, regardless of filename extension.
|
||||||
def normalize_opus_blob_content_type!
|
def normalize_opus_blob_content_type!
|
||||||
blob = file.blob
|
blob = file.blob
|
||||||
return unless blob.content_type == 'audio/opus' && blob.filename.to_s.end_with?('.ogg')
|
return unless blob.content_type == 'audio/opus'
|
||||||
|
|
||||||
blob.update_column(:content_type, 'audio/ogg') # rubocop:disable Rails/SkipsModelValidations
|
blob.update_column(:content_type, 'audio/ogg') # rubocop:disable Rails/SkipsModelValidations
|
||||||
end
|
end
|
||||||
|
|||||||
@ -105,6 +105,29 @@ class Whatsapp::Providers::Wuzapi::PayloadParser
|
|||||||
params.dig(:event, :Info, :IsGroup) || params.dig(:event, :IsGroup)
|
params.dig(:event, :Info, :IsGroup) || params.dig(:event, :IsGroup)
|
||||||
end
|
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
|
def text_content
|
||||||
# Direct text field (some WuzAPI versions)
|
# Direct text field (some WuzAPI versions)
|
||||||
return params.dig(:event, :Text) if params.dig(:event, :Text).present?
|
return params.dig(:event, :Text) if params.dig(:event, :Text).present?
|
||||||
|
|||||||
@ -14,7 +14,7 @@ class Whatsapp::Wuzapi::MediaHandler
|
|||||||
file: {
|
file: {
|
||||||
io: file_io,
|
io: file_io,
|
||||||
filename: final_filename(attachment_data),
|
filename: final_filename(attachment_data),
|
||||||
content_type: attachment_data[:mimetype] || 'application/octet-stream'
|
content_type: sanitize_content_type(attachment_data[:mimetype], @parser.message_type)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -68,12 +68,22 @@ class Whatsapp::Wuzapi::MediaHandler
|
|||||||
name = data[:file_name] || "wuzapi_#{Time.now.to_i}"
|
name = data[:file_name] || "wuzapi_#{Time.now.to_i}"
|
||||||
ext = File.extname(name)
|
ext = File.extname(name)
|
||||||
ext = detect_extension(data[:mimetype], @parser.message_type) if ext.blank?
|
ext = detect_extension(data[:mimetype], @parser.message_type) if ext.blank?
|
||||||
|
# Normalise audio extension: WhatsApp always sends OGG/Opus, never MP3
|
||||||
|
ext = '.ogg' if @parser.message_type == :audio && ext == '.mp3'
|
||||||
"#{File.basename(name, '.*')}#{ext}"
|
"#{File.basename(name, '.*')}#{ext}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sanitize_content_type(mimetype, type)
|
||||||
|
# WhatsApp audio is OGG-wrapped Opus. audio/opus is raw Opus (wrong container header).
|
||||||
|
# Saving as audio/ogg ensures browsers can play via <audio> without issues.
|
||||||
|
return 'audio/ogg' if type == :audio && mimetype.to_s.include?('opus')
|
||||||
|
|
||||||
|
mimetype || 'application/octet-stream'
|
||||||
|
end
|
||||||
|
|
||||||
def detect_extension(mimetype, type)
|
def detect_extension(mimetype, type)
|
||||||
return '.jpg' if type == :image || type == :sticker
|
return '.jpg' if type == :image || type == :sticker
|
||||||
return '.mp3' if type == :audio
|
return '.ogg' if type == :audio
|
||||||
return '.mp4' if type == :video
|
return '.mp4' if type == :video
|
||||||
|
|
||||||
case mimetype
|
case mimetype
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user