Dyte is sunsetting its existing infrastructure after the Cloudflare acquisition, so this migrates Chatwoot’s video call integration to Cloudflare RealtimeKit. The integration now uses Cloudflare Account ID, RealtimeKit App ID, and a Cloudflare API token with Realtime Admin permissions. Meeting creation and participant token generation now call Cloudflare’s RealtimeKit APIs, while the existing Chatwoot call experience remains unchanged for agents and customers. This also adds setup-time credential validation, so admins get clearer errors when the API token is invalid, the Cloudflare account or permissions are incorrect, or the RealtimeKit App ID does not belong to the selected account. Fixes https://linear.app/chatwoot/issue/PLA-176/migrate-dyte-integration-to-cloudflare-realtimekit **How to test** 1. Go to Settings → Integrations → Cloudflare RealtimeKit. 2. Add a Cloudflare Account ID, RealtimeKit App ID, and API token with Realtime Admin permissions. 3. Confirm the integration saves successfully with valid credentials. 4. Try invalid credentials and confirm the error identifies whether the token, account/permissions, or app ID is wrong. 5. Start a video call from a conversation and confirm the RealtimeKit meeting opens. --------- Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com> Co-authored-by: Sony Mathew <sony@chatwoot.com>
331 lines
10 KiB
YAML
331 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' },
|
|
'label_suggestion': { 'type': 'boolean' },
|
|
},
|
|
'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': '',
|
|
},
|
|
]
|
|
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',
|
|
]
|