fix: create message with attachment in a single step

This commit is contained in:
gabrieljablonski 2025-05-08 21:36:06 -03:00
parent eb68ab6a23
commit d4915e864f
3 changed files with 23 additions and 24 deletions

View File

@ -111,7 +111,8 @@ class Attachment < ApplicationRecord
id: id, id: id,
message_id: message_id, message_id: message_id,
file_type: file_type, file_type: file_type,
account_id: account_id account_id: account_id,
meta: meta || {}
} }
end end

View File

@ -105,8 +105,7 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
when 'reaction' when 'reaction'
create_message if message_content.present? create_message if message_content.present?
when 'image', 'file', 'video', 'audio', 'sticker' when 'image', 'file', 'video', 'audio', 'sticker'
create_message create_message(attach_media: true)
attach_media
when 'unsupported' when 'unsupported'
create_unsupported_message create_unsupported_message
Rails.logger.warn "Baileys unsupported message type: #{message_type}" Rails.logger.warn "Baileys unsupported message type: #{message_type}"
@ -152,12 +151,12 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
'unsupported' 'unsupported'
end end
def create_message def create_message(attach_media: false)
sender = incoming? ? @contact : @inbox.account.account_users.first.user sender = incoming? ? @contact : @inbox.account.account_users.first.user
sender_type = incoming? ? 'Contact' : 'User' sender_type = incoming? ? 'Contact' : 'User'
message_type = incoming? ? :incoming : :outgoing message_type = incoming? ? :incoming : :outgoing
@message = @conversation.messages.create!( @message = @conversation.messages.build(
content: message_content, content: message_content,
account_id: @inbox.account_id, account_id: @inbox.account_id,
inbox_id: @inbox.id, inbox_id: @inbox.id,
@ -167,6 +166,10 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
message_type: message_type, message_type: message_type,
content_attributes: message_content_attributes content_attributes: message_content_attributes
) )
handle_attach_media if attach_media
@message.save!
end end
def message_content_attributes def message_content_attributes
@ -191,7 +194,7 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
) )
end end
def attach_media def handle_attach_media
media = processed_params.dig(:extra, :media) media = processed_params.dig(:extra, :media)
return if media.blank? return if media.blank?
@ -201,20 +204,15 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
raise AttachmentNotFoundError raise AttachmentNotFoundError
end end
begin decoded_data = Base64.decode64(attachment_payload)
decoded_data = Base64.decode64(attachment_payload) io = StringIO.new(decoded_data)
io = StringIO.new(decoded_data)
@message.attachments.new( attachment = @message.attachments.build(
account_id: @message.account_id, account_id: @message.account_id,
file_type: file_content_type.to_s, file_type: file_content_type.to_s,
file: { io: io, filename: filename } file: { io: io, filename: filename }
) )
attachment.meta = { is_recorded_audio: true } if @raw_message.dig(:message, :audioMessage, :ptt)
@message.save!
rescue StandardError => e
Rails.logger.error "Failed to attach media for message #{message_id} (#{e.message}) payload: #{attachment_payload}"
end
end end
def file_content_type def file_content_type
@ -229,7 +227,7 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
filename = @raw_message.dig(:message, :documentMessage, :fileName) filename = @raw_message.dig(:message, :documentMessage, :fileName)
return filename if filename.present? return filename if filename.present?
"#{file_content_type}_#{@message[:id]}_#{Time.current.strftime('%Y%m%d')}" "#{file_content_type}_#{message_id}_#{Time.current.strftime('%Y%m%d')}"
end end
def message_content def message_content

View File

@ -487,7 +487,7 @@ describe Whatsapp::IncomingMessageBaileysService do
expect(attachment.file).to be_present expect(attachment.file).to be_present
expect(attachment.file_type).to eq('image') expect(attachment.file_type).to eq('image')
expect(attachment.file.filename.to_s).to eq("image_#{message.id}_#{Time.current.strftime('%Y%m%d')}") expect(attachment.file.filename.to_s).to eq("image_msg_123_#{Time.current.strftime('%Y%m%d')}")
expect(attachment.file.content_type).to eq('image/png') expect(attachment.file.content_type).to eq('image/png')
end end
end end
@ -538,7 +538,7 @@ describe Whatsapp::IncomingMessageBaileysService do
expect(attachment.file).to be_present expect(attachment.file).to be_present
expect(attachment.file_type).to eq('video') expect(attachment.file_type).to eq('video')
expect(attachment.file.filename.to_s).to eq("video_#{message.id}_#{Time.current.strftime('%Y%m%d')}") expect(attachment.file.filename.to_s).to eq("video_msg_123_#{Time.current.strftime('%Y%m%d')}")
expect(attachment.file.content_type).to eq('video/mp4') expect(attachment.file.content_type).to eq('video/mp4')
end end
end end
@ -621,7 +621,7 @@ describe Whatsapp::IncomingMessageBaileysService do
expect(attachment.file_type).to eq('audio') expect(attachment.file_type).to eq('audio')
expect(attachment.file).to be_present expect(attachment.file).to be_present
expect(attachment.file.filename.to_s).to eq("audio_#{message.id}_#{Time.current.strftime('%Y%m%d')}") expect(attachment.file.filename.to_s).to eq("audio_msg_123_#{Time.current.strftime('%Y%m%d')}")
expect(attachment.file.content_type).to eq('audio/opus') expect(attachment.file.content_type).to eq('audio/opus')
end end
end end
@ -663,7 +663,7 @@ describe Whatsapp::IncomingMessageBaileysService do
expect(attachment.file_type).to eq('image') expect(attachment.file_type).to eq('image')
expect(attachment.file).to be_present expect(attachment.file).to be_present
expect(attachment.file.filename.to_s).to eq("image_#{message.id}_#{Time.current.strftime('%Y%m%d')}") expect(attachment.file.filename.to_s).to eq("image_msg_123_#{Time.current.strftime('%Y%m%d')}")
expect(attachment.file.content_type).to eq('image/png') expect(attachment.file.content_type).to eq('image/png')
end end
end end