mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-29 02:02:27 +00:00
## Description This PR introduces WhatsApp Embedded Signup functionality, enabling users to connect their WhatsApp Business accounts through Meta's streamlined OAuth flow without manual webhook configuration. This significantly improves the user experience by automating the entire setup process. **Key Features:** - Embedded signup flow using Facebook SDK and Meta's OAuth 2.0 - Automatic webhook registration and phone number configuration - Enhanced provider selection UI with card-based design - Real-time progress tracking during signup process - Comprehensive error handling and user feedback ## Required Configuration The following environment variables must be configured by administrators before this feature can be used: Super Admin Configuration (via super_admin/app_config?config=whatsapp_embedded) - `WHATSAPP_APP_ID`: The Facebook App ID for WhatsApp Business API integration - `WHATSAPP_CONFIGURATION_ID`: The Configuration ID for WhatsApp Embedded Signup flow (obtained from Meta Developer Portal) - `WHATSAPP_APP_SECRET`: The App Secret for WhatsApp Embedded Signup flow (required for token exchange)  ## How Has This Been Tested? #### Backend Tests (RSpec): - Authentication validation for embedded signup endpoints - Authorization code validation and error handling - Missing business parameter validation - Proper response format for configuration endpoint - Unauthorized access prevention #### Manual Test Cases: - Complete embedded signup flow (happy path) - Provider selection UI navigation - Facebook authentication popup handling - Error scenarios (cancelled auth, invalid business data, API failures) - Configuration presence/absence behavior ## Related Screenshots:      Fixes https://linear.app/chatwoot/issue/CW-2131/spec-for-whatsapp-cloud-channels-sign-in-with-facebook --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: iamsivin <iamsivin@gmail.com> Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: Sojan Jose <sojan@pepalo.com>
573 lines
20 KiB
Ruby
573 lines
20 KiB
Ruby
Rails.application.routes.draw do
|
|
# AUTH STARTS
|
|
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
|
|
confirmations: 'devise_overrides/confirmations',
|
|
passwords: 'devise_overrides/passwords',
|
|
sessions: 'devise_overrides/sessions',
|
|
token_validations: 'devise_overrides/token_validations',
|
|
omniauth_callbacks: 'devise_overrides/omniauth_callbacks'
|
|
}, via: [:get, :post]
|
|
|
|
## renders the frontend paths only if its not an api only server
|
|
if ActiveModel::Type::Boolean.new.cast(ENV.fetch('CW_API_ONLY_SERVER', false))
|
|
root to: 'api#index'
|
|
else
|
|
root to: 'dashboard#index'
|
|
|
|
get '/app', to: 'dashboard#index'
|
|
get '/app/*params', to: 'dashboard#index'
|
|
get '/app/accounts/:account_id/settings/inboxes/new/twitter', to: 'dashboard#index', as: 'app_new_twitter_inbox'
|
|
get '/app/accounts/:account_id/settings/inboxes/new/microsoft', to: 'dashboard#index', as: 'app_new_microsoft_inbox'
|
|
get '/app/accounts/:account_id/settings/inboxes/new/instagram', to: 'dashboard#index', as: 'app_new_instagram_inbox'
|
|
get '/app/accounts/:account_id/settings/inboxes/new/:inbox_id/agents', to: 'dashboard#index', as: 'app_twitter_inbox_agents'
|
|
get '/app/accounts/:account_id/settings/inboxes/new/:inbox_id/agents', to: 'dashboard#index', as: 'app_email_inbox_agents'
|
|
get '/app/accounts/:account_id/settings/inboxes/new/:inbox_id/agents', to: 'dashboard#index', as: 'app_instagram_inbox_agents'
|
|
get '/app/accounts/:account_id/settings/inboxes/:inbox_id', to: 'dashboard#index', as: 'app_instagram_inbox_settings'
|
|
get '/app/accounts/:account_id/settings/inboxes/:inbox_id', to: 'dashboard#index', as: 'app_email_inbox_settings'
|
|
|
|
resource :widget, only: [:show]
|
|
namespace :survey do
|
|
resources :responses, only: [:show]
|
|
end
|
|
resource :slack_uploads, only: [:show]
|
|
end
|
|
|
|
get '/api', to: 'api#index'
|
|
namespace :api, defaults: { format: 'json' } do
|
|
namespace :v1 do
|
|
# ----------------------------------
|
|
# start of account scoped api routes
|
|
resources :accounts, only: [:create, :show, :update] do
|
|
member do
|
|
post :update_active_at
|
|
get :cache_keys
|
|
end
|
|
|
|
scope module: :accounts do
|
|
namespace :actions do
|
|
resource :contact_merge, only: [:create]
|
|
end
|
|
resource :bulk_actions, only: [:create]
|
|
resources :agents, only: [:index, :create, :update, :destroy] do
|
|
post :bulk_create, on: :collection
|
|
end
|
|
namespace :captain do
|
|
resources :assistants do
|
|
member do
|
|
post :playground
|
|
end
|
|
resources :inboxes, only: [:index, :create, :destroy], param: :inbox_id
|
|
resources :scenarios
|
|
end
|
|
resources :assistant_responses
|
|
resources :bulk_actions, only: [:create]
|
|
resources :copilot_threads, only: [:index, :create] do
|
|
resources :copilot_messages, only: [:index, :create]
|
|
end
|
|
resources :documents, only: [:index, :show, :create, :destroy]
|
|
end
|
|
resources :agent_bots, only: [:index, :create, :show, :update, :destroy] do
|
|
delete :avatar, on: :member
|
|
post :reset_access_token, on: :member
|
|
end
|
|
resources :contact_inboxes, only: [] do
|
|
collection do
|
|
post :filter
|
|
end
|
|
end
|
|
resources :assignable_agents, only: [:index]
|
|
resource :audit_logs, only: [:show]
|
|
resources :callbacks, only: [] do
|
|
collection do
|
|
post :register_facebook_page
|
|
get :register_facebook_page
|
|
post :facebook_pages
|
|
post :reauthorize_page
|
|
end
|
|
end
|
|
resources :canned_responses, only: [:index, :create, :update, :destroy]
|
|
resources :automation_rules, only: [:index, :create, :show, :update, :destroy] do
|
|
post :clone
|
|
end
|
|
resources :macros, only: [:index, :create, :show, :update, :destroy] do
|
|
post :execute, on: :member
|
|
end
|
|
resources :sla_policies, only: [:index, :create, :show, :update, :destroy]
|
|
resources :custom_roles, only: [:index, :create, :show, :update, :destroy]
|
|
resources :campaigns, only: [:index, :create, :show, :update, :destroy]
|
|
resources :dashboard_apps, only: [:index, :show, :create, :update, :destroy]
|
|
namespace :channels do
|
|
resource :twilio_channel, only: [:create]
|
|
end
|
|
resources :conversations, only: [:index, :create, :show, :update, :destroy] do
|
|
collection do
|
|
get :meta
|
|
get :search
|
|
post :filter
|
|
end
|
|
scope module: :conversations do
|
|
resources :messages, only: [:index, :create, :destroy, :update] do
|
|
member do
|
|
post :translate
|
|
post :retry
|
|
end
|
|
end
|
|
resources :assignments, only: [:create]
|
|
resources :labels, only: [:create, :index]
|
|
resource :participants, only: [:show, :create, :update, :destroy]
|
|
resource :direct_uploads, only: [:create]
|
|
resource :draft_messages, only: [:show, :update, :destroy]
|
|
end
|
|
member do
|
|
post :mute
|
|
post :unmute
|
|
post :transcript
|
|
post :toggle_status
|
|
post :toggle_priority
|
|
post :toggle_typing_status
|
|
post :update_last_seen
|
|
post :unread
|
|
post :custom_attributes
|
|
get :attachments
|
|
get :inbox_assistant
|
|
end
|
|
end
|
|
|
|
resources :search, only: [:index] do
|
|
collection do
|
|
get :conversations
|
|
get :messages
|
|
get :contacts
|
|
get :articles
|
|
end
|
|
end
|
|
|
|
resources :contacts, only: [:index, :show, :update, :create, :destroy] do
|
|
collection do
|
|
get :active
|
|
get :search
|
|
post :filter
|
|
post :import
|
|
post :export
|
|
end
|
|
member do
|
|
get :contactable_inboxes
|
|
post :destroy_custom_attributes
|
|
delete :avatar
|
|
end
|
|
scope module: :contacts do
|
|
resources :conversations, only: [:index]
|
|
resources :contact_inboxes, only: [:create]
|
|
resources :labels, only: [:create, :index]
|
|
resources :notes
|
|
end
|
|
end
|
|
resources :csat_survey_responses, only: [:index] do
|
|
collection do
|
|
get :metrics
|
|
get :download
|
|
end
|
|
end
|
|
resources :applied_slas, only: [:index] do
|
|
collection do
|
|
get :metrics
|
|
get :download
|
|
end
|
|
end
|
|
resources :custom_attribute_definitions, only: [:index, :show, :create, :update, :destroy]
|
|
resources :custom_filters, only: [:index, :show, :create, :update, :destroy]
|
|
resources :inboxes, only: [:index, :show, :create, :update, :destroy] do
|
|
get :assignable_agents, on: :member
|
|
get :campaigns, on: :member
|
|
get :agent_bot, on: :member
|
|
post :set_agent_bot, on: :member
|
|
delete :avatar, on: :member
|
|
end
|
|
resources :inbox_members, only: [:create, :show], param: :inbox_id do
|
|
collection do
|
|
delete :destroy
|
|
patch :update
|
|
end
|
|
end
|
|
resources :labels, only: [:index, :show, :create, :update, :destroy]
|
|
|
|
resources :notifications, only: [:index, :update, :destroy] do
|
|
collection do
|
|
post :read_all
|
|
get :unread_count
|
|
post :destroy_all
|
|
end
|
|
member do
|
|
post :snooze
|
|
post :unread
|
|
end
|
|
end
|
|
resource :notification_settings, only: [:show, :update]
|
|
|
|
resources :teams do
|
|
resources :team_members, only: [:index, :create] do
|
|
collection do
|
|
delete :destroy
|
|
patch :update
|
|
end
|
|
end
|
|
end
|
|
|
|
namespace :twitter do
|
|
resource :authorization, only: [:create]
|
|
end
|
|
|
|
namespace :microsoft do
|
|
resource :authorization, only: [:create]
|
|
end
|
|
|
|
namespace :google do
|
|
resource :authorization, only: [:create]
|
|
end
|
|
|
|
namespace :instagram do
|
|
resource :authorization, only: [:create]
|
|
end
|
|
|
|
namespace :notion do
|
|
resource :authorization, only: [:create]
|
|
end
|
|
|
|
namespace :whatsapp do
|
|
resource :authorization, only: [:create]
|
|
end
|
|
|
|
resources :webhooks, only: [:index, :create, :update, :destroy]
|
|
namespace :integrations do
|
|
resources :apps, only: [:index, :show]
|
|
resources :hooks, only: [:show, :create, :update, :destroy] do
|
|
member do
|
|
post :process_event
|
|
end
|
|
end
|
|
resource :slack, only: [:create, :update, :destroy], controller: 'slack' do
|
|
member do
|
|
get :list_all_channels
|
|
end
|
|
end
|
|
resource :dyte, controller: 'dyte', only: [] do
|
|
collection do
|
|
post :create_a_meeting
|
|
post :add_participant_to_meeting
|
|
end
|
|
end
|
|
resource :shopify, controller: 'shopify', only: [:destroy] do
|
|
collection do
|
|
post :auth
|
|
get :orders
|
|
end
|
|
end
|
|
resource :linear, controller: 'linear', only: [] do
|
|
collection do
|
|
delete :destroy
|
|
get :teams
|
|
get :team_entities
|
|
post :create_issue
|
|
post :link_issue
|
|
post :unlink_issue
|
|
get :search_issue
|
|
get :linked_issues
|
|
end
|
|
end
|
|
resource :notion, controller: 'notion', only: [] do
|
|
collection do
|
|
delete :destroy
|
|
end
|
|
end
|
|
end
|
|
resources :working_hours, only: [:update]
|
|
|
|
resources :portals do
|
|
member do
|
|
patch :archive
|
|
delete :logo
|
|
end
|
|
resources :categories
|
|
resources :articles do
|
|
post :reorder, on: :collection
|
|
end
|
|
end
|
|
|
|
resources :upload, only: [:create]
|
|
end
|
|
end
|
|
# end of account scoped api routes
|
|
# ----------------------------------
|
|
|
|
namespace :integrations do
|
|
resources :webhooks, only: [:create]
|
|
end
|
|
|
|
resource :profile, only: [:show, :update] do
|
|
delete :avatar, on: :collection
|
|
member do
|
|
post :availability
|
|
post :auto_offline
|
|
put :set_active_account
|
|
post :resend_confirmation
|
|
post :reset_access_token
|
|
end
|
|
end
|
|
|
|
resource :notification_subscriptions, only: [:create, :destroy]
|
|
|
|
namespace :widget do
|
|
resource :direct_uploads, only: [:create]
|
|
resource :config, only: [:create]
|
|
resources :campaigns, only: [:index]
|
|
resources :events, only: [:create]
|
|
resources :messages, only: [:index, :create, :update]
|
|
resources :conversations, only: [:index, :create] do
|
|
collection do
|
|
post :destroy_custom_attributes
|
|
post :set_custom_attributes
|
|
post :update_last_seen
|
|
post :toggle_typing
|
|
post :transcript
|
|
get :toggle_status
|
|
end
|
|
end
|
|
resource :contact, only: [:show, :update] do
|
|
collection do
|
|
post :destroy_custom_attributes
|
|
patch :set_user
|
|
end
|
|
end
|
|
resources :inbox_members, only: [:index]
|
|
resources :labels, only: [:create, :destroy]
|
|
namespace :integrations do
|
|
resource :dyte, controller: 'dyte', only: [] do
|
|
collection do
|
|
post :add_participant_to_meeting
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
namespace :v2 do
|
|
resources :accounts, only: [:create] do
|
|
scope module: :accounts do
|
|
resources :summary_reports, only: [] do
|
|
collection do
|
|
get :agent
|
|
get :team
|
|
get :inbox
|
|
get :label
|
|
end
|
|
end
|
|
resources :reports, only: [:index] do
|
|
collection do
|
|
get :summary
|
|
get :bot_summary
|
|
get :agents
|
|
get :inboxes
|
|
get :labels
|
|
get :teams
|
|
get :conversations
|
|
get :conversation_traffic
|
|
get :bot_metrics
|
|
end
|
|
end
|
|
resources :live_reports, only: [] do
|
|
collection do
|
|
get :conversation_metrics
|
|
get :grouped_conversation_metrics
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if ChatwootApp.enterprise?
|
|
namespace :enterprise, defaults: { format: 'json' } do
|
|
namespace :api do
|
|
namespace :v1 do
|
|
resources :accounts do
|
|
member do
|
|
post :checkout
|
|
post :subscription
|
|
get :limits
|
|
post :toggle_deletion
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
post 'webhooks/stripe', to: 'webhooks/stripe#process_payload'
|
|
post 'webhooks/firecrawl', to: 'webhooks/firecrawl#process_payload'
|
|
end
|
|
end
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Routes for platform APIs
|
|
namespace :platform, defaults: { format: 'json' } do
|
|
namespace :api do
|
|
namespace :v1 do
|
|
resources :users, only: [:create, :show, :update, :destroy] do
|
|
member do
|
|
get :login
|
|
post :token
|
|
end
|
|
end
|
|
resources :agent_bots, only: [:index, :create, :show, :update, :destroy] do
|
|
delete :avatar, on: :member
|
|
end
|
|
resources :accounts, only: [:create, :show, :update, :destroy] do
|
|
resources :account_users, only: [:index, :create] do
|
|
collection do
|
|
delete :destroy
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Routes for inbox APIs Exposed to contacts
|
|
namespace :public, defaults: { format: 'json' } do
|
|
namespace :api do
|
|
namespace :v1 do
|
|
resources :inboxes do
|
|
scope module: :inboxes do
|
|
resources :contacts, only: [:create, :show, :update] do
|
|
resources :conversations, only: [:index, :create, :show] do
|
|
member do
|
|
post :toggle_status
|
|
post :toggle_typing
|
|
post :update_last_seen
|
|
end
|
|
|
|
resources :messages, only: [:index, :create, :update]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
resources :csat_survey, only: [:show, :update]
|
|
end
|
|
end
|
|
end
|
|
|
|
get 'hc/:slug', to: 'public/api/v1/portals#show'
|
|
get 'hc/:slug/sitemap.xml', to: 'public/api/v1/portals#sitemap'
|
|
get 'hc/:slug/:locale', to: 'public/api/v1/portals#show'
|
|
get 'hc/:slug/:locale/articles', to: 'public/api/v1/portals/articles#index'
|
|
get 'hc/:slug/:locale/categories', to: 'public/api/v1/portals/categories#index'
|
|
get 'hc/:slug/:locale/categories/:category_slug', to: 'public/api/v1/portals/categories#show'
|
|
get 'hc/:slug/:locale/categories/:category_slug/articles', to: 'public/api/v1/portals/articles#index'
|
|
get 'hc/:slug/articles/:article_slug.png', to: 'public/api/v1/portals/articles#tracking_pixel'
|
|
get 'hc/:slug/articles/:article_slug', to: 'public/api/v1/portals/articles#show'
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Used in mailer templates
|
|
resource :app, only: [:index] do
|
|
resources :accounts do
|
|
resources :conversations, only: [:show]
|
|
end
|
|
end
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Routes for channel integrations
|
|
mount Facebook::Messenger::Server, at: 'bot'
|
|
get 'webhooks/twitter', to: 'api/v1/webhooks#twitter_crc'
|
|
post 'webhooks/twitter', to: 'api/v1/webhooks#twitter_events'
|
|
post 'webhooks/line/:line_channel_id', to: 'webhooks/line#process_payload'
|
|
post 'webhooks/telegram/:bot_token', to: 'webhooks/telegram#process_payload'
|
|
post 'webhooks/sms/:phone_number', to: 'webhooks/sms#process_payload'
|
|
get 'webhooks/whatsapp/:phone_number', to: 'webhooks/whatsapp#verify'
|
|
post 'webhooks/whatsapp/:phone_number', to: 'webhooks/whatsapp#process_payload'
|
|
get 'webhooks/instagram', to: 'webhooks/instagram#verify'
|
|
post 'webhooks/instagram', to: 'webhooks/instagram#events'
|
|
|
|
namespace :twitter do
|
|
resource :callback, only: [:show]
|
|
end
|
|
|
|
namespace :linear do
|
|
resource :callback, only: [:show]
|
|
end
|
|
|
|
namespace :shopify do
|
|
resource :callback, only: [:show]
|
|
end
|
|
|
|
namespace :twilio do
|
|
resources :callback, only: [:create]
|
|
resources :delivery_status, only: [:create]
|
|
end
|
|
|
|
get 'microsoft/callback', to: 'microsoft/callbacks#show'
|
|
get 'google/callback', to: 'google/callbacks#show'
|
|
get 'instagram/callback', to: 'instagram/callbacks#show'
|
|
get 'notion/callback', to: 'notion/callbacks#show'
|
|
# ----------------------------------------------------------------------
|
|
# Routes for external service verifications
|
|
get '.well-known/assetlinks.json' => 'android_app#assetlinks'
|
|
get '.well-known/apple-app-site-association' => 'apple_app#site_association'
|
|
get '.well-known/microsoft-identity-association.json' => 'microsoft#identity_association'
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Internal Monitoring Routes
|
|
require 'sidekiq/web'
|
|
require 'sidekiq/cron/web'
|
|
|
|
devise_for :super_admins, path: 'super_admin', controllers: { sessions: 'super_admin/devise/sessions' }
|
|
devise_scope :super_admin do
|
|
get 'super_admin/logout', to: 'super_admin/devise/sessions#destroy'
|
|
namespace :super_admin do
|
|
root to: 'dashboard#index'
|
|
|
|
resource :app_config, only: [:show, :create]
|
|
|
|
# order of resources affect the order of sidebar navigation in super admin
|
|
resources :accounts, only: [:index, :new, :create, :show, :edit, :update, :destroy] do
|
|
post :seed, on: :member
|
|
post :reset_cache, on: :member
|
|
end
|
|
resources :users, only: [:index, :new, :create, :show, :edit, :update, :destroy] do
|
|
delete :avatar, on: :member, action: :destroy_avatar
|
|
end
|
|
|
|
resources :access_tokens, only: [:index, :show]
|
|
resources :installation_configs, only: [:index, :new, :create, :show, :edit, :update]
|
|
resources :agent_bots, only: [:index, :new, :create, :show, :edit, :update, :destroy] do
|
|
delete :avatar, on: :member, action: :destroy_avatar
|
|
end
|
|
resources :platform_apps, only: [:index, :new, :create, :show, :edit, :update, :destroy]
|
|
resource :instance_status, only: [:show]
|
|
|
|
resource :settings, only: [:show] do
|
|
get :refresh, on: :collection
|
|
end
|
|
|
|
# resources that doesn't appear in primary navigation in super admin
|
|
resources :account_users, only: [:new, :create, :show, :destroy]
|
|
end
|
|
authenticated :super_admin do
|
|
mount Sidekiq::Web => '/monitoring/sidekiq'
|
|
end
|
|
end
|
|
|
|
namespace :installation do
|
|
get 'onboarding', to: 'onboarding#index'
|
|
post 'onboarding', to: 'onboarding#create'
|
|
end
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Routes for swagger docs
|
|
get '/swagger/*path', to: 'swagger#respond'
|
|
get '/swagger', to: 'swagger#respond'
|
|
|
|
# ----------------------------------------------------------------------
|
|
# Routes for testing
|
|
resources :widget_tests, only: [:index] unless Rails.env.production?
|
|
end
|