feat: Add WhatsApp reauthorization bankend flow

This commit is contained in:
Tanmay Deep Sharma
2025-07-10 03:09:16 +07:00
parent 358ec8120b
commit 9007bf1ecf
5 changed files with 195 additions and 1 deletions
@@ -32,6 +32,28 @@ class Whatsapp::EmbeddedController < ApplicationController
handle_signup_error(e)
end
def reauthorize
# Reauthorize existing WhatsApp inbox using embedded signup flow
validate_authorization_code!
return if performed?
validate_required_parameters!
return if performed?
validate_inbox_id!
return if performed?
channel = process_reauthorization
@inbox = channel.inbox
# Clear reauthorization required flag
channel.reauthorized!
render json: { message: 'WhatsApp channel reauthorized successfully' }, status: :ok
rescue StandardError => e
handle_signup_error(e)
end
private
def validate_authorization_code!
@@ -51,6 +73,14 @@ class Whatsapp::EmbeddedController < ApplicationController
}, status: :bad_request
end
def validate_inbox_id!
return if params[:inbox_id].present?
render json: {
error: 'Missing inbox_id parameter'
}, status: :bad_request
end
def process_signup
service = Whatsapp::EmbeddedSignupService.new(
account: Current.account,
@@ -63,6 +93,19 @@ class Whatsapp::EmbeddedController < ApplicationController
service.perform
end
def process_reauthorization
service = Whatsapp::EmbeddedSignupService.new(
account: Current.account,
code: params[:code],
business_id: params[:business_id],
waba_id: params[:waba_id],
phone_number_id: params[:phone_number_id],
inbox_id: params[:inbox_id]
)
service.perform_reauthorization
end
def handle_signup_error(error)
Rails.logger.error("WhatsApp embedded signup processing error: #{error.message}")
Rails.logger.error(error.backtrace.join("\n"))
@@ -1,12 +1,13 @@
class Whatsapp::EmbeddedSignupService
include Rails.application.routes.url_helpers
def initialize(account:, code:, business_id:, waba_id:, phone_number_id:)
def initialize(account:, code:, business_id:, waba_id:, phone_number_id:, inbox_id: nil)
@account = account
@code = code
@business_id = business_id
@waba_id = waba_id
@phone_number_id = phone_number_id
@inbox_id = inbox_id
end
def perform
@@ -33,6 +34,43 @@ class Whatsapp::EmbeddedSignupService
raise e
end
def perform_reauthorization
# Validate required parameters
unless @code.present? && @business_id.present? && @waba_id.present? && @phone_number_id.present? && @inbox_id.present?
raise ArgumentError, 'Code, business_id, waba_id, phone_number_id, and inbox_id are all required for reauthorization'
end
# Find the existing inbox and channel
inbox = @account.inboxes.find_by(id: @inbox_id)
raise ActiveRecord::RecordNotFound, 'Inbox not found' unless inbox
raise ArgumentError, 'Inbox is not a WhatsApp channel' unless inbox.channel_type == 'Channel::Whatsapp'
channel = inbox.channel
raise ArgumentError, 'Channel is not WhatsApp Cloud provider' unless channel.provider == 'whatsapp_cloud'
GlobalConfig.clear_cache
# Exchange code for new access token
access_token = exchange_code_for_token
# Use the provided business info directly
phone_info = fetch_phone_info_via_waba(@waba_id, @phone_number_id, access_token)
# Validate that the token has access to the provided WABA
validate_token_waba_access(access_token, @waba_id)
# Update the channel with new access token and configuration
update_channel_for_reauthorization(channel, phone_info, access_token)
# Re-register webhook with new token
register_phone_number(phone_info[:phone_number_id], access_token)
override_waba_webhook(@waba_id, channel, access_token)
channel
rescue StandardError => e
Rails.logger.error("[WHATSAPP] Reauthorization failed: #{e.message}")
raise e
end
private
def whatsapp_api_version
@@ -138,6 +176,18 @@ class Whatsapp::EmbeddedSignupService
)
end
def update_channel_for_reauthorization(channel, phone_info, access_token)
# Update channel with new access token and configuration
channel.update!(
provider_config: channel.provider_config.merge(
'api_key' => access_token,
'phone_number_id' => phone_info[:phone_number_id],
'business_account_id' => @waba_id,
'reauthorized_at' => Time.current.iso8601
)
)
end
def sanitize_phone_number(phone_number)
return phone_number if phone_number.blank?
@@ -116,4 +116,5 @@ json.provider resource.channel.try(:provider)
if resource.whatsapp?
json.message_templates resource.channel.try(:message_templates)
json.provider_config resource.channel.try(:provider_config) if Current.account_user&.administrator?
json.reauthorization_required resource.channel.try(:reauthorization_required?)
end