feat(wa-cloud): reaction messages and meta is_record_audio for voice messages (#111)

* feat: add send_reaction_message method and corresponding tests

* chore: useless comment from previous PR

* feat(wa-cloud): set is_recorded_audio for voice message
This commit is contained in:
Gabriel Jablonski 2025-09-10 09:02:06 -03:00 committed by GitHub
parent 3dac94e058
commit 6cd0a3bf7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 70 additions and 3 deletions

View File

@ -126,7 +126,8 @@ class Whatsapp::IncomingMessageBaseService
io: attachment_file,
filename: attachment_file.original_filename,
content_type: attachment_file.content_type
}
},
meta: ({ is_recorded_audio: true } if attachment_payload[:voice])
)
end

View File

@ -1,4 +1,4 @@
class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseService
class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseService # rubocop:disable Metrics/ClassLength
def send_message(phone_number, message)
@message = message
@ -6,6 +6,8 @@ class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseServi
send_attachment_message(phone_number, message)
elsif message.content_type == 'input_select'
send_interactive_text_message(phone_number, message)
elsif message.content_attributes[:is_reaction]
send_reaction_message(phone_number, message)
else
send_text_message(phone_number, message)
end
@ -219,4 +221,23 @@ class Whatsapp::Providers::WhatsappCloudService < Whatsapp::Providers::BaseServi
response.success?
end
def send_reaction_message(phone_number, message)
response = HTTParty.post(
"#{phone_id_path('v23.0')}/messages",
headers: api_headers,
body: {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to: phone_number,
type: 'reaction',
reaction: {
message_id: message.content_attributes[:in_reply_to_external_id],
emoji: message.outgoing_content
}
}.to_json
)
process_response(response, message)
end
end

View File

@ -18,7 +18,6 @@ RSpec.describe Article do
it { is_expected.to belong_to(:author) }
end
# This validation happens in ApplicationRecord
describe 'length validations' do
let(:article) do
create(:article, category_id: category_1.id, content: 'This is the content', description: 'this is the description',

View File

@ -223,6 +223,28 @@ describe Whatsapp::IncomingMessageService do
expect(whatsapp_channel.inbox.messages.first.content).to eq('Check out my product!')
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be true
end
it 'sets is_recorded_audio metadata for voice messages' do
stub_request(:get, whatsapp_channel.media_url('b1c68f38-8734-4ad3-b4a1-ef0c10d683')).to_return(
status: 200,
body: File.read('spec/assets/sample.mp3'),
headers: {}
)
params = {
'contacts' => [{ 'profile' => { 'name' => 'Sojan Jose' }, 'wa_id' => '2423423243' }],
'messages' => [{ 'from' => '2423423243', 'id' => 'SDFADSf23sfasdafasdfa',
'audio' => { 'id' => 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
'mime_type' => 'audio/mp3',
'sha256' => 'fa2820256f2cd3f2df03fa247d7b01e79d3fe794344aadcea08cee06bcce3c94',
'voice' => true },
'timestamp' => '1633034394', 'type' => 'audio' }]
}.with_indifferent_access
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
expect(whatsapp_channel.inbox.messages.first.attachments.first.meta['is_recorded_audio']).to be true
end
end
context 'when valid location message params' do

View File

@ -402,4 +402,28 @@ describe Whatsapp::Providers::WhatsappCloudService do
expect(Rails.logger).to have_received(:error)
end
end
describe '#send_reaction_message' do
it 'calls messages endpoint to send reaction message' do
message_with_reaction = create(:message, message_type: :outgoing, content: '👍', conversation: conversation,
inbox: whatsapp_channel.inbox, content_attributes: { is_reaction: true, in_reply_to: message.id })
stub_request(:post, 'https://graph.facebook.com/v23.0/123456789/messages')
.with(
body: {
messaging_product: 'whatsapp',
recipient_type: 'individual',
to: '+123456789',
type: 'reaction',
reaction: {
message_id: message.source_id,
emoji: '👍'
}
}.to_json
)
.to_return(status: 200, body: whatsapp_response.to_json, headers: response_headers)
expect(service.send_message('+123456789', message_with_reaction)).to eq 'message_id'
end
end
end