feat(ee): Add Captain features (#10665)
Migration Guide: https://chwt.app/v4/migration This PR imports all the work related to Captain into the EE codebase. Captain represents the AI-based features in Chatwoot and includes the following key components: - Assistant: An assistant has a persona, the product it would be trained on. At the moment, the data at which it is trained is from websites. Future integrations on Notion documents, PDF etc. This PR enables connecting an assistant to an inbox. The assistant would run the conversation every time before transferring it to an agent. - Copilot for Agents: When an agent is supporting a customer, we will be able to offer additional help to lookup some data or fetch information from integrations etc via copilot. - Conversation FAQ generator: When a conversation is resolved, the Captain integration would identify questions which were not in the knowledge base. - CRM memory: Learns from the conversations and identifies important information about the contact. --------- Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com> Co-authored-by: Sojan <sojan@pepalo.com> Co-authored-by: iamsivin <iamsivin@gmail.com> Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This commit is contained in:
@@ -40,6 +40,7 @@ module Chatwoot
|
||||
|
||||
config.eager_load_paths << Rails.root.join('lib')
|
||||
config.eager_load_paths << Rails.root.join('enterprise/lib')
|
||||
config.eager_load_paths << Rails.root.join('enterprise/listeners')
|
||||
# rubocop:disable Rails/FilePath
|
||||
config.eager_load_paths += Dir["#{Rails.root}/enterprise/app/**"]
|
||||
# rubocop:enable Rails/FilePath
|
||||
|
||||
@@ -17,7 +17,7 @@ module ActiveRecord
|
||||
extensions = @connection.extensions
|
||||
return unless extensions.any?
|
||||
|
||||
stream.puts ' # These are extensions that must be enabled in order to support this database'
|
||||
stream.puts ' # These extensions should be enabled to support this database'
|
||||
extensions.sort.each do |extension|
|
||||
stream.puts " enable_extension #{extension.inspect}" unless ignore_extentions.include?(extension)
|
||||
end
|
||||
@@ -27,11 +27,3 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
## Extentions / Tables to be ignored
|
||||
ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaDumper.ignore_extentions << 'vector'
|
||||
ActiveRecord::SchemaDumper.ignore_tables << 'responses'
|
||||
ActiveRecord::SchemaDumper.ignore_tables << 'response_sources'
|
||||
ActiveRecord::SchemaDumper.ignore_tables << 'response_documents'
|
||||
ActiveRecord::SchemaDumper.ignore_tables << 'inbox_response_sources'
|
||||
ActiveRecord::SchemaDumper.ignore_tables << 'article_embeddings'
|
||||
|
||||
@@ -7,11 +7,14 @@ Sidekiq.configure_client do |config|
|
||||
end
|
||||
|
||||
Sidekiq.configure_server do |config|
|
||||
config.logger.formatter = Sidekiq::Logger::Formatters::JSON.new
|
||||
config.redis = Redis::Config.app
|
||||
|
||||
# skip the default start stop logging
|
||||
config[:skip_default_job_logging] = true
|
||||
config.logger.level = Logger.const_get(ENV.fetch('LOG_LEVEL', 'info').upcase.to_s)
|
||||
if Rails.env.production?
|
||||
config.logger.formatter = Sidekiq::Logger::Formatters::JSON.new
|
||||
config[:skip_default_job_logging] = true
|
||||
config.logger.level = Logger.const_get(ENV.fetch('LOG_LEVEL', 'info').upcase.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
# https://github.com/ondrejbartas/sidekiq-cron
|
||||
|
||||
@@ -133,6 +133,13 @@
|
||||
locked: false
|
||||
# End of Microsoft Email Channel Config
|
||||
|
||||
# MARK: Captain Config
|
||||
- name: CAPTAIN_OPEN_AI_API_KEY
|
||||
display_title: 'OpenAI API Key'
|
||||
description: 'The OpenAI API key for the Captain AI service'
|
||||
locked: false
|
||||
# End of Captain Config
|
||||
|
||||
# ------- Chatwoot Internal Config for Cloud ----#
|
||||
- name: CHATWOOT_INBOX_TOKEN
|
||||
value:
|
||||
@@ -222,14 +229,3 @@
|
||||
locked: false
|
||||
description: 'Contents on your firebase credentials json file'
|
||||
## ------ End of Configs added for FCM v1 notifications ------ ##
|
||||
|
||||
## ----- Captain Configs ----- ##
|
||||
- name: CAPTAIN_API_URL
|
||||
value:
|
||||
display_title: 'Captain API URL'
|
||||
description: 'The API URL for Captain'
|
||||
- name: CAPTAIN_APP_URL
|
||||
value:
|
||||
display_title: 'Captain App URL'
|
||||
description: 'The App URL for Captain'
|
||||
## ----- End of Captain Configs ----- ##
|
||||
|
||||
@@ -8,34 +8,6 @@
|
||||
# settings_json_schema: the json schema used to validate the settings hash (https://json-schema.org/)
|
||||
# settings_form_schema: the formulate schema used in frontend to render settings form (https://vueformulate.com/)
|
||||
########################################################
|
||||
captain:
|
||||
id: captain
|
||||
logo: captain.png
|
||||
i18n_key: captain
|
||||
action: /captain
|
||||
hook_type: account
|
||||
allow_multiple_hooks: false
|
||||
settings_json_schema: {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access_token": { "type": "string" },
|
||||
"account_id": { "type": "string" },
|
||||
"account_email": { "type": "string" },
|
||||
"assistant_id": { "type": "string" },
|
||||
"inbox_ids": { "type": "strings" },
|
||||
},
|
||||
"required": ["access_token", "account_id", "account_email", "assistant_id"],
|
||||
"additionalProperties": false,
|
||||
}
|
||||
settings_form_schema: [
|
||||
{
|
||||
"label": "Inbox Ids",
|
||||
"type": "text",
|
||||
"name": "inbox_ids",
|
||||
"validation": "",
|
||||
},
|
||||
]
|
||||
visible_properties: []
|
||||
webhooks:
|
||||
id: webhook
|
||||
logo: webhooks.png
|
||||
@@ -56,29 +28,32 @@ openai:
|
||||
action: /openai
|
||||
hook_type: account
|
||||
allow_multiple_hooks: false
|
||||
settings_json_schema: {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_key": { "type": "string" },
|
||||
"label_suggestion": { "type": "boolean" },
|
||||
settings_json_schema:
|
||||
{
|
||||
'type': 'object',
|
||||
'properties':
|
||||
{
|
||||
'api_key': { 'type': 'string' },
|
||||
'label_suggestion': { 'type': 'boolean' },
|
||||
},
|
||||
'required': ['api_key'],
|
||||
'additionalProperties': false,
|
||||
}
|
||||
settings_form_schema:
|
||||
[
|
||||
{
|
||||
'label': 'API Key',
|
||||
'type': 'text',
|
||||
'name': 'api_key',
|
||||
'validation': 'required',
|
||||
},
|
||||
"required": ["api_key"],
|
||||
"additionalProperties": false,
|
||||
}
|
||||
settings_form_schema: [
|
||||
{
|
||||
"label": "API Key",
|
||||
"type": "text",
|
||||
"name": "api_key",
|
||||
"validation": "required",
|
||||
},
|
||||
{
|
||||
"label": "Show label suggestions",
|
||||
"type": "checkbox",
|
||||
"name": "label_suggestion",
|
||||
"validation": "",
|
||||
},
|
||||
]
|
||||
{
|
||||
'label': 'Show label suggestions',
|
||||
'type': 'checkbox',
|
||||
'name': 'label_suggestion',
|
||||
'validation': '',
|
||||
},
|
||||
]
|
||||
visible_properties: ['api_key', 'label_suggestion']
|
||||
linear:
|
||||
id: linear
|
||||
@@ -87,22 +62,22 @@ linear:
|
||||
action: /linear
|
||||
hook_type: account
|
||||
allow_multiple_hooks: false
|
||||
settings_json_schema: {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_key": { "type": "string" },
|
||||
},
|
||||
"required": ["api_key"],
|
||||
"additionalProperties": false,
|
||||
}
|
||||
settings_form_schema: [
|
||||
settings_json_schema:
|
||||
{
|
||||
"label": "API Key",
|
||||
"type": "text",
|
||||
"name": "api_key",
|
||||
"validation": "required",
|
||||
},
|
||||
]
|
||||
'type': 'object',
|
||||
'properties': { 'api_key': { 'type': 'string' } },
|
||||
'required': ['api_key'],
|
||||
'additionalProperties': false,
|
||||
}
|
||||
settings_form_schema:
|
||||
[
|
||||
{
|
||||
'label': 'API Key',
|
||||
'type': 'text',
|
||||
'name': 'api_key',
|
||||
'validation': 'required',
|
||||
},
|
||||
]
|
||||
visible_properties: []
|
||||
slack:
|
||||
id: slack
|
||||
@@ -118,35 +93,36 @@ dialogflow:
|
||||
action: /dialogflow
|
||||
hook_type: inbox
|
||||
allow_multiple_hooks: true
|
||||
settings_json_schema: {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_id": { "type": "string" },
|
||||
"credentials": { "type": "object" }
|
||||
},
|
||||
"required": ["project_id", "credentials"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
settings_form_schema: [
|
||||
settings_json_schema:
|
||||
{
|
||||
"label": "Dialogflow Project ID",
|
||||
"type": "text",
|
||||
"name": "project_id",
|
||||
"validation": "required",
|
||||
"validationName": 'Project Id',
|
||||
},
|
||||
{
|
||||
"label": "Dialogflow Project Key File",
|
||||
"type": "textarea",
|
||||
"name": "credentials",
|
||||
"validation": "required|JSON",
|
||||
"validationName": 'Credentials',
|
||||
"validation-messages": {
|
||||
"JSON": "Invalid JSON",
|
||||
"required": "Credentials is required"
|
||||
}
|
||||
'type': 'object',
|
||||
'properties':
|
||||
{
|
||||
'project_id': { 'type': 'string' },
|
||||
'credentials': { 'type': 'object' },
|
||||
},
|
||||
'required': ['project_id', 'credentials'],
|
||||
'additionalProperties': false,
|
||||
}
|
||||
]
|
||||
settings_form_schema:
|
||||
[
|
||||
{
|
||||
'label': 'Dialogflow Project ID',
|
||||
'type': 'text',
|
||||
'name': 'project_id',
|
||||
'validation': 'required',
|
||||
'validationName': 'Project Id',
|
||||
},
|
||||
{
|
||||
'label': 'Dialogflow Project Key File',
|
||||
'type': 'textarea',
|
||||
'name': 'credentials',
|
||||
'validation': 'required|JSON',
|
||||
'validationName': 'Credentials',
|
||||
'validation-messages':
|
||||
{ 'JSON': 'Invalid JSON', 'required': 'Credentials is required' },
|
||||
},
|
||||
]
|
||||
visible_properties: ['project_id']
|
||||
google_translate:
|
||||
id: google_translate
|
||||
@@ -155,35 +131,36 @@ google_translate:
|
||||
action: /google_translate
|
||||
hook_type: account
|
||||
allow_multiple_hooks: false
|
||||
settings_json_schema: {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_id": { "type": "string" },
|
||||
"credentials": { "type": "object" },
|
||||
},
|
||||
"required": ["project_id", "credentials"],
|
||||
"additionalProperties": false,
|
||||
}
|
||||
settings_form_schema: [
|
||||
settings_json_schema:
|
||||
{
|
||||
"label": "Google Cloud Project ID",
|
||||
"type": "text",
|
||||
"name": "project_id",
|
||||
"validation": "required",
|
||||
"validationName": "Project Id",
|
||||
},
|
||||
{
|
||||
"label": "Google Cloud Project Key File",
|
||||
"type": "textarea",
|
||||
"name": "credentials",
|
||||
"validation": "required|JSON",
|
||||
"validationName": "Credentials",
|
||||
"validation-messages": {
|
||||
"JSON": "Invalid JSON",
|
||||
"required": "Credentials is required"
|
||||
'type': 'object',
|
||||
'properties':
|
||||
{
|
||||
'project_id': { 'type': 'string' },
|
||||
'credentials': { 'type': 'object' },
|
||||
},
|
||||
'required': ['project_id', 'credentials'],
|
||||
'additionalProperties': false,
|
||||
}
|
||||
settings_form_schema:
|
||||
[
|
||||
{
|
||||
'label': 'Google Cloud Project ID',
|
||||
'type': 'text',
|
||||
'name': 'project_id',
|
||||
'validation': 'required',
|
||||
'validationName': 'Project Id',
|
||||
},
|
||||
},
|
||||
]
|
||||
{
|
||||
'label': 'Google Cloud Project Key File',
|
||||
'type': 'textarea',
|
||||
'name': 'credentials',
|
||||
'validation': 'required|JSON',
|
||||
'validationName': 'Credentials',
|
||||
'validation-messages':
|
||||
{ 'JSON': 'Invalid JSON', 'required': 'Credentials is required' },
|
||||
},
|
||||
]
|
||||
visible_properties: ['project_id']
|
||||
dyte:
|
||||
id: dyte
|
||||
@@ -192,27 +169,30 @@ dyte:
|
||||
action: /dyte
|
||||
hook_type: account
|
||||
allow_multiple_hooks: false
|
||||
settings_json_schema: {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_key": { "type": "string" },
|
||||
"organization_id": { "type": "string" },
|
||||
settings_json_schema:
|
||||
{
|
||||
'type': 'object',
|
||||
'properties':
|
||||
{
|
||||
'api_key': { 'type': 'string' },
|
||||
'organization_id': { 'type': 'string' },
|
||||
},
|
||||
'required': ['api_key', 'organization_id'],
|
||||
'additionalProperties': false,
|
||||
}
|
||||
settings_form_schema:
|
||||
[
|
||||
{
|
||||
'label': 'Organization ID',
|
||||
'type': 'text',
|
||||
'name': 'organization_id',
|
||||
'validation': 'required',
|
||||
},
|
||||
"required": ["api_key", "organization_id"],
|
||||
"additionalProperties": false,
|
||||
}
|
||||
settings_form_schema: [
|
||||
{
|
||||
"label": "Organization ID",
|
||||
"type": "text",
|
||||
"name": "organization_id",
|
||||
"validation": "required",
|
||||
},
|
||||
{
|
||||
"label": "API Key",
|
||||
"type": "text",
|
||||
"name": "api_key",
|
||||
"validation": "required",
|
||||
},
|
||||
]
|
||||
visible_properties: ["organization_id"]
|
||||
{
|
||||
'label': 'API Key',
|
||||
'type': 'text',
|
||||
'name': 'api_key',
|
||||
'validation': 'required',
|
||||
},
|
||||
]
|
||||
visible_properties: ['organization_id']
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
# available at https://guides.rubyonrails.org/i18n.html.
|
||||
|
||||
en:
|
||||
hello: "Hello world"
|
||||
hello: 'Hello world'
|
||||
messages:
|
||||
reset_password_success: Woot! Request for password reset is successful. Check your mail for instructions.
|
||||
reset_password_failure: Uh ho! We could not find any user with the specified email.
|
||||
@@ -45,7 +45,7 @@ en:
|
||||
disposable_email: We do not allow disposable emails
|
||||
blocked_domain: This domain is not allowed. If you believe this is a mistake, please contact support.
|
||||
invalid_email: You have entered an invalid email
|
||||
email_already_exists: "You have already signed up for an account with %{email}"
|
||||
email_already_exists: 'You have already signed up for an account with %{email}'
|
||||
invalid_params: 'Invalid, please check the signup paramters and try again'
|
||||
failed: Signup failed
|
||||
data_import:
|
||||
@@ -64,9 +64,9 @@ en:
|
||||
locale:
|
||||
unique: should be unique in the category and portal
|
||||
dyte:
|
||||
invalid_message_type: "Invalid message type. Action not permitted"
|
||||
invalid_message_type: 'Invalid message type. Action not permitted'
|
||||
slack:
|
||||
invalid_channel_id: "Invalid slack channel. Please try again"
|
||||
invalid_channel_id: 'Invalid slack channel. Please try again'
|
||||
inboxes:
|
||||
imap:
|
||||
socket_error: Please check the network connection, IMAP address and try again.
|
||||
@@ -135,103 +135,102 @@ en:
|
||||
|
||||
notifications:
|
||||
notification_title:
|
||||
conversation_creation: "A conversation (#%{display_id}) has been created in %{inbox_name}"
|
||||
conversation_assignment: "A conversation (#%{display_id}) has been assigned to you"
|
||||
assigned_conversation_new_message: "A new message is created in conversation (#%{display_id})"
|
||||
conversation_mention: "You have been mentioned in conversation (#%{display_id})"
|
||||
sla_missed_first_response: "SLA target first response missed for conversation (#%{display_id})"
|
||||
sla_missed_next_response: "SLA target next response missed for conversation (#%{display_id})"
|
||||
sla_missed_resolution: "SLA target resolution missed for conversation (#%{display_id})"
|
||||
attachment: "Attachment"
|
||||
no_content: "No content"
|
||||
conversation_creation: 'A conversation (#%{display_id}) has been created in %{inbox_name}'
|
||||
conversation_assignment: 'A conversation (#%{display_id}) has been assigned to you'
|
||||
assigned_conversation_new_message: 'A new message is created in conversation (#%{display_id})'
|
||||
conversation_mention: 'You have been mentioned in conversation (#%{display_id})'
|
||||
sla_missed_first_response: 'SLA target first response missed for conversation (#%{display_id})'
|
||||
sla_missed_next_response: 'SLA target next response missed for conversation (#%{display_id})'
|
||||
sla_missed_resolution: 'SLA target resolution missed for conversation (#%{display_id})'
|
||||
attachment: 'Attachment'
|
||||
no_content: 'No content'
|
||||
conversations:
|
||||
messages:
|
||||
instagram_story_content: "%{story_sender} mentioned you in the story: "
|
||||
instagram_story_content: '%{story_sender} mentioned you in the story: '
|
||||
instagram_deleted_story_content: This story is no longer available.
|
||||
deleted: This message was deleted
|
||||
delivery_status:
|
||||
error_code: "Error code: %{error_code}"
|
||||
error_code: 'Error code: %{error_code}'
|
||||
activity:
|
||||
status:
|
||||
resolved: "Conversation was marked resolved by %{user_name}"
|
||||
contact_resolved: "Conversation was resolved by %{contact_name}"
|
||||
open: "Conversation was reopened by %{user_name}"
|
||||
pending: "Conversation was marked as pending by %{user_name}"
|
||||
snoozed: "Conversation was snoozed by %{user_name}"
|
||||
auto_resolved: "Conversation was marked resolved by system due to %{duration} days of inactivity"
|
||||
resolved: 'Conversation was marked resolved by %{user_name}'
|
||||
contact_resolved: 'Conversation was resolved by %{contact_name}'
|
||||
open: 'Conversation was reopened by %{user_name}'
|
||||
pending: 'Conversation was marked as pending by %{user_name}'
|
||||
snoozed: 'Conversation was snoozed by %{user_name}'
|
||||
auto_resolved: 'Conversation was marked resolved by system due to %{duration} days of inactivity'
|
||||
system_auto_open: System reopened the conversation due to a new incoming message.
|
||||
priority:
|
||||
added: '%{user_name} set the priority to %{new_priority}'
|
||||
updated: '%{user_name} changed the priority from %{old_priority} to %{new_priority}'
|
||||
removed: '%{user_name} removed the priority'
|
||||
assignee:
|
||||
self_assigned: "%{user_name} self-assigned this conversation"
|
||||
assigned: "Assigned to %{assignee_name} by %{user_name}"
|
||||
removed: "Conversation unassigned by %{user_name}"
|
||||
self_assigned: '%{user_name} self-assigned this conversation'
|
||||
assigned: 'Assigned to %{assignee_name} by %{user_name}'
|
||||
removed: 'Conversation unassigned by %{user_name}'
|
||||
team:
|
||||
assigned: "Assigned to %{team_name} by %{user_name}"
|
||||
assigned_with_assignee: "Assigned to %{assignee_name} via %{team_name} by %{user_name}"
|
||||
removed: "Unassigned from %{team_name} by %{user_name}"
|
||||
assigned: 'Assigned to %{team_name} by %{user_name}'
|
||||
assigned_with_assignee: 'Assigned to %{assignee_name} via %{team_name} by %{user_name}'
|
||||
removed: 'Unassigned from %{team_name} by %{user_name}'
|
||||
labels:
|
||||
added: "%{user_name} added %{labels}"
|
||||
removed: "%{user_name} removed %{labels}"
|
||||
added: '%{user_name} added %{labels}'
|
||||
removed: '%{user_name} removed %{labels}'
|
||||
sla:
|
||||
added: "%{user_name} added SLA policy %{sla_name}"
|
||||
removed: "%{user_name} removed SLA policy %{sla_name}"
|
||||
muted: "%{user_name} has muted the conversation"
|
||||
unmuted: "%{user_name} has unmuted the conversation"
|
||||
added: '%{user_name} added SLA policy %{sla_name}'
|
||||
removed: '%{user_name} removed SLA policy %{sla_name}'
|
||||
muted: '%{user_name} has muted the conversation'
|
||||
unmuted: '%{user_name} has unmuted the conversation'
|
||||
templates:
|
||||
greeting_message_body: "%{account_name} typically replies in a few hours."
|
||||
ways_to_reach_you_message_body: "Give the team a way to reach you."
|
||||
email_input_box_message_body: "Get notified by email"
|
||||
csat_input_message_body: "Please rate the conversation"
|
||||
greeting_message_body: '%{account_name} typically replies in a few hours.'
|
||||
ways_to_reach_you_message_body: 'Give the team a way to reach you.'
|
||||
email_input_box_message_body: 'Get notified by email'
|
||||
csat_input_message_body: 'Please rate the conversation'
|
||||
reply:
|
||||
email:
|
||||
header:
|
||||
from_with_name: "%{assignee_name} from %{inbox_name} <%{from_email}>"
|
||||
reply_with_name: "%{assignee_name} from %{inbox_name} <reply+%{reply_email}>"
|
||||
friendly_name: "%{sender_name} from %{business_name} <%{from_email}>"
|
||||
professional_name: "%{business_name} <%{from_email}>"
|
||||
from_with_name: '%{assignee_name} from %{inbox_name} <%{from_email}>'
|
||||
reply_with_name: '%{assignee_name} from %{inbox_name} <reply+%{reply_email}>'
|
||||
friendly_name: '%{sender_name} from %{business_name} <%{from_email}>'
|
||||
professional_name: '%{business_name} <%{from_email}>'
|
||||
channel_email:
|
||||
header:
|
||||
reply_with_name: "%{assignee_name} from %{inbox_name} <%{from_email}>"
|
||||
reply_with_inbox_name: "%{inbox_name} <%{from_email}>"
|
||||
email_subject: "New messages on this conversation"
|
||||
transcript_subject: "Conversation Transcript"
|
||||
reply_with_name: '%{assignee_name} from %{inbox_name} <%{from_email}>'
|
||||
reply_with_inbox_name: '%{inbox_name} <%{from_email}>'
|
||||
email_subject: 'New messages on this conversation'
|
||||
transcript_subject: 'Conversation Transcript'
|
||||
survey:
|
||||
response: "Please rate this conversation, %{link}"
|
||||
response: 'Please rate this conversation, %{link}'
|
||||
contacts:
|
||||
online:
|
||||
delete: "%{contact_name} is Online, please try again later"
|
||||
delete: '%{contact_name} is Online, please try again later'
|
||||
integration_apps:
|
||||
dashboard_apps:
|
||||
name: "Dashboard Apps"
|
||||
description: "Dashboard Apps allow you to create and embed applications that display user information, orders, or payment history, providing more context to your customer support agents."
|
||||
name: 'Dashboard Apps'
|
||||
description: 'Dashboard Apps allow you to create and embed applications that display user information, orders, or payment history, providing more context to your customer support agents.'
|
||||
dyte:
|
||||
name: "Dyte"
|
||||
description: "Dyte is a product that integrates audio and video functionalities into your application. With this integration, your agents can start video/voice calls with your customers directly from Chatwoot."
|
||||
meeting_name: "%{agent_name} has started a meeting"
|
||||
name: 'Dyte'
|
||||
description: 'Dyte is a product that integrates audio and video functionalities into your application. With this integration, your agents can start video/voice calls with your customers directly from Chatwoot.'
|
||||
meeting_name: '%{agent_name} has started a meeting'
|
||||
slack:
|
||||
name: "Slack"
|
||||
name: 'Slack'
|
||||
description: "Integrate Chatwoot with Slack to keep your team in sync. This integration allows you to receive notifications for new conversations and respond to them directly within Slack's interface."
|
||||
webhooks:
|
||||
name: "Webhooks"
|
||||
description: "Webhook events provide real-time updates about activities in your Chatwoot account. You can subscribe to your preferred events, and Chatwoot will send you HTTP callbacks with the updates."
|
||||
name: 'Webhooks'
|
||||
description: 'Webhook events provide real-time updates about activities in your Chatwoot account. You can subscribe to your preferred events, and Chatwoot will send you HTTP callbacks with the updates.'
|
||||
dialogflow:
|
||||
name: "Dialogflow"
|
||||
description: "Build chatbots with Dialogflow and easily integrate them into your inbox. These bots can handle initial queries before transferring them to a customer service agent."
|
||||
name: 'Dialogflow'
|
||||
description: 'Build chatbots with Dialogflow and easily integrate them into your inbox. These bots can handle initial queries before transferring them to a customer service agent.'
|
||||
google_translate:
|
||||
name: "Google Translate"
|
||||
name: 'Google Translate'
|
||||
description: "Integrate Google Translate to help agents easily translate customer messages. This integration automatically detects the language and converts it to the agent's or admin's preferred language."
|
||||
openai:
|
||||
name: "OpenAI"
|
||||
description: "Leverage the power of large language models from OpenAI with the features such as reply suggestions, summarization, message rephrasing, spell-checking, and label classification."
|
||||
name: 'OpenAI'
|
||||
description: 'Leverage the power of large language models from OpenAI with the features such as reply suggestions, summarization, message rephrasing, spell-checking, and label classification.'
|
||||
linear:
|
||||
name: "Linear"
|
||||
description: "Create issues in Linear directly from your conversation window. Alternatively, link existing Linear issues for a more streamlined and efficient issue tracking process."
|
||||
captain:
|
||||
name: "Captain"
|
||||
description: "Captain is a native AI assistant built for your product and trained on your company's knowledge base. It responds like a human and resolves customer queries effectively. Configure it to your inboxes easily."
|
||||
name: 'Linear'
|
||||
description: 'Create issues in Linear directly from your conversation window. Alternatively, link existing Linear issues for a more streamlined and efficient issue tracking process.'
|
||||
captain:
|
||||
copilot_error: 'Please connect an assistant to this inbox to use copilot'
|
||||
public_portal:
|
||||
search:
|
||||
search_placeholder: Search for article by title or body...
|
||||
@@ -269,23 +268,23 @@ en:
|
||||
back_to_home: Go to home page
|
||||
slack_unfurl:
|
||||
fields:
|
||||
name: Name
|
||||
email: Email
|
||||
phone_number: Phone
|
||||
company_name: Company
|
||||
inbox_name: Inbox
|
||||
inbox_type: Inbox Type
|
||||
name: Name
|
||||
email: Email
|
||||
phone_number: Phone
|
||||
company_name: Company
|
||||
inbox_name: Inbox
|
||||
inbox_type: Inbox Type
|
||||
button: Open conversation
|
||||
time_units:
|
||||
days:
|
||||
one: "%{count} day"
|
||||
other: "%{count} days"
|
||||
one: '%{count} day'
|
||||
other: '%{count} days'
|
||||
hours:
|
||||
one: "%{count} hour"
|
||||
other: "%{count} hours"
|
||||
one: '%{count} hour'
|
||||
other: '%{count} hours'
|
||||
minutes:
|
||||
one: "%{count} minute"
|
||||
other: "%{count} minutes"
|
||||
one: '%{count} minute'
|
||||
other: '%{count} minutes'
|
||||
seconds:
|
||||
one: "%{count} second"
|
||||
other: "%{count} seconds"
|
||||
one: '%{count} second'
|
||||
other: '%{count} seconds'
|
||||
|
||||
@@ -48,6 +48,13 @@ Rails.application.routes.draw do
|
||||
resources :agents, only: [:index, :create, :update, :destroy] do
|
||||
post :bulk_create, on: :collection
|
||||
end
|
||||
namespace :captain do
|
||||
resources :assistants do
|
||||
resources :inboxes, only: [:index, :create, :destroy], param: :inbox_id
|
||||
end
|
||||
resources :documents, only: [:index, :show, :create, :destroy]
|
||||
resources :assistant_responses
|
||||
end
|
||||
resources :agent_bots, only: [:index, :create, :show, :update, :destroy] do
|
||||
delete :avatar, on: :member
|
||||
end
|
||||
@@ -110,6 +117,7 @@ Rails.application.routes.draw do
|
||||
post :unread
|
||||
post :custom_attributes
|
||||
get :attachments
|
||||
post :copilot
|
||||
end
|
||||
end
|
||||
|
||||
@@ -158,7 +166,6 @@ Rails.application.routes.draw do
|
||||
resources :inboxes, only: [:index, :show, :create, :update, :destroy] do
|
||||
get :assignable_agents, on: :member
|
||||
get :campaigns, on: :member
|
||||
get :response_sources, on: :member
|
||||
get :agent_bot, on: :member
|
||||
post :set_agent_bot, on: :member
|
||||
delete :avatar, on: :member
|
||||
@@ -170,15 +177,6 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
resources :labels, only: [:index, :show, :create, :update, :destroy]
|
||||
resources :response_sources, only: [:create] do
|
||||
collection do
|
||||
post :parse
|
||||
end
|
||||
member do
|
||||
post :add_document
|
||||
post :remove_document
|
||||
end
|
||||
end
|
||||
|
||||
resources :notifications, only: [:index, :update, :destroy] do
|
||||
collection do
|
||||
@@ -217,12 +215,6 @@ Rails.application.routes.draw do
|
||||
resources :webhooks, only: [:index, :create, :update, :destroy]
|
||||
namespace :integrations do
|
||||
resources :apps, only: [:index, :show]
|
||||
resource :captain, controller: 'captain', only: [] do
|
||||
collection do
|
||||
post :proxy
|
||||
post :copilot
|
||||
end
|
||||
end
|
||||
resources :hooks, only: [:show, :create, :update, :destroy] do
|
||||
member do
|
||||
post :process_event
|
||||
@@ -364,6 +356,7 @@ Rails.application.routes.draw do
|
||||
end
|
||||
|
||||
post 'webhooks/stripe', to: 'webhooks/stripe#process_payload'
|
||||
post 'webhooks/firecrawl', to: 'webhooks/firecrawl#process_payload'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -488,10 +481,6 @@ Rails.application.routes.draw do
|
||||
end
|
||||
|
||||
resources :access_tokens, only: [:index, :show]
|
||||
resources :response_sources, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
|
||||
get :chat, on: :member
|
||||
post :chat, on: :member, action: :process_chat
|
||||
end
|
||||
resources :response_documents, only: [:index, :show, :new, :create, :edit, :update, :destroy]
|
||||
resources :responses, only: [:index, :show, :new, :create, :edit, :update, :destroy]
|
||||
resources :installation_configs, only: [:index, :new, :create, :show, :edit, :update]
|
||||
|
||||
@@ -7,29 +7,28 @@ internal_check_new_versions_job:
|
||||
cron: '0 12 */1 * *'
|
||||
class: 'Internal::CheckNewVersionsJob'
|
||||
queue: scheduled_jobs
|
||||
# # executed At every 5th minute..
|
||||
# trigger_scheduled_items_job:
|
||||
# cron: '*/5 * * * *'
|
||||
# class: 'TriggerScheduledItemsJob'
|
||||
# queue: scheduled_jobs
|
||||
|
||||
# executed At every 5th minute..
|
||||
trigger_scheduled_items_job:
|
||||
cron: '*/5 * * * *'
|
||||
class: 'TriggerScheduledItemsJob'
|
||||
queue: scheduled_jobs
|
||||
# # executed At every minute..
|
||||
# trigger_imap_email_inboxes_job:
|
||||
# cron: '*/1 * * * *'
|
||||
# class: 'Inboxes::FetchImapEmailInboxesJob'
|
||||
# queue: scheduled_jobs
|
||||
|
||||
# executed At every minute..
|
||||
trigger_imap_email_inboxes_job:
|
||||
cron: '*/1 * * * *'
|
||||
class: 'Inboxes::FetchImapEmailInboxesJob'
|
||||
queue: scheduled_jobs
|
||||
# # executed daily at 2230 UTC
|
||||
# # which is our lowest traffic time
|
||||
# remove_stale_contact_inboxes_job.rb:
|
||||
# cron: '30 22 * * *'
|
||||
# class: 'Internal::RemoveStaleContactInboxesJob'
|
||||
# queue: scheduled_jobs
|
||||
|
||||
# executed daily at 2230 UTC
|
||||
# which is our lowest traffic time
|
||||
remove_stale_contact_inboxes_job.rb:
|
||||
cron: '30 22 * * *'
|
||||
class: 'Internal::RemoveStaleContactInboxesJob'
|
||||
queue: scheduled_jobs
|
||||
|
||||
# executed daily at 2230 UTC
|
||||
# which is our lowest traffic time
|
||||
remove_stale_redis_keys_job.rb:
|
||||
cron: '30 22 * * *'
|
||||
class: 'Internal::RemoveStaleRedisKeysJob'
|
||||
queue: scheduled_jobs
|
||||
# # executed daily at 2230 UTC
|
||||
# # which is our lowest traffic time
|
||||
# remove_stale_redis_keys_job.rb:
|
||||
# cron: '30 22 * * *'
|
||||
# class: 'Internal::RemoveStaleRedisKeysJob'
|
||||
# queue: scheduled_jobs
|
||||
|
||||
Reference in New Issue
Block a user