mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-29 18:22:53 +00:00
chore: Add region option to Dialogflow integration (#11510)
## Summary - support region option when configuring Dialogflow integration - connect to region endpoint when set - use session identification based on the region Fixes: https://github.com/chatwoot/chatwoot/issues/4129
This commit is contained in:
@@ -84,6 +84,7 @@ dialogflow:
|
||||
{
|
||||
'project_id': { 'type': 'string' },
|
||||
'credentials': { 'type': 'object' },
|
||||
'region': { 'type': 'string' },
|
||||
},
|
||||
'required': ['project_id', 'credentials'],
|
||||
'additionalProperties': false,
|
||||
@@ -106,8 +107,21 @@ dialogflow:
|
||||
'validation-messages':
|
||||
{ 'JSON': 'Invalid JSON', 'required': 'Credentials is required' },
|
||||
},
|
||||
{
|
||||
'label': 'Dialogflow Region',
|
||||
'type': 'select',
|
||||
'name': 'region',
|
||||
'default': 'global',
|
||||
'options': [
|
||||
{ 'label': 'Global - Default', 'value': 'global' },
|
||||
{ 'label': 'AS-NE1 - Tokyo, Japan', 'value': 'asia-northeast1' },
|
||||
{ 'label': 'AU-SE1 - Sydney, Australia', 'value': 'australia-southeast1' },
|
||||
{ 'label': 'EU-W1 - St. Ghislain, Belgium', 'value': 'europe-west1' },
|
||||
{ 'label': 'EU-W2 - London, England', 'value': 'europe-west2' },
|
||||
],
|
||||
},
|
||||
]
|
||||
visible_properties: ['project_id']
|
||||
visible_properties: ['project_id', 'region']
|
||||
google_translate:
|
||||
id: google_translate
|
||||
logo: google-translate.png
|
||||
|
||||
@@ -65,13 +65,37 @@ class Integrations::Dialogflow::ProcessorService < Integrations::BotProcessorSer
|
||||
::Google::Cloud::Dialogflow::V2::Sessions::Client.configure do |config|
|
||||
config.timeout = 10.0
|
||||
config.credentials = hook.settings['credentials']
|
||||
config.endpoint = dialogflow_endpoint
|
||||
end
|
||||
end
|
||||
|
||||
def normalized_region
|
||||
region = hook.settings['region'].to_s.strip
|
||||
(region.presence || 'global')
|
||||
end
|
||||
|
||||
def dialogflow_endpoint
|
||||
region = normalized_region
|
||||
return 'dialogflow.googleapis.com' if region == 'global'
|
||||
|
||||
"#{region}-dialogflow.googleapis.com"
|
||||
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}"
|
||||
session = build_session_path(session_id)
|
||||
query_input = { text: { text: message, language_code: 'en-US' } }
|
||||
client.detect_intent session: session, query_input: query_input
|
||||
end
|
||||
|
||||
def build_session_path(session_id)
|
||||
project_id = hook.settings['project_id']
|
||||
region = normalized_region
|
||||
|
||||
if region == 'global'
|
||||
"projects/#{project_id}/agent/sessions/#{session_id}"
|
||||
else
|
||||
"projects/#{project_id}/locations/#{region}/agent/sessions/#{session_id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ RSpec.describe 'Integration Hooks API', type: :request do
|
||||
let(:admin) { create(:user, account: account, role: :administrator) }
|
||||
let(:agent) { create(:user, account: account, role: :agent) }
|
||||
let(:inbox) { create(:inbox, account: account) }
|
||||
let(:params) { { app_id: 'dialogflow', inbox_id: inbox.id, settings: { project_id: 'xx', credentials: { test: 'test' } } } }
|
||||
let(:params) { { app_id: 'dialogflow', inbox_id: inbox.id, settings: { project_id: 'xx', credentials: { test: 'test' }, region: 'europe-west1' } } }
|
||||
|
||||
describe 'POST /api/v1/accounts/{account.id}/integrations/hooks' do
|
||||
context 'when it is an unauthenticated user' do
|
||||
|
||||
@@ -9,7 +9,7 @@ FactoryBot.define do
|
||||
|
||||
trait :dialogflow do
|
||||
app_id { 'dialogflow' }
|
||||
settings { { project_id: 'test', credentials: {} } }
|
||||
settings { { project_id: 'test', credentials: {}, region: 'global' } }
|
||||
end
|
||||
|
||||
trait :dyte do
|
||||
|
||||
@@ -175,4 +175,65 @@ describe Integrations::Dialogflow::ProcessorService do
|
||||
.to change(hook, :status).from('enabled').to('disabled')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'region configuration' do
|
||||
let(:processor) { described_class.new(event_name: event_name, hook: hook, event_data: event_data) }
|
||||
|
||||
context 'when region is global or not specified' do
|
||||
it 'uses global endpoint and session path' do
|
||||
hook.update(settings: { 'project_id' => 'test-project', 'credentials' => {} })
|
||||
|
||||
expect(processor.send(:dialogflow_endpoint)).to eq('dialogflow.googleapis.com')
|
||||
expect(processor.send(:build_session_path, 'test-session')).to eq('projects/test-project/agent/sessions/test-session')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when region is specified' do
|
||||
it 'uses regional endpoint and session path' do
|
||||
hook.update(settings: { 'project_id' => 'test-project', 'credentials' => {}, 'region' => 'europe-west1' })
|
||||
|
||||
expect(processor.send(:dialogflow_endpoint)).to eq('europe-west1-dialogflow.googleapis.com')
|
||||
expect(processor.send(:build_session_path, 'test-session')).to eq('projects/test-project/locations/europe-west1/agent/sessions/test-session')
|
||||
end
|
||||
end
|
||||
|
||||
it 'configures client with correct endpoint' do
|
||||
hook.update(settings: { 'project_id' => 'test', 'credentials' => {}, 'region' => 'europe-west1' })
|
||||
config = OpenStruct.new
|
||||
expect(Google::Cloud::Dialogflow::V2::Sessions::Client).to receive(:configure).and_yield(config)
|
||||
|
||||
processor.send(:configure_dialogflow_client_defaults)
|
||||
expect(config.endpoint).to eq('europe-west1-dialogflow.googleapis.com')
|
||||
end
|
||||
|
||||
context 'when calling detect_intent' do
|
||||
let(:mock_client) { instance_double(Google::Cloud::Dialogflow::V2::Sessions::Client) }
|
||||
|
||||
before do
|
||||
allow(Google::Cloud::Dialogflow::V2::Sessions::Client).to receive(:new).and_return(mock_client)
|
||||
end
|
||||
|
||||
it 'uses global session path when region is not specified' do
|
||||
hook.update(settings: { 'project_id' => 'test-project', 'credentials' => {} })
|
||||
|
||||
expect(mock_client).to receive(:detect_intent).with(
|
||||
session: 'projects/test-project/agent/sessions/test-session',
|
||||
query_input: { text: { text: 'Hello', language_code: 'en-US' } }
|
||||
)
|
||||
|
||||
processor.send(:detect_intent, 'test-session', 'Hello')
|
||||
end
|
||||
|
||||
it 'uses regional session path when region is specified' do
|
||||
hook.update(settings: { 'project_id' => 'test-project', 'credentials' => {}, 'region' => 'europe-west1' })
|
||||
|
||||
expect(mock_client).to receive(:detect_intent).with(
|
||||
session: 'projects/test-project/locations/europe-west1/agent/sessions/test-session',
|
||||
query_input: { text: { text: 'Hello', language_code: 'en-US' } }
|
||||
)
|
||||
|
||||
processor.send(:detect_intent, 'test-session', 'Hello')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user