feat: Baileys-API get media using CDN (#48)
* feat: add get_media method to retrieve media from provider service * feat: implement media attachment handling and add media_url method * feat: add includeMedia option to webhook request in WhatsappBaileysService * feat: add get_media method to error handling in WhatsappBaileysService * feat: add includeMedia option to webhook request in WhatsappBaileysService spec * feat: add media_url method to retrieve media URL in WhatsappBaileysService spec * refactor: remove get_media method from WhatsappBaileysService and Channel::Whatsapp * refactor: streamline message handling in IncomingMessageBaileysService spec * chore: add todo comment about includeMedia * refactor: simplify media download stubbing in IncomingMessageBaileysService spec * refactor: simplify media download stubbing in IncomingMessageBaileysService spec * fix: add missing end statements missed in rebase --------- Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
This commit is contained in:
parent
c8daebb5f1
commit
5735134772
@ -189,26 +189,21 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
|
||||
end
|
||||
|
||||
def handle_attach_media
|
||||
media = processed_params.dig(:extra, :media)
|
||||
return if media.blank?
|
||||
|
||||
attachment_payload = media[message_id]
|
||||
if attachment_payload.blank?
|
||||
Rails.logger.error "Attachment not found for message: #{message_id}"
|
||||
raise AttachmentNotFoundError
|
||||
end
|
||||
|
||||
decoded_data = Base64.decode64(attachment_payload)
|
||||
io = StringIO.new(decoded_data)
|
||||
attachment_file = download_attachment_file
|
||||
return unless attachment_file
|
||||
|
||||
attachment = @message.attachments.build(
|
||||
account_id: @message.account_id,
|
||||
file_type: file_content_type.to_s,
|
||||
file: { io: io, filename: filename }
|
||||
file: { io: attachment_file, filename: filename, content_type: message_mimetype }
|
||||
)
|
||||
attachment.meta = { is_recorded_audio: true } if @raw_message.dig(:message, :audioMessage, :ptt)
|
||||
end
|
||||
|
||||
def download_attachment_file
|
||||
Down.download(@conversation.inbox.channel.media_url(@raw_message.dig(:key, :id)), headers: @conversation.inbox.channel.api_headers)
|
||||
end
|
||||
|
||||
def file_content_type
|
||||
return :image if message_type.in?(%w[image sticker])
|
||||
return :video if message_type.in?(%w[video video_note])
|
||||
|
||||
@ -13,7 +13,9 @@ class Whatsapp::Providers::WhatsappBaileysService < Whatsapp::Providers::BaseSer
|
||||
body: {
|
||||
clientName: DEFAULT_CLIENT_NAME,
|
||||
webhookUrl: whatsapp_channel.inbox.callback_webhook_url,
|
||||
webhookVerifyToken: whatsapp_channel.provider_config['webhook_verify_token']
|
||||
webhookVerifyToken: whatsapp_channel.provider_config['webhook_verify_token'],
|
||||
# TODO: Remove on Baileys v2, default will be false
|
||||
includeMedia: false
|
||||
}.to_json
|
||||
)
|
||||
|
||||
@ -51,7 +53,9 @@ class Whatsapp::Providers::WhatsappBaileysService < Whatsapp::Providers::BaseSer
|
||||
|
||||
def sync_templates; end
|
||||
|
||||
def media_url(media_id); end
|
||||
def media_url(media_id)
|
||||
"#{provider_url}/media/#{media_id}"
|
||||
end
|
||||
|
||||
def api_headers
|
||||
{ 'x-api-key' => api_key, 'Content-Type' => 'application/json' }
|
||||
|
||||
@ -384,161 +384,182 @@ describe Whatsapp::IncomingMessageBaileysService do
|
||||
end
|
||||
|
||||
context 'when message type is image' do
|
||||
it 'creates the message with caption' do
|
||||
raw_message[:message] = { imageMessage: { caption: 'Hello from Baileys', mimetype: 'image/png' } }
|
||||
params[:extra] = {
|
||||
media: {
|
||||
'msg_123' => 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='
|
||||
let(:params) do
|
||||
{
|
||||
webhookVerifyToken: webhook_verify_token,
|
||||
event: 'messages.upsert',
|
||||
data: {
|
||||
type: 'notify',
|
||||
messages: [
|
||||
{
|
||||
key: { id: 'msg_123', remoteJid: '5511912345678@s.whatsapp.net', fromMe: false },
|
||||
message: { imageMessage: { caption: 'Hello from Baileys', mimetype: 'image/png' } },
|
||||
pushName: 'John Doe'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates the message with caption' do
|
||||
stub_download
|
||||
|
||||
described_class.new(inbox: inbox, params: params).perform
|
||||
conversation = inbox.conversations.last
|
||||
message = conversation.messages.last
|
||||
|
||||
expect(message).to be_present
|
||||
message = inbox.conversations.last.messages.last
|
||||
|
||||
expect(message.content).to eq('Hello from Baileys')
|
||||
end
|
||||
|
||||
it 'creates message attachment' do
|
||||
raw_message[:message] = { imageMessage: { caption: 'Hello from Baileys', mimetype: 'image/png' } }
|
||||
params[:extra] = {
|
||||
media: {
|
||||
'msg_123' => 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='
|
||||
}
|
||||
}
|
||||
|
||||
freeze_time
|
||||
stub_download
|
||||
|
||||
described_class.new(inbox: inbox, params: params).perform
|
||||
|
||||
conversation = inbox.conversations.last
|
||||
message = conversation.messages.last
|
||||
message = inbox.conversations.last.messages.last
|
||||
attachment = message.attachments.last
|
||||
|
||||
expect(attachment).to be_present
|
||||
expect(attachment.file).to be_present
|
||||
expect(attachment.file_type).to eq('image')
|
||||
|
||||
expect(attachment.file.filename.to_s).to eq("image_msg_123_#{Time.current.strftime('%Y%m%d')}.png")
|
||||
expect(attachment.file.content_type).to eq('image/png')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message type is video' do
|
||||
it 'creates the message with caption' do
|
||||
raw_message[:message] = { videoMessage: { caption: 'Hello from Baileys', mimetype: 'video/mp4' } }
|
||||
params[:extra] = {
|
||||
media: {
|
||||
'msg_123' => 'AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAABL21kYXQAAAGzABAHAAABthGBxgj238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G237wAAAbMAEAcAAAG2E4HGCkbckbbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G237AAABswAQBwAAAbYVgcYLltyRtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfsAAAGzABAHAAABtheBxhPbckbbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G237wAAAbMAEAcAAAG2GYHGJG3JG238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt+/AAADHW1vb3YAAABsbXZoZAAAAAAAAAAAAAAAAAAAA+gAAAPoAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAJHdHJhawAAAFx0a2hkAAAAAwAAAAAAAAAAAAAAAQAAAAAAAAPoAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAABAAAAAQAAAAAAAJGVkdHMAAAAcZWxzdAAAAAAAAAABAAAD6AAAAAAAAQAAAAABv21kaWEAAAAgbWRoZAAAAAAAAAAAAAAAAAAAKAAAACgAVcQAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAAAWptaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAEqc3RibAAAAGJzdHNkAAAAAAAAACVhdmMxAAAAAAAAAAAAAAAAAACFc3R0cwAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' # rubocop:disable Layout/LineLength
|
||||
let(:params) do
|
||||
{
|
||||
webhookVerifyToken: webhook_verify_token,
|
||||
event: 'messages.upsert',
|
||||
data: {
|
||||
type: 'notify',
|
||||
messages: [
|
||||
{
|
||||
key: { id: 'msg_123', remoteJid: '5511912345678@s.whatsapp.net', fromMe: false },
|
||||
message: { videoMessage: { caption: 'Hello from Baileys', mimetype: 'video/mp4' } },
|
||||
pushName: 'John Doe'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates the message with caption' do
|
||||
stub_download
|
||||
|
||||
described_class.new(inbox: inbox, params: params).perform
|
||||
|
||||
conversation = inbox.conversations.last
|
||||
message = conversation.messages.last
|
||||
message = inbox.conversations.last.messages.last
|
||||
|
||||
expect(message).to be_present
|
||||
expect(message.content).to eq('Hello from Baileys')
|
||||
end
|
||||
|
||||
it 'creates message attachment' do
|
||||
raw_message[:message] = { videoMessage: { caption: 'Hello from Baileys', mimetype: 'video/mp4' } }
|
||||
params[:extra] = {
|
||||
media: {
|
||||
'msg_123' => 'AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAABL21kYXQAAAGzABAHAAABthGBxgj238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G237wAAAbMAEAcAAAG2E4HGCkbckbbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G237AAABswAQBwAAAbYVgcYLltyRtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfsAAAGzABAHAAABtheBxhPbckbbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G237wAAAbMAEAcAAAG2GYHGJG3JG238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt+/AAADHW1vb3YAAABsbXZoZAAAAAAAAAAAAAAAAAAAA+gAAAPoAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAJHdHJhawAAAFx0a2hkAAAAAwAAAAAAAAAAAAAAAQAAAAAAAAPoAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAABAAAAAQAAAAAAAJGVkdHMAAAAcZWxzdAAAAAAAAAABAAAD6AAAAAAAAQAAAAABv21kaWEAAAAgbWRoZAAAAAAAAAAAAAAAAAAAKAAAACgAVcQAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAAAWptaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAEqc3RibAAAAGJzdHNkAAAAAAAAACVhdmMxAAAAAAAAAAAAAAAAAACFc3R0cwAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' # rubocop:disable Layout/LineLength
|
||||
}
|
||||
}
|
||||
|
||||
freeze_time
|
||||
stub_download
|
||||
|
||||
described_class.new(inbox: inbox, params: params).perform
|
||||
|
||||
conversation = inbox.conversations.last
|
||||
message = conversation.messages.last
|
||||
message = inbox.conversations.last.messages.last
|
||||
attachment = message.attachments.last
|
||||
|
||||
expect(attachment).to be_present
|
||||
expect(attachment.file).to be_present
|
||||
expect(attachment.file_type).to eq('video')
|
||||
|
||||
expect(attachment.file.filename.to_s).to eq("video_msg_123_#{Time.current.strftime('%Y%m%d')}.mp4")
|
||||
expect(attachment.file.content_type).to eq('video/mp4')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message type is file' do
|
||||
it 'creates message attachment' do
|
||||
raw_message[:message] = { documentMessage: { fileName: 'file.pdf' } }
|
||||
params[:extra] = {
|
||||
media: {
|
||||
'msg_123' => 'JVBERi0xLjQKJVRlc3QgUERGCjEgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL091dGxpbmVzIDIgMCBSIC9QYWdlcyAzIDAgUiA+PgplbmRvYmoKMiAwIG9iago8PCAvVHlwZSAvT3V0bGluZXMgL0NvdW50IDAgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFs0IDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgCiAgIC9QYXJlbnQgMyAwIFIgCiAgIC9NZWRpYUJveCBbMCAwIDMwMCAyMDBdIAogICAvQ29udGVudHMgNSAwIFIgCiAgIC9SZXNvdXJjZXMgPDwgL0ZvbnQgPDwgL0YxIDw8IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UeXBlMSAvQmFzZUZvbnQgL0hlbHZldGljYSA+PiA+PiA+PgplbmRvYmoKNSAwIG9iago8PCAvTGVuZ3RoIDUzID4+CnN0cmVhbQpCVAovRjEgMTIgVGYKNzIgMTUwIFRkCihIZWxsbyBQREYhKSBUagpFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNyAwMDAwMCBuIAowMDAwMDAwMDg0IDAwMDAwIG4gCjAwMDAwMDAxMzQgMDAwMDAgbiAKMDAwMDAwMDE5MyAwMDAwMCBuIAowMDAwMDAwMzkxIDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNiAvUm9vdCAxIDAgUiA+PgpzdGFydHhyZWYKNDk0CiUlRU9GCg==' # rubocop:disable Layout/LineLength
|
||||
let(:filename) { 'file.pdf' }
|
||||
let(:params) do
|
||||
{
|
||||
webhookVerifyToken: webhook_verify_token,
|
||||
event: 'messages.upsert',
|
||||
data: {
|
||||
type: 'notify',
|
||||
messages: [
|
||||
{
|
||||
key: { id: 'msg_123', remoteJid: '5511912345678@s.whatsapp.net', fromMe: false },
|
||||
message: { documentMessage: { fileName: filename } },
|
||||
pushName: 'John Doe'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates message attachment' do
|
||||
stub_download
|
||||
|
||||
described_class.new(inbox: inbox, params: params).perform
|
||||
|
||||
conversation = inbox.conversations.last
|
||||
message = conversation.messages.last
|
||||
message = inbox.conversations.last.messages.last
|
||||
attachment = message.attachments.last
|
||||
|
||||
expect(attachment).to be_present
|
||||
expect(attachment.file_type).to eq('file')
|
||||
expect(attachment.file).to be_present
|
||||
|
||||
expect(attachment.file.filename.to_s).to eq('file.pdf')
|
||||
expect(attachment.file.filename.to_s).to eq(filename)
|
||||
expect(attachment.file.content_type).to eq('application/pdf')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message type is audio' do
|
||||
it 'creates message attachment' do
|
||||
raw_message[:message] = { audioMessage: { mimetype: 'audio/opus' } }
|
||||
params[:extra] = {
|
||||
media: {
|
||||
'msg_123' => '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' # rubocop:disable Layout/LineLength
|
||||
let(:params) do
|
||||
{
|
||||
webhookVerifyToken: webhook_verify_token,
|
||||
event: 'messages.upsert',
|
||||
data: {
|
||||
type: 'notify',
|
||||
messages: [
|
||||
{
|
||||
key: { id: 'msg_123', remoteJid: '5511912345678@s.whatsapp.net', fromMe: false },
|
||||
message: { audioMessage: { mimetype: 'audio/opus' } },
|
||||
pushName: 'John Doe'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
freeze_time
|
||||
it 'creates message attachment' do
|
||||
stub_download
|
||||
|
||||
described_class.new(inbox: inbox, params: params).perform
|
||||
|
||||
conversation = inbox.conversations.last
|
||||
message = conversation.messages.last
|
||||
message = inbox.conversations.last.messages.last
|
||||
attachment = message.attachments.last
|
||||
|
||||
expect(attachment).to be_present
|
||||
expect(attachment.file_type).to eq('audio')
|
||||
expect(attachment.file).to be_present
|
||||
|
||||
expect(attachment.file.filename.to_s).to eq("audio_msg_123_#{Time.current.strftime('%Y%m%d')}.opus")
|
||||
expect(attachment.file.content_type).to eq('audio/opus')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message type is sticker' do
|
||||
it 'creates message attachment' do
|
||||
raw_message[:message] = { stickerMessage: { mimetype: 'image/png' } }
|
||||
params[:extra] = {
|
||||
media: {
|
||||
'msg_123' => 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='
|
||||
let(:params) do
|
||||
{
|
||||
webhookVerifyToken: webhook_verify_token,
|
||||
event: 'messages.upsert',
|
||||
data: {
|
||||
type: 'notify',
|
||||
messages: [
|
||||
{
|
||||
key: { id: 'msg_123', remoteJid: '5511912345678@s.whatsapp.net', fromMe: false },
|
||||
message: { stickerMessage: { mimetype: 'image/png' } },
|
||||
pushName: 'John Doe'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
freeze_time
|
||||
it 'creates message attachment' do
|
||||
stub_download
|
||||
|
||||
described_class.new(inbox: inbox, params: params).perform
|
||||
|
||||
conversation = inbox.conversations.last
|
||||
message = conversation.messages.last
|
||||
message = inbox.conversations.last.messages.last
|
||||
attachment = message.attachments.last
|
||||
|
||||
expect(attachment).to be_present
|
||||
expect(attachment.file_type).to eq('image')
|
||||
expect(attachment.file).to be_present
|
||||
|
||||
expect(attachment.file.filename.to_s).to eq("image_msg_123_#{Time.current.strftime('%Y%m%d')}.png")
|
||||
expect(attachment.file.content_type).to eq('image/png')
|
||||
end
|
||||
@ -624,4 +645,10 @@ describe Whatsapp::IncomingMessageBaileysService do
|
||||
def format_message_source_key(message_id)
|
||||
format(Redis::RedisKeys::MESSAGE_SOURCE_KEY, id: message_id)
|
||||
end
|
||||
|
||||
def stub_download
|
||||
allow(Down).to receive(:download)
|
||||
.with('https://baileys.api/media/msg_123', headers: inbox.channel.api_headers)
|
||||
.and_return(StringIO.new('Media data'))
|
||||
end
|
||||
end
|
||||
|
||||
@ -22,7 +22,8 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
body: {
|
||||
clientName: 'chatwoot-test',
|
||||
webhookUrl: whatsapp_channel.inbox.callback_webhook_url,
|
||||
webhookVerifyToken: whatsapp_channel.provider_config['webhook_verify_token']
|
||||
webhookVerifyToken: whatsapp_channel.provider_config['webhook_verify_token'],
|
||||
includeMedia: false
|
||||
}.to_json
|
||||
)
|
||||
.to_return(status: 200)
|
||||
@ -41,7 +42,8 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
body: {
|
||||
clientName: 'chatwoot-test',
|
||||
webhookUrl: whatsapp_channel.inbox.callback_webhook_url,
|
||||
webhookVerifyToken: whatsapp_channel.provider_config['webhook_verify_token']
|
||||
webhookVerifyToken: whatsapp_channel.provider_config['webhook_verify_token'],
|
||||
includeMedia: false
|
||||
}.to_json
|
||||
)
|
||||
.to_return(
|
||||
@ -310,6 +312,15 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#media_url' do
|
||||
it 'returns the media url' do
|
||||
media_id = '12345'
|
||||
expected_url = "#{whatsapp_channel.provider_config['provider_url']}/media/#{media_id}"
|
||||
|
||||
expect(service.media_url(media_id)).to eq(expected_url)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#api_headers' do
|
||||
it 'returns the headers' do
|
||||
expect(service.api_headers).to eq('x-api-key' => 'test_key', 'Content-Type' => 'application/json')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user