feat: mark recorded audio messages (#36)
* feat: mark recorded audio * refactor: cleaner logic for message builder metadata * test: message builder specs * test: baileys service specs * fix: correct method call for checking attachment filename in process_metadata
This commit is contained in:
parent
a52a4cf8ce
commit
b764f3997d
@ -9,6 +9,7 @@ class Messages::MessageBuilder
|
||||
@user = user
|
||||
@message_type = params[:message_type] || 'outgoing'
|
||||
@attachments = params[:attachments]
|
||||
@is_recorded_audio = params[:is_recorded_audio]
|
||||
@automation_rule = content_attributes&.dig(:automation_rule_id)
|
||||
return unless params.instance_of?(ActionController::Parameters)
|
||||
|
||||
@ -67,7 +68,7 @@ class Messages::MessageBuilder
|
||||
account_id: @message.account_id,
|
||||
file: uploaded_attachment
|
||||
)
|
||||
|
||||
attachment.meta = process_metadata(uploaded_attachment)
|
||||
attachment.file_type = if uploaded_attachment.is_a?(String)
|
||||
file_type_by_signed_id(
|
||||
uploaded_attachment
|
||||
@ -78,6 +79,10 @@ class Messages::MessageBuilder
|
||||
end
|
||||
end
|
||||
|
||||
def process_metadata(attachment)
|
||||
{ is_recorded_audio: true } if @is_recorded_audio && attachment.original_filename.in?(@is_recorded_audio)
|
||||
end
|
||||
|
||||
def process_emails
|
||||
return unless @conversation.inbox&.inbox_type == 'Email'
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ export const buildCreatePayload = ({
|
||||
contentAttributes,
|
||||
echoId,
|
||||
files,
|
||||
isRecordedAudio,
|
||||
ccEmails = '',
|
||||
bccEmails = '',
|
||||
toEmails = '',
|
||||
@ -22,6 +23,7 @@ export const buildCreatePayload = ({
|
||||
files.forEach(file => {
|
||||
payload.append('attachments[]', file);
|
||||
});
|
||||
payload.append('is_recorded_audio', JSON.stringify(isRecordedAudio));
|
||||
payload.append('private', isPrivate);
|
||||
payload.append('echo_id', echoId);
|
||||
payload.append('cc_emails', ccEmails);
|
||||
@ -60,6 +62,7 @@ class MessageApi extends ApiClient {
|
||||
contentAttributes,
|
||||
echo_id: echoId,
|
||||
files,
|
||||
isRecordedAudio,
|
||||
ccEmails = '',
|
||||
bccEmails = '',
|
||||
toEmails = '',
|
||||
@ -74,6 +77,7 @@ class MessageApi extends ApiClient {
|
||||
contentAttributes,
|
||||
echoId,
|
||||
files,
|
||||
isRecordedAudio,
|
||||
ccEmails,
|
||||
bccEmails,
|
||||
toEmails,
|
||||
|
||||
@ -1012,11 +1012,17 @@ export default {
|
||||
|
||||
if (this.attachedFiles && this.attachedFiles.length) {
|
||||
messagePayload.files = [];
|
||||
messagePayload.isRecordedAudio = [];
|
||||
this.attachedFiles.forEach(attachment => {
|
||||
if (this.globalConfig.directUploadsEnabled) {
|
||||
messagePayload.files.push(attachment.blobSignedId);
|
||||
} else {
|
||||
messagePayload.files.push(attachment.resource.file);
|
||||
if (attachment.isRecordedAudio) {
|
||||
messagePayload.isRecordedAudio.push(
|
||||
attachment.resource.file.name
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ class Whatsapp::Providers::WhatsappBaileysService < Whatsapp::Providers::BaseSer
|
||||
}
|
||||
end
|
||||
|
||||
def attachment_message_content
|
||||
def attachment_message_content # rubocop:disable Metrics/MethodLength
|
||||
attachment = @message.attachments.first
|
||||
buffer = Base64.strict_encode64(attachment.file.download)
|
||||
|
||||
@ -99,6 +99,7 @@ class Whatsapp::Providers::WhatsappBaileysService < Whatsapp::Providers::BaseSer
|
||||
content[:image] = buffer
|
||||
when 'audio'
|
||||
content[:audio] = buffer
|
||||
content[:ptt] = attachment.meta['is_recorded_audio']
|
||||
when 'file'
|
||||
content[:document] = buffer
|
||||
when 'sticker'
|
||||
|
||||
@ -134,6 +134,14 @@ describe Messages::MessageBuilder do
|
||||
expect(message.attachments.first.file_type).to eq 'image'
|
||||
end
|
||||
|
||||
it 'creates attachment with is_recorded_audio metadata' do
|
||||
params[:is_recorded_audio] = ['avatar.png']
|
||||
|
||||
message = message_builder
|
||||
|
||||
expect(message.attachments.first.meta).to eq({ 'is_recorded_audio' => true })
|
||||
end
|
||||
|
||||
context 'when DIRECT_UPLOAD_ENABLED' do
|
||||
let(:params) do
|
||||
ActionController::Parameters.new({
|
||||
|
||||
@ -92,6 +92,8 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
end
|
||||
|
||||
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
|
||||
it 'updates the message with content attribute is_unsupported' do
|
||||
message.update!(content: nil)
|
||||
@ -107,7 +109,7 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
let(:base64_image) { 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=' }
|
||||
|
||||
before do
|
||||
message.attachments.new(
|
||||
message.attachments.create!(
|
||||
account_id: message.account_id,
|
||||
file_type: 'image',
|
||||
file: {
|
||||
@ -115,11 +117,10 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
filename: 'image.png'
|
||||
}
|
||||
)
|
||||
message.save!
|
||||
end
|
||||
|
||||
it 'sends the attachment message' do
|
||||
stub_request(:post, "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message")
|
||||
stub_request(:post, request_path)
|
||||
.with(
|
||||
headers: stub_headers(whatsapp_channel),
|
||||
body: {
|
||||
@ -140,7 +141,7 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
|
||||
it 'omits caption if message content is empty' do
|
||||
message.update!(content: nil)
|
||||
stub_request(:post, "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message")
|
||||
stub_request(:post, request_path)
|
||||
.with(
|
||||
headers: stub_headers(whatsapp_channel),
|
||||
body: {
|
||||
@ -158,26 +159,31 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
|
||||
expect(result).to eq('msg_123')
|
||||
end
|
||||
|
||||
context 'when request is unsuccessful' do
|
||||
it 'raises MessageNotSentError' do
|
||||
stub_request(:post, "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message")
|
||||
.to_return(
|
||||
status: 400,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: { 'data' => { 'key' => { 'id' => 'msg_123' } } }.to_json
|
||||
)
|
||||
|
||||
expect do
|
||||
service.send_message(test_send_phone_number, message)
|
||||
end.to raise_error(Whatsapp::Providers::WhatsappBaileysService::MessageNotSentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message is a text' do
|
||||
it 'sends the message' do
|
||||
stub_request(:post, "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message")
|
||||
context 'when message is an audio file' do
|
||||
let(:base64_audio) { 'UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAAAAA=' }
|
||||
|
||||
before do
|
||||
message.attachments.create!(
|
||||
account_id: message.account_id,
|
||||
file_type: 'audio',
|
||||
file: {
|
||||
io: StringIO.new(Base64.decode64(base64_audio)),
|
||||
filename: 'audio.wav'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'sends the audio message' do
|
||||
stub_request(:post, request_path)
|
||||
.with(
|
||||
headers: stub_headers(whatsapp_channel),
|
||||
body: {
|
||||
jid: test_send_jid,
|
||||
messageContent: { fileName: 'audio.wav', caption: message.content, audio: base64_audio }
|
||||
}.to_json
|
||||
)
|
||||
.to_return(
|
||||
status: 200,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
@ -189,17 +195,41 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
expect(result).to eq('msg_123')
|
||||
end
|
||||
|
||||
it 'raises MessageNotSentError' do
|
||||
stub_request(:post, "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message")
|
||||
it 'sends message with ptt true if message is recorded audio' do
|
||||
message.attachments.first.update!(meta: { is_recorded_audio: true })
|
||||
|
||||
stub_request(:post, request_path)
|
||||
.with(
|
||||
headers: stub_headers(whatsapp_channel),
|
||||
body: {
|
||||
jid: test_send_jid,
|
||||
messageContent: { fileName: 'audio.wav', caption: message.content, audio: base64_audio, ptt: true }
|
||||
}.to_json
|
||||
)
|
||||
.to_return(
|
||||
status: 400,
|
||||
status: 200,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: { 'data' => { 'key' => { 'id' => 'msg_123' } } }.to_json
|
||||
)
|
||||
|
||||
expect do
|
||||
service.send_message(test_send_phone_number, message)
|
||||
end.to raise_error(Whatsapp::Providers::WhatsappBaileysService::MessageNotSentError)
|
||||
result = service.send_message(test_send_phone_number, message)
|
||||
|
||||
expect(result).to eq('msg_123')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when message is a text' do
|
||||
it 'sends the message' do
|
||||
stub_request(:post, request_path)
|
||||
.to_return(
|
||||
status: 200,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: { 'data' => { 'key' => { 'id' => 'msg_123' } } }.to_json
|
||||
)
|
||||
|
||||
result = service.send_message(test_send_phone_number, message)
|
||||
|
||||
expect(result).to eq('msg_123')
|
||||
end
|
||||
end
|
||||
|
||||
@ -216,7 +246,7 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
message = create(:message, inbox: inbox, conversation: conversation, sender: account_user, message_type: 'outgoing', source_id: 'msg_123')
|
||||
reaction = create(:message, inbox: inbox, conversation: conversation, sender: account_user, content: '👍',
|
||||
content_attributes: { is_reaction: true, in_reply_to: message.id })
|
||||
stub_request(:post, "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message")
|
||||
stub_request(:post, request_path)
|
||||
.with(
|
||||
headers: stub_headers(whatsapp_channel),
|
||||
body: {
|
||||
@ -242,7 +272,7 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
message = create(:message, inbox: inbox, conversation: conversation, sender: contact, source_id: 'msg_123')
|
||||
reaction = create(:message, inbox: inbox, conversation: conversation, sender: account_user, content: '👍',
|
||||
content_attributes: { is_reaction: true, in_reply_to: message.id })
|
||||
stub_request(:post, "#{whatsapp_channel.provider_config['provider_url']}/connections/#{whatsapp_channel.phone_number}/send-message")
|
||||
stub_request(:post, request_path)
|
||||
.with(
|
||||
headers: stub_headers(whatsapp_channel),
|
||||
body: {
|
||||
@ -264,6 +294,21 @@ describe Whatsapp::Providers::WhatsappBaileysService do
|
||||
expect(result).to eq('reaction_123')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when request is unsuccessful' do
|
||||
it 'raises MessageNotSentError' do
|
||||
stub_request(:post, request_path)
|
||||
.to_return(
|
||||
status: 400,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: { 'data' => { 'key' => { 'id' => 'msg_123' } } }.to_json
|
||||
)
|
||||
|
||||
expect do
|
||||
service.send_message(test_send_phone_number, message)
|
||||
end.to raise_error(Whatsapp::Providers::WhatsappBaileysService::MessageNotSentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#api_headers' do
|
||||
|
||||
Loading…
Reference in New Issue
Block a user