Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
144
research/chatwoot/app/controllers/tiktok/callbacks_controller.rb
Normal file
144
research/chatwoot/app/controllers/tiktok/callbacks_controller.rb
Normal file
@@ -0,0 +1,144 @@
|
||||
class Tiktok::CallbacksController < ApplicationController
|
||||
include Tiktok::IntegrationHelper
|
||||
|
||||
def show
|
||||
return handle_authorization_error if params[:error].present?
|
||||
return handle_ungranted_scopes_error unless all_scopes_granted?
|
||||
|
||||
process_successful_authorization
|
||||
rescue StandardError => e
|
||||
handle_error(e)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def all_scopes_granted?
|
||||
granted_scopes = short_term_access_token[:scope].to_s.split(',')
|
||||
(Tiktok::AuthClient::REQUIRED_SCOPES - granted_scopes).blank?
|
||||
end
|
||||
|
||||
def process_successful_authorization
|
||||
inbox, already_exists = find_or_create_inbox
|
||||
|
||||
if already_exists
|
||||
redirect_to app_tiktok_inbox_settings_url(account_id: account_id, inbox_id: inbox.id)
|
||||
else
|
||||
redirect_to app_tiktok_inbox_agents_url(account_id: account_id, inbox_id: inbox.id)
|
||||
end
|
||||
end
|
||||
|
||||
def handle_error(error)
|
||||
Rails.logger.error("TikTok Channel creation Error: #{error.message}")
|
||||
ChatwootExceptionTracker.new(error).capture_exception
|
||||
|
||||
redirect_to_error_page(error_type: error.class.name, code: 500, error_message: error.message)
|
||||
end
|
||||
|
||||
# Handles the case when a user denies permissions or cancels the authorization flow
|
||||
def handle_authorization_error
|
||||
redirect_to_error_page(
|
||||
error_type: params[:error] || 'access_denied',
|
||||
code: params[:error_code],
|
||||
error_message: params[:error_description] || 'User cancelled the Authorization'
|
||||
)
|
||||
end
|
||||
|
||||
# Handles the case when a user partially accepted the required scopes
|
||||
def handle_ungranted_scopes_error
|
||||
redirect_to_error_page(
|
||||
error_type: 'ungranted_scopes',
|
||||
code: 400,
|
||||
error_message: 'User did not grant all the required scopes'
|
||||
)
|
||||
end
|
||||
|
||||
# Centralized method to redirect to error page with appropriate parameters
|
||||
# This ensures consistent error handling across different error scenarios
|
||||
# Frontend will handle the error page based on the error_type
|
||||
def redirect_to_error_page(error_type:, code:, error_message:)
|
||||
redirect_to app_new_tiktok_inbox_url(
|
||||
account_id: account_id,
|
||||
error_type: error_type,
|
||||
code: code,
|
||||
error_message: error_message
|
||||
)
|
||||
end
|
||||
|
||||
def find_or_create_inbox
|
||||
business_details = tiktok_client.business_account_details
|
||||
channel_tiktok = find_channel
|
||||
channel_exists = channel_tiktok.present?
|
||||
|
||||
if channel_tiktok
|
||||
update_channel(channel_tiktok, business_details)
|
||||
else
|
||||
channel_tiktok = create_channel_with_inbox(business_details)
|
||||
end
|
||||
|
||||
# reauthorized will also update cache keys for the associated inbox
|
||||
channel_tiktok.reauthorized!
|
||||
|
||||
set_avatar(channel_tiktok.inbox, business_details[:profile_image]) if business_details[:profile_image].present?
|
||||
|
||||
[channel_tiktok.inbox, channel_exists]
|
||||
end
|
||||
|
||||
def create_channel_with_inbox(business_details)
|
||||
ActiveRecord::Base.transaction do
|
||||
channel_tiktok = Channel::Tiktok.create!(
|
||||
account: account,
|
||||
business_id: short_term_access_token[:business_id],
|
||||
access_token: short_term_access_token[:access_token],
|
||||
refresh_token: short_term_access_token[:refresh_token],
|
||||
expires_at: short_term_access_token[:expires_at],
|
||||
refresh_token_expires_at: short_term_access_token[:refresh_token_expires_at]
|
||||
)
|
||||
|
||||
account.inboxes.create!(
|
||||
account: account,
|
||||
channel: channel_tiktok,
|
||||
name: business_details[:display_name].presence || business_details[:username]
|
||||
)
|
||||
|
||||
channel_tiktok
|
||||
end
|
||||
end
|
||||
|
||||
def find_channel
|
||||
Channel::Tiktok.find_by(business_id: short_term_access_token[:business_id], account: account)
|
||||
end
|
||||
|
||||
def update_channel(channel_tiktok, business_details)
|
||||
channel_tiktok.update!(
|
||||
access_token: short_term_access_token[:access_token],
|
||||
refresh_token: short_term_access_token[:refresh_token],
|
||||
expires_at: short_term_access_token[:expires_at],
|
||||
refresh_token_expires_at: short_term_access_token[:refresh_token_expires_at]
|
||||
)
|
||||
|
||||
channel_tiktok.inbox.update!(name: business_details[:display_name].presence || business_details[:username])
|
||||
end
|
||||
|
||||
def set_avatar(inbox, avatar_url)
|
||||
Avatar::AvatarFromUrlJob.perform_later(inbox, avatar_url)
|
||||
end
|
||||
|
||||
def account_id
|
||||
@account_id ||= verify_tiktok_token(params[:state])
|
||||
end
|
||||
|
||||
def account
|
||||
@account ||= Account.find(account_id)
|
||||
end
|
||||
|
||||
def short_term_access_token
|
||||
@short_term_access_token ||= Tiktok::AuthClient.obtain_short_term_access_token(params[:code])
|
||||
end
|
||||
|
||||
def tiktok_client
|
||||
@tiktok_client ||= Tiktok::Client.new(
|
||||
business_id: short_term_access_token[:business_id],
|
||||
access_token: short_term_access_token[:access_token]
|
||||
)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user