feat: use message is unsupported content attribute (#44)

* refactor: simplify message_type method using a hash for message types

* refactor: streamline message handling and update unsupported message logic

* refactor: simplify create_message method by inlining sender_type and message_type assignments

* refactor: simplify message_type method for improved readability and performance

* feat: allow is_recorded_audio as boolean

* chore: refactor create message + attach media logic

* fix: unsupported message templates

---------

Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
This commit is contained in:
Cayo P. R. Oliveira 2025-05-09 10:52:07 -03:00 committed by GitHub
parent 16637c03c6
commit 322f0d1922
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 55 additions and 65 deletions

View File

@ -80,7 +80,11 @@ class Messages::MessageBuilder
end
def process_metadata(attachment)
{ is_recorded_audio: true } if @is_recorded_audio && attachment.original_filename.in?(@is_recorded_audio)
# NOTE: `is_recorded_audio` can be either a boolean or an array of file names.
return unless @is_recorded_audio
return { is_recorded_audio: true } if @is_recorded_audio == true
{ is_recorded_audio: true } if @is_recorded_audio.is_a?(Array) && attachment.original_filename.in?(@is_recorded_audio)
end
def process_emails

View File

@ -485,6 +485,9 @@ export default {
<template v-else-if="isAFacebookInbox">
{{ $t('CONVERSATION.UNSUPPORTED_MESSAGE_FACEBOOK') }}
</template>
<template v-else-if="isAWhatsAppChannel">
{{ $t('CONVERSATION.UNSUPPORTED_MESSAGE_WHATSAPP') }}
</template>
<template v-else>
{{ $t('CONVERSATION.UNSUPPORTED_MESSAGE') }}
</template>

View File

@ -52,7 +52,8 @@
},
"UPLOADING_ATTACHMENTS": "Uploading attachments...",
"REPLIED_TO_STORY": "Replied to your story",
"UNSUPPORTED_MESSAGE": "This message is unsupported. You can view this message on the Facebook / Instagram app.",
"UNSUPPORTED_MESSAGE": "This message is unsupported. You can view this message on the app.",
"UNSUPPORTED_MESSAGE_WHATSAPP": "This message is unsupported. You can view this message on the WhatsApp app.",
"UNSUPPORTED_MESSAGE_FACEBOOK": "This message is unsupported. You can view this message on the Facebook Messenger app.",
"UNSUPPORTED_MESSAGE_INSTAGRAM": "This message is unsupported. You can view this message on the Instagram app.",
"SUCCESS_DELETE_MESSAGE": "Message deleted successfully",

View File

@ -52,7 +52,8 @@
},
"UPLOADING_ATTACHMENTS": "Enviando anexos...",
"REPLIED_TO_STORY": "Respondido ao seu story",
"UNSUPPORTED_MESSAGE": "Esta mensagem não é suportada. Você pode ver esta mensagem no aplicativo Facebook Messenger.",
"UNSUPPORTED_MESSAGE": "Esta mensagem não é suportada. Você pode ver esta mensagem no aplicativo.",
"UNSUPPORTED_MESSAGE_WHATSAPP": "Esta mensagem não é suportada. Você pode ver esta mensagem no aplicativo do WhatsApp.",
"UNSUPPORTED_MESSAGE_FACEBOOK": "Esta mensagem não é suportada. Você pode ver esta mensagem no aplicativo Facebook Messenger.",
"UNSUPPORTED_MESSAGE_INSTAGRAM": "Esta mensagem não é suportada. Você pode ver esta mensagem no aplicativo do Instagram.",
"SUCCESS_DELETE_MESSAGE": "Mensagem excluída com sucesso",

View File

