Some checks failed
Frontend Lint & Test / test (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot EE docker images / merge (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot CE docker images / merge (push) Has been cancelled
Run Chatwoot CE spec / lint-backend (push) Has been cancelled
Run Chatwoot CE spec / security-scan (push) Has been cancelled
Run Chatwoot CE spec / lint-frontend (push) Has been cancelled
Run Chatwoot CE spec / frontend-tests (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (0, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (1, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (10, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (11, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (12, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (13, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (14, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (15, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (2, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (3, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (4, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (5, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (6, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (7, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (8, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (9, 16) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Add an optional custom OpenAI-compatible base URL to the per-account OpenAI
integration (/app/accounts/{id}/settings/integrations/openai) so account owners
can point label suggestions / reply suggestions at a self-hosted or proxy
endpoint (vLLM, OpenRouter, etc.) instead of the default api.openai.com.
- config/integration/apps.yml: add 'base_url' to the openai settings schema +
form (optional custom URL input).
- lib/integrations/llm_base_service.rb: api_base resolves per-account
hook.settings['base_url'] -> CAPTAIN_OPEN_AI_ENDPOINT -> api.openai.com.
- lib/integrations/openai/key_validator.rb: valid? accepts an optional base_url
keyword; api_base uses it first (backward-compatible).
- app/models/integrations/hook.rb: fail-closed validation rejecting a present
but non-https base_url; both KeyValidator callers pass the hook base_url.
Approved by independent five-key pre-commit review deleg_1c66a89b
(passed=true, blocking arrays empty).
338 lines
10 KiB
YAML
338 lines
10 KiB
YAML
###### Attributes Supported by Integration Apps #######
|
|
# id: Internal Id for the integrations, used by the hooks
|
|
# logo: place the image in /public/dashboard/images/integrations and reference here
|
|
# i18n_key: the key under which translations for the integration is placed in en.yml
|
|
# action: if integration requires external redirect url
|
|
# hook_type: ( account / inbox )
|
|
# feature_flag: (string) feature flag to enable/disable the integration
|
|
# allow_multiple_hooks: whether multiple hooks can be created for the integration
|
|
# visible_properties: hook setting keys safe to return in API responses and show in the UI
|
|
# 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/)
|
|
########################################################
|
|
webhooks:
|
|
id: webhook
|
|
logo: webhooks.png
|
|
i18n_key: webhooks
|
|
action: /webhook
|
|
hook_type: account
|
|
allow_multiple_hooks: true
|
|
dashboard_apps:
|
|
id: dashboard_apps
|
|
logo: dashboard_apps.png
|
|
i18n_key: dashboard_apps
|
|
hook_type: account
|
|
allow_multiple_hooks: true
|
|
openai:
|
|
id: openai
|
|
logo: openai.png
|
|
i18n_key: openai
|
|
action: /openai
|
|
hook_type: account
|
|
allow_multiple_hooks: false
|
|
settings_json_schema:
|
|
{
|
|
'type': 'object',
|
|
'properties':
|
|
{
|
|
'api_key': { 'type': 'string' },
|
|
'base_url': { 'type': 'string' },
|
|
'label_suggestion': { 'type': 'boolean' },
|
|
},
|
|
'required': ['api_key'],
|
|
'additionalProperties': false,
|
|
}
|
|
settings_form_schema:
|
|
[
|
|
{
|
|
'label': 'API Key',
|
|
'type': 'text',
|
|
'name': 'api_key',
|
|
'validation': 'required',
|
|
},
|
|
{
|
|
'label': 'OpenAI Base URL (custom OpenAI-compatible server, optional)',
|
|
'type': 'text',
|
|
'name': 'base_url',
|
|
'validation': '',
|
|
},
|
|
{
|
|
'label': 'Show label suggestions',
|
|
'type': 'checkbox',
|
|
'name': 'label_suggestion',
|
|
'validation': '',
|
|
},
|
|
]
|
|
visible_properties: ['label_suggestion']
|
|
linear:
|
|
id: linear
|
|
logo: linear.png
|
|
i18n_key: linear
|
|
action: https://linear.app/oauth/authorize
|
|
hook_type: account
|
|
allow_multiple_hooks: false
|
|
visible_properties: []
|
|
notion:
|
|
id: notion
|
|
logo: notion.png
|
|
i18n_key: notion
|
|
hook_type: account
|
|
allow_multiple_hooks: false
|
|
visible_properties: []
|
|
slack:
|
|
id: slack
|
|
logo: slack.png
|
|
i18n_key: slack
|
|
action: https://slack.com/oauth/v2/authorize?scope=commands,chat:write,channels:read,channels:manage,channels:join,groups:read,groups:write,im:write,mpim:write,users:read,users:read.email,chat:write.customize,channels:history,groups:history,mpim:history,im:history,files:read,files:write
|
|
hook_type: account
|
|
allow_multiple_hooks: false
|
|
visible_properties: ['channel_name']
|
|
dialogflow:
|
|
id: dialogflow
|
|
logo: dialogflow.png
|
|
i18n_key: dialogflow
|
|
action: /dialogflow
|
|
hook_type: inbox
|
|
allow_multiple_hooks: true
|
|
settings_json_schema:
|
|
{
|
|
'type': 'object',
|
|
'properties':
|
|
{
|
|
'project_id': { 'type': 'string' },
|
|
'credentials': { 'type': 'object' },
|
|
'region': { 'type': 'string' },
|
|
'language_code': { 'type': 'string' },
|
|
},
|
|
'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' },
|
|
},
|
|
{
|
|
'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' },
|
|
],
|
|
},
|
|
{
|
|
'label': 'Language Code',
|
|
'type': 'select',
|
|
'name': 'language_code',
|
|
'default': 'en-US',
|
|
'help': 'Language code for Dialogflow agent. Use "auto" to detect from contact language.',
|
|
'options': [
|
|
{ 'label': 'Auto-detect from contact', 'value': 'auto' },
|
|
{ 'label': 'English (US)', 'value': 'en-US' },
|
|
{ 'label': 'English (UK)', 'value': 'en-GB' },
|
|
{ 'label': 'Spanish (Spain)', 'value': 'es-ES' },
|
|
{ 'label': 'Spanish (Latin America)', 'value': 'es-419' },
|
|
{ 'label': 'French', 'value': 'fr-FR' },
|
|
{ 'label': 'German', 'value': 'de-DE' },
|
|
{ 'label': 'Portuguese (Brazil)', 'value': 'pt-BR' },
|
|
{ 'label': 'Portuguese (Portugal)', 'value': 'pt-PT' },
|
|
{ 'label': 'Italian', 'value': 'it-IT' },
|
|
{ 'label': 'Japanese', 'value': 'ja-JP' },
|
|
{ 'label': 'Korean', 'value': 'ko-KR' },
|
|
{ 'label': 'Chinese (Simplified)', 'value': 'zh-CN' },
|
|
{ 'label': 'Chinese (Traditional)', 'value': 'zh-TW' },
|
|
{ 'label': 'Hindi', 'value': 'hi-IN' },
|
|
{ 'label': 'Arabic', 'value': 'ar' },
|
|
{ 'label': 'Russian', 'value': 'ru-RU' },
|
|
{ 'label': 'Dutch', 'value': 'nl-NL' },
|
|
{ 'label': 'Polish', 'value': 'pl-PL' },
|
|
{ 'label': 'Turkish', 'value': 'tr-TR' },
|
|
{ 'label': 'Thai', 'value': 'th-TH' },
|
|
{ 'label': 'Vietnamese', 'value': 'vi-VN' },
|
|
{ 'label': 'Indonesian', 'value': 'id-ID' },
|
|
],
|
|
},
|
|
]
|
|
visible_properties: ['project_id', 'region', 'language_code']
|
|
google_translate:
|
|
id: google_translate
|
|
logo: google-translate.png
|
|
i18n_key: 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:
|
|
[
|
|
{
|
|
'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
|
|
logo: dyte.png
|
|
i18n_key: dyte
|
|
action: /dyte
|
|
hook_type: account
|
|
allow_multiple_hooks: false
|
|
settings_json_schema:
|
|
{
|
|
'type': 'object',
|
|
'properties':
|
|
{
|
|
'account_id': { 'type': 'string' },
|
|
'app_id': { 'type': 'string' },
|
|
'api_token': { 'type': 'string' },
|
|
},
|
|
'required': ['account_id', 'app_id', 'api_token'],
|
|
'additionalProperties': false,
|
|
}
|
|
settings_form_schema:
|
|
[
|
|
{
|
|
'label': 'Cloudflare Account ID',
|
|
'type': 'text',
|
|
'name': 'account_id',
|
|
'validation': 'required',
|
|
},
|
|
{
|
|
'label': 'RealtimeKit App ID',
|
|
'type': 'text',
|
|
'name': 'app_id',
|
|
'validation': 'required',
|
|
},
|
|
{
|
|
'label': 'Cloudflare API Token',
|
|
'type': 'text',
|
|
'name': 'api_token',
|
|
'validation': 'required',
|
|
},
|
|
]
|
|
visible_properties: ['account_id', 'app_id']
|
|
|
|
shopify:
|
|
id: shopify
|
|
logo: shopify.png
|
|
i18n_key: shopify
|
|
hook_type: account
|
|
allow_multiple_hooks: false
|
|
visible_properties: []
|
|
|
|
leadsquared:
|
|
id: leadsquared
|
|
feature_flag: crm_integration
|
|
logo: leadsquared.png
|
|
i18n_key: leadsquared
|
|
action: /leadsquared
|
|
hook_type: account
|
|
allow_multiple_hooks: false
|
|
settings_json_schema:
|
|
{
|
|
'type': 'object',
|
|
'properties':
|
|
{
|
|
'access_key': { 'type': 'string' },
|
|
'secret_key': { 'type': 'string' },
|
|
'endpoint_url': { 'type': 'string' },
|
|
'app_url': { 'type': 'string' },
|
|
'timezone': { 'type': 'string' },
|
|
'enable_conversation_activity': { 'type': 'boolean' },
|
|
'enable_transcript_activity': { 'type': 'boolean' },
|
|
'conversation_activity_score': { 'type': 'string' },
|
|
'transcript_activity_score': { 'type': 'string' },
|
|
'conversation_activity_code': { 'type': 'integer' },
|
|
'transcript_activity_code': { 'type': 'integer' },
|
|
},
|
|
'required': ['access_key', 'secret_key'],
|
|
'additionalProperties': false,
|
|
}
|
|
settings_form_schema:
|
|
[
|
|
{
|
|
'label': 'Access Key',
|
|
'type': 'text',
|
|
'name': 'access_key',
|
|
'validation': 'required',
|
|
},
|
|
{
|
|
'label': 'Secret Key',
|
|
'type': 'text',
|
|
'name': 'secret_key',
|
|
'validation': 'required',
|
|
},
|
|
{
|
|
'label': 'Push Conversation Activity',
|
|
'type': 'checkbox',
|
|
'name': 'enable_conversation_activity',
|
|
'help': 'Enable this option to push an activity when a conversation is created',
|
|
},
|
|
{
|
|
'label': 'Conversation Activity Score',
|
|
'type': 'number',
|
|
'name': 'conversation_activity_score',
|
|
'help': 'Score to assign to the conversation created activity, default is 0',
|
|
},
|
|
{
|
|
'label': 'Push Transcript Activity',
|
|
'type': 'checkbox',
|
|
'name': 'enable_transcript_activity',
|
|
'help': 'Enable this option to push an activity when a transcript is created',
|
|
},
|
|
{
|
|
'label': 'Transcript Activity Score',
|
|
'type': 'number',
|
|
'name': 'transcript_activity_score',
|
|
'help': 'Score to assign to the conversation transcript activity, default is 0',
|
|
},
|
|
]
|
|
visible_properties:
|
|
[
|
|
'endpoint_url',
|
|
'enable_conversation_activity',
|
|
'enable_transcript_activity',
|
|
'conversation_activity_score',
|
|
'transcript_activity_score',
|
|
]
|