mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 12:08:01 +00:00
We recently introduced the WhatsApp Embedded Signup flow in Chatwoot to simplify onboarding. However, we discovered two important limitations: Some customers’ numbers are already linked to an Embedded Signup, which blocks re-use. Tech providers cannot onboard their own numbers via Embedded Signup. As a result, we need to support both Manual and Embedded Signup flows to cover all scenarios. ### Problem - Current UI only offers the Embedded Signup option. - Customers who need to reuse existing numbers (already connected to WABA) or tech providers testing their own numbers get stuck. - Manual flow exists but is no longer exposed in the UX **Current Embedded Signup screen** <img width="2564" height="1250" alt="CleanShot 2025-08-21 at 21 58 07@2x" src="https://github.com/user-attachments/assets/c3de4cf1-cae6-4a0e-aa9c-5fa4e2249c0e" /> **Current Manual Setup screen** <img width="2568" height="1422" alt="CleanShot 2025-08-21 at 22 00 25@2x" src="https://github.com/user-attachments/assets/96408f97-3ffe-42d1-9019-a511e808f5ac" /> ### Solution - Design a dual-path UX in the Create WhatsApp Inbox step that: - Offers Embedded Signup (default/recommended) for new numbers and businesses. - Offers Manual Setup for advanced users, existing linked numbers, and tech providers. <img width="2030" height="1376" alt="CleanShot 2025-09-01 at 14 13 16@2x" src="https://github.com/user-attachments/assets/6f17e5a2-a2fd-40fb-826a-c9ee778be795" /> --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: iamsivin <iamsivin@gmail.com>
78 lines
2.3 KiB
Ruby
78 lines
2.3 KiB
Ruby
class Api::V1::Accounts::Whatsapp::AuthorizationsController < Api::V1::Accounts::BaseController
|
|
before_action :fetch_and_validate_inbox, if: -> { params[:inbox_id].present? }
|
|
|
|
# POST /api/v1/accounts/:account_id/whatsapp/authorization
|
|
# Handles both initial authorization and reauthorization
|
|
# If inbox_id is present in params, it performs reauthorization
|
|
def create
|
|
validate_embedded_signup_params!
|
|
channel = process_embedded_signup
|
|
render_success_response(channel.inbox)
|
|
rescue StandardError => e
|
|
render_error_response(e)
|
|
end
|
|
|
|
private
|
|
|
|
def process_embedded_signup
|
|
service = Whatsapp::EmbeddedSignupService.new(
|
|
account: Current.account,
|
|
params: params.permit(:code, :business_id, :waba_id, :phone_number_id).to_h.symbolize_keys,
|
|
inbox_id: params[:inbox_id]
|
|
)
|
|
service.perform
|
|
end
|
|
|
|
def fetch_and_validate_inbox
|
|
@inbox = Current.account.inboxes.find(params[:inbox_id])
|
|
validate_reauthorization_required
|
|
end
|
|
|
|
def validate_reauthorization_required
|
|
return if @inbox.channel.reauthorization_required? || can_upgrade_to_embedded_signup?
|
|
|
|
render json: {
|
|
success: false,
|
|
message: I18n.t('inbox.reauthorization.not_required')
|
|
}, status: :unprocessable_entity
|
|
end
|
|
|
|
def can_upgrade_to_embedded_signup?
|
|
channel = @inbox.channel
|
|
return false unless channel.provider == 'whatsapp_cloud'
|
|
|
|
true
|
|
end
|
|
|
|
def render_success_response(inbox)
|
|
response = {
|
|
success: true,
|
|
id: inbox.id,
|
|
name: inbox.name,
|
|
channel_type: 'whatsapp'
|
|
}
|
|
response[:message] = I18n.t('inbox.reauthorization.success') if params[:inbox_id].present?
|
|
render json: response
|
|
end
|
|
|
|
def render_error_response(error)
|
|
Rails.logger.error "[WHATSAPP AUTHORIZATION] Embedded signup error: #{error.message}"
|
|
Rails.logger.error error.backtrace.join("\n")
|
|
render json: {
|
|
success: false,
|
|
error: error.message
|
|
}, status: :unprocessable_entity
|
|
end
|
|
|
|
def validate_embedded_signup_params!
|
|
missing_params = []
|
|
missing_params << 'code' if params[:code].blank?
|
|
missing_params << 'business_id' if params[:business_id].blank?
|
|
missing_params << 'waba_id' if params[:waba_id].blank?
|
|
|
|
return if missing_params.empty?
|
|
|
|
raise ArgumentError, "Required parameters are missing: #{missing_params.join(', ')}"
|
|
end
|
|
end
|