@ -99,17 +99,10 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
end
def handle_create_message
case message_type
when 'text'
create_message
when 'reaction'
create_message if message_content.present?
when 'image', 'file', 'video', 'audio', 'sticker'
create_message(attach_media: true)
when 'unsupported'
create_unsupported_message
Rails.logger.warn "Baileys unsupported message type: #{message_type}"
end
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
def jid_type # rubocop:disable Metrics/CyclomaticComplexity
@ -136,34 +129,38 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
end
end
def message_type # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
def message_type # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/MethodLength
msg = @raw_message[:message]
return 'text' if msg.key?(:conversation) || msg.dig(:extendedTextMessage, :text).present?
return 'image' if msg.key?(:imageMessage)
return 'audio' if msg.key?(:audioMessage)
return 'video' if msg.key?(:videoMessage)
return 'file' if msg.key?(:documentMessage)
return 'sticker' if msg.key?(:stickerMessage)
return 'reaction' if msg.key?(:reactionMessage)
return 'protocol' if msg.key?(:protocolMessage)
'unsupported'
@message_type ||= if msg.key?(:conversation) || msg.dig(:extendedTextMessage, :text).present?
'text'
elsif msg.key?(:imageMessage)
'image'
elsif msg.key?(:audioMessage)
'audio'
elsif msg.key?(:videoMessage)
'video'
elsif msg.key?(:documentMessage)
'file'
elsif msg.key?(:stickerMessage)
'sticker'
elsif msg.key?(:reactionMessage)
'reaction'
elsif msg.key?(:protocolMessage)
'protocol'
else
'unsupported'
end
end
def create_message(attach_media: false)
sender = incoming? ? @contact : @inbox.account.account_users.first.user
sender_type = incoming? ? 'Contact' : 'User'
message_type = incoming? ? :incoming : :outgoing
@message = @conversation.messages.build(
content: message_content,
account_id: @inbox.account_id,
inbox_id: @inbox.id,
source_id: message_id,
sender: sender,
sender_type: sender_type,
message_type: message_type,
sender: incoming? ? @contact : @inbox.account.account_users.first.user,
sender_type: incoming? ? 'Contact' : 'User',
message_type: incoming? ? :incoming : :outgoing,
content_attributes: message_content_attributes
)
@ -173,27 +170,22 @@ class Whatsapp::IncomingMessageBaileysService < Whatsapp::IncomingMessageBaseSer
end
def message_content_attributes
return unless message_type == 'reaction'
{
in_reply_to_external_id: @raw_message.dig(:message, :reactionMessage, :key, :id),
is_reaction: true
}
if message_type == 'reaction'
{
in_reply_to_external_id: @raw_message.dig(:message, :reactionMessage, :key, :id),
is_reaction: true
}
elsif message_type == 'unsupported'
{
is_unsupported: true
}
end
end
def incoming?
!@raw_message[:key][:fromMe]
end
def create_unsupported_message
create_message
@message.update!(
content: I18n.t('errors.messages.unsupported'),
message_type: 'template',
status: 'failed'
)
end
def handle_attach_media
media = processed_params.dig(:extra, :media)
return if media.blank?

View File

@ -40,7 +40,7 @@ class Whatsapp::Providers::WhatsappBaileysService < Whatsapp::Providers::BaseSer
elsif message.content.present?
@message_content = { text: @message.content }
else
message.update!(content: I18n.t('errors.messages.send.unsupported'), status: 'failed')
@message.update!(is_unsupported: true)
return
end

View File

@ -171,17 +171,7 @@ describe Whatsapp::IncomingMessageBaileysService do
message = conversation.messages.last
expect(message).to be_present
expect(message.content).to eq(I18n.t('errors.messages.unsupported'))
expect(message.message_type).to eq('template')
expect(message.status).to eq('failed')
end
it 'logs a warning message' do
allow(Rails.logger).to receive(:warn).with('Baileys unsupported message type: unsupported')
described_class.new(inbox: inbox, params: params).perform
expect(Rails.logger).to have_received(:warn)
expect(message.is_unsupported).to be(true)
end
end

View File

@ -94,14 +94,13 @@ describe Whatsapp::Providers::WhatsappBaileysService do
describe '#send_message' do
let(:request_path) { "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message" }
context 'when message does not have content nor attachments' do
context 'when message is unsupported' do
it 'updates the message with content attribute is_unsupported' do
message.update!(content: nil)
unsupported_message = create(:message, content: nil)
service.send_message(test_send_phone_number, message)
service.send_message(test_send_phone_number, unsupported_message)
expect(message.content).to eq(I18n.t('errors.messages.send.unsupported'))
expect(message.status).to eq('failed')
expect(unsupported_message.is_unsupported).to be(true)
end
end