fix: Handle PermissionDeniedError for Dialogflow processor (#8252)

This commit is contained in:
Pranav Raj S
2023-10-30 13:24:03 -07:00
committed by GitHub
parent 013dab7da6
commit 653e0335c0
8 changed files with 82 additions and 20 deletions

View File

@@ -7,6 +7,13 @@ class AdministratorNotifications::ChannelNotificationsMailer < ApplicationMailer
send_mail_with_liquid(to: admin_emails, subject: subject) and return
end
def dialogflow_disconnect
return unless smtp_config_set_or_development?
subject = 'Your Dialogflow integration was disconnected'
send_mail_with_liquid(to: admin_emails, subject: subject) and return
end
def facebook_disconnect(inbox)
return unless smtp_config_set_or_development?

View File

@@ -39,15 +39,25 @@ module Reauthorizable
def prompt_reauthorization!
::Redis::Alfred.set(reauthorization_required_key, true)
mailer = AdministratorNotifications::ChannelNotificationsMailer.with(account: account)
case self.class.name
when 'Integrations::Hook'
AdministratorNotifications::ChannelNotificationsMailer.with(account: account).slack_disconnect.deliver_later if slack?
process_integration_hook_reauthorization_emails(mailer)
when 'Channel::FacebookPage'
AdministratorNotifications::ChannelNotificationsMailer.with(account: account).facebook_disconnect(inbox).deliver_later
mailer.facebook_disconnect(inbox).deliver_later
when 'Channel::Whatsapp'
AdministratorNotifications::ChannelNotificationsMailer.with(account: account).whatsapp_disconnect(inbox).deliver_later
mailer.whatsapp_disconnect(inbox).deliver_later
when 'Channel::Email'
AdministratorNotifications::ChannelNotificationsMailer.with(account: account).email_disconnect(inbox).deliver_later
mailer.email_disconnect(inbox).deliver_later
end
end
def process_integration_hook_reauthorization_emails(mailer)
if slack?
mailer.slack_disconnect.deliver_later
elsif dialogflow?
mailer.dialogflow_disconnect.deliver_later
end
end

View File

@@ -129,7 +129,7 @@ class Inbox < ApplicationRecord
end
def active_bot?
agent_bot_inbox&.active? || hooks.pluck(:app_id).include?('dialogflow')
agent_bot_inbox&.active? || hooks.where(app_id: 'dialogflow', status: 'enabled').count.positive?
end
def inbox_type

View File

@@ -43,6 +43,10 @@ class Integrations::Hook < ApplicationRecord
app_id == 'slack'
end
def dialogflow?
app_id == 'dialogflow'
end
def disable
update(status: 'disabled')
end

View File

@@ -0,0 +1,3 @@
<p>Hello there,</p>
<p>Your Dialogflow integration was disconnected because of permission issues. To resolve this, please delete the integration from the admin dashboard and reconnect it using new credentials.</p>

View File

@@ -19,15 +19,12 @@ class Integrations::Dialogflow::ProcessorService < Integrations::BotProcessorSer
Rails.logger.warn "Account: #{hook.try(:account_id)} Hook: #{hook.id} credentials are not present." && return
end
::Google::Cloud::Dialogflow::V2::Sessions::Client.configure do |config|
config.timeout = 10.0
config.credentials = hook.settings['credentials']
end
client = ::Google::Cloud::Dialogflow::V2::Sessions::Client.new
session = "projects/#{hook.settings['project_id']}/agent/sessions/#{session_id}"
query_input = { text: { text: message, language_code: 'en-US' } }
client.detect_intent session: session, query_input: query_input
configure_dialogflow_client_defaults
detect_intent(session_id, message)
rescue Google::Cloud::PermissionDeniedError => e
Rails.logger.warn "DialogFlow Error: (account-#{hook.try(:account_id)}, hook-#{hook.id}) #{e.message}"
hook.prompt_reauthorization!
hook.disable
end
def process_response(message, response)
@@ -53,10 +50,28 @@ class Integrations::Dialogflow::ProcessorService < Integrations::BotProcessorSer
return if content_params.blank?
conversation = message.conversation
conversation.messages.create!(content_params.merge({
message_type: :outgoing,
account_id: conversation.account_id,
inbox_id: conversation.inbox_id
}))
conversation.messages.create!(
content_params.merge(
{
message_type: :outgoing,
account_id: conversation.account_id,
inbox_id: conversation.inbox_id
}
)
)
end
def configure_dialogflow_client_defaults
::Google::Cloud::Dialogflow::V2::Sessions::Client.configure do |config|
config.timeout = 10.0
config.credentials = hook.settings['credentials']
end
end
def detect_intent(session_id, message)
client = ::Google::Cloud::Dialogflow::V2::Sessions::Client.new
session = "projects/#{hook.settings['project_id']}/agent/sessions/#{session_id}"
query_input = { text: { text: message, language_code: 'en-US' } }
client.detect_intent session: session, query_input: query_input
end
end

View File

@@ -162,10 +162,17 @@ describe Integrations::Dialogflow::ProcessorService do
allow(session_client).to receive(:detect_intent).and_return({ session: session, query_input: query_input })
end
it 'returns indented response' do
it 'returns intended response' do
response = processor.send(:get_response, conversation.contact_inbox.source_id, message.content)
expect(response[:query_input][:text][:text]).to eq(message)
expect(response[:query_input][:text][:language_code]).to eq('en-US')
end
it 'disables the hook if permission errors are thrown' do
allow(session_client).to receive(:detect_intent).and_raise(Google::Cloud::PermissionDeniedError)
expect { processor.send(:get_response, conversation.contact_inbox.source_id, message.content) }
.to change(hook, :status).from('enabled').to('disabled')
end
end
end

View File

@@ -25,6 +25,22 @@ RSpec.describe AdministratorNotifications::ChannelNotificationsMailer do
end
end
describe 'dialogflow disconnect' do
let(:mail) { described_class.with(account: account).dialogflow_disconnect.deliver_now }
it 'renders the subject' do
expect(mail.subject).to eq('Your Dialogflow integration was disconnected')
end
it 'renders the content' do
expect(mail.body).to include('Your Dialogflow integration was disconnected because of permission issues.')
end
it 'renders the receiver email' do
expect(mail.to).to eq([administrator.email])
end
end
describe 'facebook_disconnect' do
before do
stub_request(:post, /graph.facebook.com/)