feat(wuzapi): add send_buttons, send_list, send_url_button methods
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a4472b80b9
commit
7a203ccb6d
@ -79,6 +79,38 @@ class Wuzapi::Client # rubocop:disable Metrics/ClassLength
|
||||
)
|
||||
end
|
||||
|
||||
# Sends quick-reply buttons (up to 3 by WhatsApp limit).
|
||||
def send_buttons(user_token, phone_number, text, buttons)
|
||||
payload = {
|
||||
Phone: phone_number,
|
||||
Text: text,
|
||||
Buttons: buttons.map { |b| { DisplayText: b[:text] || b['text'] } }
|
||||
}
|
||||
request(:post, '/chat/sendbuttons', payload, user_auth_headers(user_token))
|
||||
end
|
||||
|
||||
# Sends a list menu (sections with rows).
|
||||
def send_list(user_token, phone_number, text:, button_text:, sections:, footer: nil)
|
||||
payload = {
|
||||
Phone: phone_number,
|
||||
Text: text,
|
||||
ButtonText: button_text,
|
||||
FooterText: footer,
|
||||
Sections: build_list_sections(sections)
|
||||
}.compact
|
||||
request(:post, '/chat/sendlist', payload, user_auth_headers(user_token))
|
||||
end
|
||||
|
||||
# Sends a single button that opens a URL when clicked.
|
||||
def send_url_button(user_token, phone_number, text:, button_text:, url:)
|
||||
payload = {
|
||||
Phone: phone_number,
|
||||
Text: text,
|
||||
Buttons: [{ Type: 'url', DisplayText: button_text, Url: url }]
|
||||
}
|
||||
request(:post, '/chat/sendbuttons', payload, user_auth_headers(user_token))
|
||||
end
|
||||
|
||||
def send_chat_presence(user_token, phone_number, state, media = nil)
|
||||
# State: "composing" or "paused"
|
||||
# Media: "audio" (optional)
|
||||
@ -401,4 +433,19 @@ class Wuzapi::Client # rubocop:disable Metrics/ClassLength
|
||||
def raise_authentication_error(response)
|
||||
raise AuthenticationError, "Authentication failed: #{response.code} #{response.body}"
|
||||
end
|
||||
|
||||
def build_list_sections(sections)
|
||||
sections.map do |s|
|
||||
{
|
||||
Title: s[:title] || s['title'],
|
||||
Rows: Array(s[:rows] || s['rows']).map do |r|
|
||||
{
|
||||
Title: r[:title] || r['title'],
|
||||
Description: r[:description] || r['description'],
|
||||
RowId: r[:row_id] || r['row_id']
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
67
spec/services/wuzapi/client_interactive_spec.rb
Normal file
67
spec/services/wuzapi/client_interactive_spec.rb
Normal file
@ -0,0 +1,67 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Wuzapi::Client do
|
||||
let(:base_url) { 'https://wuzapi.test' }
|
||||
let(:client) { described_class.new(base_url) }
|
||||
let(:user_token) { 'tok' }
|
||||
let(:phone) { '5561999999999' }
|
||||
|
||||
describe '#send_buttons' do
|
||||
it 'POSTs to /chat/sendbuttons with buttons payload' do
|
||||
stub = stub_request(:post, "#{base_url}/chat/sendbuttons")
|
||||
.with(
|
||||
headers: { 'Token' => user_token },
|
||||
body: hash_including(
|
||||
Phone: phone,
|
||||
Text: 'Curtiu?',
|
||||
Buttons: [
|
||||
{ DisplayText: 'Sim' },
|
||||
{ DisplayText: 'Não' }
|
||||
]
|
||||
)
|
||||
)
|
||||
.to_return(status: 200, body: { Id: 'msg-1' }.to_json, headers: { 'Content-Type' => 'application/json' })
|
||||
|
||||
response = client.send_buttons(
|
||||
user_token, phone, 'Curtiu?',
|
||||
[{ text: 'Sim' }, { text: 'Não' }]
|
||||
)
|
||||
expect(response).to be_a(Hash)
|
||||
expect(stub).to have_been_requested
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_list' do
|
||||
it 'POSTs to /chat/sendlist with sections' do
|
||||
stub = stub_request(:post, "#{base_url}/chat/sendlist")
|
||||
.with(headers: { 'Token' => user_token })
|
||||
.to_return(status: 200, body: { Id: 'msg-2' }.to_json, headers: { 'Content-Type' => 'application/json' })
|
||||
|
||||
response = client.send_list(
|
||||
user_token, phone,
|
||||
text: 'Cardápio',
|
||||
button_text: 'Ver opções',
|
||||
sections: [{ title: 'Bebidas', rows: [{ title: 'Água', row_id: 'agua' }] }]
|
||||
)
|
||||
expect(response).to be_a(Hash)
|
||||
expect(stub).to have_been_requested
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_url_button' do
|
||||
it 'POSTs to /chat/sendbuttons with URL button' do
|
||||
stub = stub_request(:post, "#{base_url}/chat/sendbuttons")
|
||||
.with(body: hash_including('Buttons' => array_including(hash_including('Type' => 'url'))))
|
||||
.to_return(status: 200, body: { Id: 'msg-3' }.to_json, headers: { 'Content-Type' => 'application/json' })
|
||||
|
||||
response = client.send_url_button(user_token, phone,
|
||||
text: 'Avalie no Google',
|
||||
button_text: 'Avaliar',
|
||||
url: 'https://g.page/r/XYZ')
|
||||
expect(response).to be_a(Hash)
|
||||
expect(stub).to have_been_requested
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user