This update adds support to the coexistence method to Embedded Whatsapp, allowing users to add their existing whatsapp business number in order to use it in both places(chatwoot and whatsapp business) at the same time. This update require some changes in the permissions for the Meta App, as described in the Meta Oficial Docs, I'll leave this listed below: - **history** — describes past messages the business customer has sent/received - **smb_app_state_sync** — describes the business customer's current and new contacts - **smb_message_echoes** — describes any new messages the business customer sends with the WhatsApp Business app after having been onboarded Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Sojan Jose <sojan@pepalo.com> Co-authored-by: Tanmay Deep Sharma <32020192+tds-1@users.noreply.github.com>
153 lines
6.5 KiB
Ruby
153 lines
6.5 KiB
Ruby
require 'rails_helper'
|
|
|
|
describe Whatsapp::WebhookSetupService do
|
|
let(:channel) do
|
|
create(:channel_whatsapp,
|
|
phone_number: '+1234567890',
|
|
provider_config: {
|
|
'phone_number_id' => 'test_phone_id',
|
|
'webhook_verify_token' => 'test_verify_token'
|
|
},
|
|
provider: 'whatsapp_cloud',
|
|
sync_templates: false,
|
|
validate_provider_config: false)
|
|
end
|
|
let(:waba_id) { 'test_waba_id' }
|
|
let(:access_token) { 'test_access_token' }
|
|
let(:service) { described_class.new(channel, waba_id, access_token) }
|
|
let(:api_client) { instance_double(Whatsapp::FacebookApiClient) }
|
|
|
|
before do
|
|
# Clean up any existing channels to avoid phone number conflicts
|
|
Channel::Whatsapp.destroy_all
|
|
allow(Whatsapp::FacebookApiClient).to receive(:new).and_return(api_client)
|
|
end
|
|
|
|
describe '#perform' do
|
|
context 'when phone number is NOT verified (should register)' do
|
|
before do
|
|
allow(api_client).to receive(:phone_number_verified?).with('123456789').and_return(false)
|
|
allow(SecureRandom).to receive(:random_number).with(900_000).and_return(123_456)
|
|
allow(api_client).to receive(:register_phone_number).with('123456789', 223_456)
|
|
allow(api_client).to receive(:subscribe_waba_webhook)
|
|
.with(waba_id, anything, 'test_verify_token').and_return({ 'success' => true })
|
|
allow(channel).to receive(:save!)
|
|
end
|
|
|
|
it 'registers the phone number and sets up webhook' do
|
|
with_modified_env FRONTEND_URL: 'https://app.chatwoot.com' do
|
|
expect(api_client).to receive(:register_phone_number).with('123456789', 223_456)
|
|
expect(api_client).to receive(:subscribe_waba_webhook)
|
|
.with(waba_id, 'https://app.chatwoot.com/webhooks/whatsapp/+1234567890', 'test_verify_token')
|
|
service.perform
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when phone number IS verified (should NOT register)' do
|
|
before do
|
|
allow(api_client).to receive(:phone_number_verified?).with('123456789').and_return(true)
|
|
allow(api_client).to receive(:subscribe_waba_webhook)
|
|
.with(waba_id, anything, 'test_verify_token').and_return({ 'success' => true })
|
|
end
|
|
|
|
it 'does NOT register phone, but sets up webhook' do
|
|
with_modified_env FRONTEND_URL: 'https://app.chatwoot.com' do
|
|
expect(api_client).not_to receive(:register_phone_number)
|
|
expect(api_client).to receive(:subscribe_waba_webhook)
|
|
.with(waba_id, 'https://app.chatwoot.com/webhooks/whatsapp/+1234567890', 'test_verify_token')
|
|
service.perform
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when phone_number_verified? raises error' do
|
|
before do
|
|
allow(api_client).to receive(:phone_number_verified?).with('123456789').and_raise('API down')
|
|
allow(SecureRandom).to receive(:random_number).with(900_000).and_return(123_456)
|
|
allow(api_client).to receive(:register_phone_number)
|
|
allow(api_client).to receive(:subscribe_waba_webhook).and_return({ 'success' => true })
|
|
allow(channel).to receive(:save!)
|
|
end
|
|
|
|
it 'tries to register phone and proceeds with webhook setup' do
|
|
with_modified_env FRONTEND_URL: 'https://app.chatwoot.com' do
|
|
expect(api_client).to receive(:register_phone_number)
|
|
expect(api_client).to receive(:subscribe_waba_webhook)
|
|
expect { service.perform }.not_to raise_error
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when phone registration fails (not blocking)' do
|
|
before do
|
|
allow(api_client).to receive(:phone_number_verified?).with('123456789').and_return(false)
|
|
allow(SecureRandom).to receive(:random_number).with(900_000).and_return(123_456)
|
|
allow(api_client).to receive(:register_phone_number).and_raise('Registration failed')
|
|
allow(api_client).to receive(:subscribe_waba_webhook).and_return({ 'success' => true })
|
|
allow(channel).to receive(:save!)
|
|
end
|
|
|
|
it 'continues with webhook setup even if registration fails' do
|
|
with_modified_env FRONTEND_URL: 'https://app.chatwoot.com' do
|
|
expect(api_client).to receive(:register_phone_number)
|
|
expect(api_client).to receive(:subscribe_waba_webhook)
|
|
expect { service.perform }.not_to raise_error
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when webhook setup fails (should raise)' do
|
|
before do
|
|
allow(api_client).to receive(:phone_number_verified?).with('123456789').and_return(false)
|
|
allow(SecureRandom).to receive(:random_number).with(900_000).and_return(123_456)
|
|
allow(api_client).to receive(:register_phone_number)
|
|
allow(api_client).to receive(:subscribe_waba_webhook).and_raise('Webhook failed')
|
|
end
|
|
|
|
it 'raises an error' do
|
|
with_modified_env FRONTEND_URL: 'https://app.chatwoot.com' do
|
|
expect(api_client).to receive(:register_phone_number)
|
|
expect(api_client).to receive(:subscribe_waba_webhook)
|
|
expect { service.perform }.to raise_error(/Webhook setup failed/)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when required parameters are missing' do
|
|
it 'raises error when channel is nil' do
|
|
service_invalid = described_class.new(nil, waba_id, access_token)
|
|
expect { service_invalid.perform }.to raise_error(ArgumentError, 'Channel is required')
|
|
end
|
|
|
|
it 'raises error when waba_id is blank' do
|
|
service_invalid = described_class.new(channel, '', access_token)
|
|
expect { service_invalid.perform }.to raise_error(ArgumentError, 'WABA ID is required')
|
|
end
|
|
|
|
it 'raises error when access_token is blank' do
|
|
service_invalid = described_class.new(channel, waba_id, '')
|
|
expect { service_invalid.perform }.to raise_error(ArgumentError, 'Access token is required')
|
|
end
|
|
end
|
|
|
|
context 'when PIN already exists' do
|
|
before do
|
|
channel.provider_config['verification_pin'] = 123_456
|
|
allow(api_client).to receive(:phone_number_verified?).with('123456789').and_return(false)
|
|
allow(api_client).to receive(:register_phone_number)
|
|
allow(api_client).to receive(:subscribe_waba_webhook).and_return({ 'success' => true })
|
|
allow(channel).to receive(:save!)
|
|
end
|
|
|
|
it 'reuses existing PIN' do
|
|
with_modified_env FRONTEND_URL: 'https://app.chatwoot.com' do
|
|
expect(api_client).to receive(:register_phone_number).with('123456789', 123_456)
|
|
expect(SecureRandom).not_to receive(:random_number)
|
|
service.perform
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|