diff --git a/.env.example b/.env.example
index befcde463..81228f00a 100644
--- a/.env.example
+++ b/.env.example
@@ -257,3 +257,5 @@ AZURE_APP_SECRET=
# Set to true if you want to remove stale contact inboxes
# contact_inboxes with no conversation older than 90 days will be removed
# REMOVE_STALE_CONTACT_INBOX_JOB_STATUS=false
+
+# CAPTAIN_API_URL=http://localhost:3001/api
diff --git a/app/controllers/api/v1/accounts/integrations/apps_controller.rb b/app/controllers/api/v1/accounts/integrations/apps_controller.rb
index 358a15d87..c2284bc2e 100644
--- a/app/controllers/api/v1/accounts/integrations/apps_controller.rb
+++ b/app/controllers/api/v1/accounts/integrations/apps_controller.rb
@@ -10,7 +10,7 @@ class Api::V1::Accounts::Integrations::AppsController < Api::V1::Accounts::BaseC
private
def fetch_apps
- @apps = Integrations::App.all.select(&:active?)
+ @apps = Integrations::App.all.select { |app| app.active?(Current.account) }
end
def fetch_app
diff --git a/app/javascript/dashboard/assets/scss/widgets/_woot-tables.scss b/app/javascript/dashboard/assets/scss/widgets/_woot-tables.scss
index 97535bf0d..b5182bf87 100644
--- a/app/javascript/dashboard/assets/scss/widgets/_woot-tables.scss
+++ b/app/javascript/dashboard/assets/scss/widgets/_woot-tables.scss
@@ -1,6 +1,10 @@
table {
@apply border-spacing-0 text-sm w-full;
+
+}
+
+.woot-table {
thead {
th {
@apply font-semibold tracking-[1px] text-left px-2.5 uppercase text-slate-900 dark:text-slate-200;
@@ -16,9 +20,7 @@ table {
@apply p-2.5 text-slate-700 dark:text-slate-100;
}
}
-}
-.woot-table {
tr {
.show-if-hover {
transition: opacity 0.2s $swift-ease-out-function;
diff --git a/app/javascript/dashboard/components/widgets/BackButton.vue b/app/javascript/dashboard/components/widgets/BackButton.vue
index 2528aada7..111e838cb 100644
--- a/app/javascript/dashboard/components/widgets/BackButton.vue
+++ b/app/javascript/dashboard/components/widgets/BackButton.vue
@@ -1,34 +1,40 @@
+
+
-
diff --git a/app/javascript/dashboard/helper/featureHelper.js b/app/javascript/dashboard/helper/featureHelper.js
index edbbf4472..fb514f806 100644
--- a/app/javascript/dashboard/helper/featureHelper.js
+++ b/app/javascript/dashboard/helper/featureHelper.js
@@ -1,4 +1,20 @@
+const FEATURE_HELP_URLS = {
+ channel_email: 'https://chwt.app/hc/email',
+ channel_facebook: 'https://chwt.app/hc/fb',
+ help_center: 'https://chwt.app/hc/help-center',
+ agent_bots: 'https://chwt.app/hc/agent-bots',
+ team_management: 'https://chwt.app/hc/teams',
+ labels: 'https://chwt.app/hc/labels',
+ custom_attributes: 'https://chwt.app/hc/custom-attributes',
+ canned_responses: 'https://chwt.app/hc/canned',
+ integrations: 'https://chwt.app/hc/integrations',
+ campaigns: 'https://chwt.app/hc/campaigns',
+ reports: 'https://chwt.app/hc/reports',
+ message_reply_to: 'https://chwt.app/hc/reply-to',
+ sla: 'https://chwt.app/hc/sla',
+ dashboard_apps: 'https://chwt.app/hc/dashboard-apps',
+};
+
export function getHelpUrlForFeature(featureName) {
- const { helpUrls } = window.chatwootConfig;
- return helpUrls[featureName];
+ return FEATURE_HELP_URLS[featureName];
}
diff --git a/app/javascript/dashboard/i18n/locale/en/integrations.json b/app/javascript/dashboard/i18n/locale/en/integrations.json
index 3ad79379f..80742f881 100644
--- a/app/javascript/dashboard/i18n/locale/en/integrations.json
+++ b/app/javascript/dashboard/i18n/locale/en/integrations.json
@@ -172,6 +172,7 @@
"HEADER_BTN_TXT": "Add a new dashboard app",
"SIDEBAR_TXT": "
Dashboard Apps
Dashboard Apps allow organizations to embed an application inside the Chatwoot dashboard to provide the context for customer support agents. This feature allows you to create an application independently and embed that inside the dashboard to provide user information, their orders, or their previous payment history.
When you embed your application using the dashboard in Chatwoot, your application will get the context of the conversation and contact as a window event. Implement a listener for the message event on your page to receive the context.
To add a new dashboard app, click on the button 'Add a new dashboard app'.
",
"DESCRIPTION": "Dashboard Apps allow organizations to embed an application inside the dashboard to provide the context for customer support agents. This feature allows you to create an application independently and embed that to provide user information, their orders, or their previous payment history.",
+ "LEARN_MORE": "Learn more about Dashboard Apps",
"LIST": {
"404": "There are no dashboard apps configured on this account yet",
"LOADING": "Fetching dashboard apps...",
diff --git a/app/javascript/dashboard/routes/dashboard/settings/SettingsHeader.vue b/app/javascript/dashboard/routes/dashboard/settings/SettingsHeader.vue
index 2cb27b463..b378d8d11 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/SettingsHeader.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/SettingsHeader.vue
@@ -10,6 +10,7 @@
v-if="showBackButton"
:button-label="backButtonLabel"
:back-url="backUrl"
+ class="ml-2 mr-4"
/>
diff --git a/app/javascript/dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue b/app/javascript/dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue
index c3933689d..5a2110a8e 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/components/BaseSettingsHeader.vue
@@ -1,6 +1,7 @@
-
+
+
{
{{ description }}
@@ -74,7 +84,7 @@ const openInNewTab = url => {
:href="helpURL"
target="_blank"
rel="noopener noreferrer"
- class="sm:inline-flex hidden tracking-[-0.6%] gap-1 w-fit items-center text-woot-500 dark:text-woot-500 text-sm font-medium tracking=[-0.6%] hover:underline"
+ class="sm:inline-flex hidden gap-1 w-fit items-center text-woot-500 dark:text-woot-500 text-sm font-medium hover:underline"
>
{{ linkText }}
{
-
+
{{ linkText }}
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/DashboardAppsRow.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/DashboardAppsRow.vue
index 35a990724..e7770cffe 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/DashboardAppsRow.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/DashboardAppsRow.vue
@@ -1,12 +1,26 @@
+
+
-
- |
+ |
+ |
{{ app.title }}
|
-
+ |
{{ app.content[0].url }}
|
-
+ |
-.dashboard-app-label-url {
- @apply relative w-full;
- &:before {
- @apply invisible content-[' '];
- }
- span {
- @apply absolute left-0 right-0;
- }
-}
-
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/Index.vue
index b21f745d2..ffa47bf0b 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/Index.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/DashboardApps/Index.vue
@@ -1,95 +1,14 @@
-
-
-
- {{ $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.HEADER_BTN_TXT') }}
-
-
-
-
- {{ $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.LIST.404') }}
-
-
-
-
- |
- {{ thHeader }}
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {{ $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.HEADER_BTN_TXT') }}
+
+
+
+
+
+ {{ $t('INTEGRATION_SETTINGS.DASHBOARD_APPS.LIST.404') }}
+
+
+
+
+ |
+ {{ thHeader }}
+ |
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/integrations/Index.vue
index 0a88a3dbf..3d2d0079f 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/integrations/Index.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/Index.vue
@@ -33,7 +33,7 @@ onMounted(() => {
/>
-
+
hook.settings['account_email'],
+ 'X-USER-TOKEN' => hook.settings['access_token'],
+ 'Content-Type' => 'application/json'
+ }
+
+ body = {
+ message: message_content,
+ previous_messages: previous_messages
+ }
+
+ response = HTTParty.post(url, headers: headers, body: body.to_json)
+ response.parsed_response['message']
+ end
+
+ def previous_messages
+ previous_messages = []
+ conversation.messages.where(message_type: [:outgoing, :incoming]).where(private: false).offset(1).find_each do |message|
+ next if message.content_type != 'text'
+
+ role = determine_role(message)
+ previous_messages << { message: message.content, type: role }
+ end
+ previous_messages
+ end
+
+ def determine_role(message)
+ message.message_type == 'incoming' ? 'User' : 'Bot'
+ end
+end
diff --git a/lib/integrations/dialogflow/processor_service.rb b/lib/integrations/dialogflow/processor_service.rb
index 103ef05c5..f3962a66c 100644
--- a/lib/integrations/dialogflow/processor_service.rb
+++ b/lib/integrations/dialogflow/processor_service.rb
@@ -14,13 +14,13 @@ class Integrations::Dialogflow::ProcessorService < Integrations::BotProcessorSer
message.content
end
- def get_response(session_id, message)
+ def get_response(session_id, message_content)
if hook.settings['credentials'].blank?
Rails.logger.warn "Account: #{hook.try(:account_id)} Hook: #{hook.id} credentials are not present." && return
end
configure_dialogflow_client_defaults
- detect_intent(session_id, message)
+ detect_intent(session_id, message_content)
rescue Google::Cloud::PermissionDeniedError => e
Rails.logger.warn "DialogFlow Error: (account-#{hook.try(:account_id)}, hook-#{hook.id}) #{e.message}"
hook.prompt_reauthorization!
diff --git a/public/dashboard/images/integrations/captain-dark.png b/public/dashboard/images/integrations/captain-dark.png
new file mode 100644
index 000000000..edf8029d9
Binary files /dev/null and b/public/dashboard/images/integrations/captain-dark.png differ
diff --git a/public/dashboard/images/integrations/captain.png b/public/dashboard/images/integrations/captain.png
new file mode 100644
index 000000000..3141160f4
Binary files /dev/null and b/public/dashboard/images/integrations/captain.png differ
diff --git a/spec/controllers/api/v1/accounts/integrations/apps_controller_spec.rb b/spec/controllers/api/v1/accounts/integrations/apps_controller_spec.rb
index 43735046e..8662a5006 100644
--- a/spec/controllers/api/v1/accounts/integrations/apps_controller_spec.rb
+++ b/spec/controllers/api/v1/accounts/integrations/apps_controller_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Integration Apps API', type: :request do
let(:admin) { create(:user, account: account, role: :administrator) }
it 'returns all active apps without sensitive information if the user is an agent' do
- first_app = Integrations::App.all.find(&:active?)
+ first_app = Integrations::App.all.find { |app| app.active?(account) }
get api_v1_account_integrations_apps_url(account),
headers: agent.create_new_auth_token,
as: :json
@@ -41,7 +41,7 @@ RSpec.describe 'Integration Apps API', type: :request do
end
it 'returns all active apps with sensitive information if user is an admin' do
- first_app = Integrations::App.all.find(&:active?)
+ first_app = Integrations::App.all.find { |app| app.active?(account) }
get api_v1_account_integrations_apps_url(account),
headers: admin.create_new_auth_token,
as: :json
diff --git a/spec/models/integrations/app_spec.rb b/spec/models/integrations/app_spec.rb
index 703069349..b9652ff89 100644
--- a/spec/models/integrations/app_spec.rb
+++ b/spec/models/integrations/app_spec.rb
@@ -5,10 +5,6 @@ RSpec.describe Integrations::App do
let(:app) { apps.find(id: app_name) }
let(:account) { create(:account) }
- before do
- allow(Current).to receive(:account).and_return(account)
- end
-
describe '#name' do
let(:app_name) { 'slack' }
@@ -28,6 +24,10 @@ RSpec.describe Integrations::App do
describe '#action' do
let(:app_name) { 'slack' }
+ before do
+ allow(Current).to receive(:account).and_return(account)
+ end
+
context 'when the app is slack' do
it 'returns the action URL with client_id and redirect_uri' do
with_modified_env SLACK_CLIENT_ID: 'dummy_client_id' do
@@ -46,7 +46,7 @@ RSpec.describe Integrations::App do
context 'when the app is slack' do
it 'returns true if SLACK_CLIENT_SECRET is present' do
with_modified_env SLACK_CLIENT_SECRET: 'random_secret' do
- expect(app.active?).to be true
+ expect(app.active?(account)).to be true
end
end
end
@@ -55,14 +55,14 @@ RSpec.describe Integrations::App do
let(:app_name) { 'linear' }
it 'returns true if the linear integration feature is disabled' do
- expect(app.active?).to be false
+ expect(app.active?(account)).to be false
end
it 'returns false if the linear integration feature is enabled' do
account.enable_features('linear_integration')
account.save!
- expect(app.active?).to be true
+ expect(app.active?(account)).to be true
end
end
@@ -70,7 +70,7 @@ RSpec.describe Integrations::App do
let(:app_name) { 'webhook' }
it 'returns true' do
- expect(app.active?).to be true
+ expect(app.active?(account)).to be true
end
end
end
|