diff --git a/app/services/whatsapp/baileys_handlers/helpers.rb b/app/services/whatsapp/baileys_handlers/helpers.rb index 3847c2557..ea40cf114 100644 --- a/app/services/whatsapp/baileys_handlers/helpers.rb +++ b/app/services/whatsapp/baileys_handlers/helpers.rb @@ -45,20 +45,24 @@ module Whatsapp::BaileysHandlers::Helpers # rubocop:disable Metrics/ModuleLength 'audio' elsif msg.key?(:videoMessage) 'video' - elsif msg.key?(:documentMessage) + elsif msg.key?(:documentMessage) || msg.key?(:documentWithCaptionMessage) 'file' elsif msg.key?(:stickerMessage) 'sticker' elsif msg.key?(:reactionMessage) 'reaction' + elsif msg.key?(:editedMessage) + 'edited' elsif msg.key?(:protocolMessage) 'protocol' + elsif msg.key?(:messageContextInfo) + 'context' else 'unsupported' end end - def message_content + def message_content # rubocop:disable Metrics/CyclomaticComplexity case message_type when 'text' @raw_message.dig(:message, :conversation) || @raw_message.dig(:message, :extendedTextMessage, :text) @@ -66,6 +70,9 @@ module Whatsapp::BaileysHandlers::Helpers # rubocop:disable Metrics/ModuleLength @raw_message.dig(:message, :imageMessage, :caption) when 'video' @raw_message.dig(:message, :videoMessage, :caption) + when 'file' + @raw_message.dig(:message, :documentMessage, :caption).presence || + @raw_message.dig(:message, :documentWithCaptionMessage, :message, :documentMessage, :caption) when 'reaction' @raw_message.dig(:message, :reactionMessage, :text) end @@ -90,7 +97,8 @@ module Whatsapp::BaileysHandlers::Helpers # rubocop:disable Metrics/ModuleLength when 'audio' @raw_message.dig(:message, :audioMessage, :mimetype) when 'file' - @raw_message.dig(:message, :documentMessage, :mimetype) + @raw_message.dig(:message, :documentMessage, :mimetype).presence || + @raw_message.dig(:message, :documentWithCaptionMessage, :message, :documentMessage, :mimetype) end end @@ -113,6 +121,11 @@ module Whatsapp::BaileysHandlers::Helpers # rubocop:disable Metrics/ModuleLength phone_number_from_jid == inbox.channel.phone_number.delete('+') end + def ignore_message? + message_type.in?(%w[protocol context edited]) || + (message_type == 'reaction' && message_content.blank?) + end + def message_under_process? key = format(Redis::RedisKeys::MESSAGE_SOURCE_KEY, id: raw_message_id) Redis::Alfred.get(key) diff --git a/app/services/whatsapp/baileys_handlers/messages_upsert.rb b/app/services/whatsapp/baileys_handlers/messages_upsert.rb index ff398a03c..7fb4b75f7 100644 --- a/app/services/whatsapp/baileys_handlers/messages_upsert.rb +++ b/app/services/whatsapp/baileys_handlers/messages_upsert.rb @@ -22,7 +22,7 @@ module Whatsapp::BaileysHandlers::MessagesUpsert def handle_message return if jid_type != 'user' - return if message_type == 'protocol' + return if ignore_message? return if find_message_by_source_id(raw_message_id) || message_under_process? cache_message_source_id_in_redis @@ -56,9 +56,6 @@ module Whatsapp::BaileysHandlers::MessagesUpsert end def handle_create_message - return if message_type == 'protocol' || - (message_type == 'reaction' && message_content.blank?) - create_message(attach_media: %w[image file video audio sticker].include?(message_type)) end diff --git a/spec/services/whatsapp/incoming_message_baileys_service_spec.rb b/spec/services/whatsapp/incoming_message_baileys_service_spec.rb index 328929284..19a3e0253 100644 --- a/spec/services/whatsapp/incoming_message_baileys_service_spec.rb +++ b/spec/services/whatsapp/incoming_message_baileys_service_spec.rb @@ -200,6 +200,29 @@ describe Whatsapp::IncomingMessageBaileysService do end end + context 'when message is context message' do + it 'does not create contact inbox nor message' do + raw_message[:message] = { 'messageContextInfo': { 'deviceListMetadata': {}, + 'deviceListMetadataVersion': 2, + 'messageSecret': '********' } } + described_class.new(inbox: inbox, params: params).perform + + expect(inbox.messages).to be_empty + expect(inbox.contact_inboxes).to be_empty + end + end + + context 'when message is edited message' do + it 'does not create contact inbox nor message' do + raw_message[:message] = { editedMessage: { message: { protocolMessage: { editedMessage: { documentMessage: 1 } } } } } + + described_class.new(inbox: inbox, params: params).perform + + expect(inbox.messages).to be_empty + expect(inbox.contact_inboxes).to be_empty + end + end + context 'when message is not from a user' do it 'does not create a conversation' do raw_message[:key][:remoteJid] = 'status@broadcast' @@ -407,7 +430,6 @@ describe Whatsapp::IncomingMessageBaileysService do described_class.new(inbox: inbox, params: params).perform message = inbox.conversations.last.messages.last - expect(message.content).to eq('Hello from Baileys') end @@ -418,7 +440,6 @@ describe Whatsapp::IncomingMessageBaileysService do message = inbox.conversations.last.messages.last attachment = message.attachments.last - 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') @@ -473,7 +494,6 @@ describe Whatsapp::IncomingMessageBaileysService do message = inbox.conversations.last.messages.last attachment = message.attachments.last - 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') @@ -506,11 +526,30 @@ describe Whatsapp::IncomingMessageBaileysService do message = inbox.conversations.last.messages.last attachment = message.attachments.last - expect(attachment.file_type).to eq('file') expect(attachment.file.filename.to_s).to eq(filename) expect(attachment.file.content_type).to eq('application/pdf') end + + it 'creates the message with caption' do + params[:data][:messages].first[:message] = { + documentWithCaptionMessage: { + message: { + documentMessage: { + fileName: filename, + caption: 'Hello from Baileys' + } + } + } + } + stub_download + + described_class.new(inbox: inbox, params: params).perform + + message = inbox.conversations.last.messages.last + expect(message).to be_present + expect(message.content).to eq('Hello from Baileys') + end end context 'when message type is audio' do @@ -538,7 +577,6 @@ describe Whatsapp::IncomingMessageBaileysService do message = inbox.conversations.last.messages.last attachment = message.attachments.last - expect(attachment.file_type).to eq('audio') 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') @@ -570,7 +608,6 @@ describe Whatsapp::IncomingMessageBaileysService do message = inbox.conversations.last.messages.last attachment = message.attachments.last - 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') @@ -580,10 +617,9 @@ describe Whatsapp::IncomingMessageBaileysService do context 'when processing messages.update event' do let(:conversation) do - agent = create(:user, account: inbox.account, role: :agent) - contact = create(:contact, account: inbox.account) - contact_inbox = create(:contact_inbox, inbox: inbox, contact: contact) - create(:conversation, inbox: inbox, contact_inbox: contact_inbox, assignee_id: agent.id) + contact = create(:contact, account: inbox.account, name: 'John Doe') + contact_inbox = create(:contact_inbox, inbox: inbox, contact: contact, source_id: '5511912345678') + create(:conversation, inbox: inbox, contact_inbox: contact_inbox, assignee_id: contact.id) end let!(:message) { create(:message, inbox: inbox, conversation: conversation, source_id: 'msg_123', status: 'sent') } let(:update_payload) { { key: { id: 'msg_123' }, update: { status: 3 } } }