feat(channels): add ClickClack config compatibility

This commit is contained in:
晴天
2026-05-23 08:07:39 +08:00
parent d933177ec3
commit 579d706075
7 changed files with 371 additions and 7 deletions

View File

@@ -19,6 +19,7 @@ export const CHANNEL_LABELS = {
line: 'LINE',
nostr: 'Nostr',
mattermost: 'Mattermost',
clickclack: 'ClickClack',
'openclaw-weixin': '微信',
weixin: '微信',
}

View File

@@ -128,6 +128,22 @@ export default {
mattermostNameMatchingHint: _('关闭时优先使用稳定 ID避免同名用户或频道误匹配。', 'When disabled, prefer stable IDs to avoid wrong matches with duplicate users or channels.'),
mattermostPrivateNetwork: _('允许内网地址', 'Allow Private Network'),
mattermostPrivateNetworkHint: _('仅在 Mattermost 部署于可信内网时开启。', 'Enable only when Mattermost is deployed on a trusted private network.'),
clickclackDesc: _('接入自托管 ClickClack 工作区,支持频道、线程和私信目标', 'Connect a self-hosted ClickClack workspace with channel, thread, and DM targets'),
clickclackGuide1: _('确认 ClickClack 服务已部署并可被 Gateway 访问,复制工作区 Base URL', 'Make sure ClickClack is deployed and reachable by Gateway, then copy the workspace Base URL'),
clickclackGuide2: _('准备访问 Token 与 Workspace 标识;多账号时建议填写账号标识,例如 work', 'Prepare the access Token and Workspace identifier; for multi-account setup, use an account id such as work'),
clickclackGuide3: _('Default To 支持 <code>channel:&lt;id&gt;</code>、<code>thread:&lt;id&gt;</code>、<code>dm:&lt;id&gt;</code>,例如 <code>channel:general</code>', 'Default To supports <code>channel:&lt;id&gt;</code>, <code>thread:&lt;id&gt;</code>, and <code>dm:&lt;id&gt;</code>, e.g. <code>channel:general</code>'),
clickclackGuide4: _('保存后面板会启用 bundled ClickClack 插件并重载 Gateway连通性以 Gateway 日志或 channels status 为准', 'After saving, the panel enables the bundled ClickClack plugin and reloads Gateway; verify connectivity through Gateway logs or channels status'),
clickclackGuideFooter: _('<div style="margin-top:8px;font-size:var(--font-size-xs);color:var(--text-tertiary)">ClickClack 最小配置需要 Base URL、Token 与 Workspace。</div>', '<div style="margin-top:8px;font-size:var(--font-size-xs);color:var(--text-tertiary)">ClickClack minimally requires Base URL, Token, and Workspace.</div>'),
clickclackBaseUrlHint: _('填写 ClickClack 服务根地址,例如 https://clickclack.example.com。', 'Use the ClickClack service root URL, for example https://clickclack.example.com.'),
clickclackTokenPh: _('ClickClack Access Token', 'ClickClack Access Token'),
clickclackWorkspaceHint: _('工作区标识必须与 ClickClack 服务端配置一致。', 'Workspace must match the ClickClack server configuration.'),
clickclackSystemPromptPh: _('可选,覆盖该渠道使用的系统提示词', 'Optional system prompt override for this channel'),
clickclackTimeoutHint: _('请求超时时间,单位秒;上游允许 1 到 3600。', 'Request timeout in seconds; upstream allows 1 to 3600.'),
clickclackToolsAllowHint: _('可选,逗号分隔允许调用的工具名。', 'Optional comma-separated tool names allowed for this channel.'),
clickclackSenderIsOwner: _('发送者作为 Owner', 'Sender Is Owner'),
clickclackSenderIsOwnerHint: _('开启后将 ClickClack 消息发送者视为 owner 身份,适合可信内部工作区。', 'Treat the ClickClack sender as owner when enabled; use only in trusted internal workspaces.'),
clickclackDefaultToHint: _('默认发送目标,例如 channel:general、thread:123 或 dm:alice。', 'Default target, e.g. channel:general, thread:123, or dm:alice.'),
clickclackAllowFromHint: _('可选,逗号分隔允许来源;留空按上游默认处理,* 表示允许全部。', 'Optional comma-separated allowed sources; leave empty for upstream defaults, * allows all.'),
synologyChatDesc: _('接入群晖 Synology Chat适合 NAS 内网团队协作', 'Connect Synology Chat for NAS-hosted team messaging'),
synologyChatGuide1: _('在 Synology Chat 管理后台创建 Bot并复制 Token', 'Create a bot in Synology Chat administration and copy its Token'),
synologyChatGuide2: _('配置 Incoming Webhook 或机器人发消息 URL填入 Incoming URL', 'Configure an Incoming Webhook or bot post URL, then paste it as Incoming URL'),

View File

@@ -274,6 +274,42 @@ const PLATFORM_REGISTRY = {
pluginRequired: '@openclaw/mattermost@latest',
pluginId: 'mattermost',
},
clickclack: {
label: 'ClickClack',
iconName: 'message-square',
desc: t('channels.clickclackDesc'),
guide: [
t('channels.clickclackGuide1'),
t('channels.clickclackGuide2'),
t('channels.clickclackGuide3'),
t('channels.clickclackGuide4'),
],
guideFooter: t('channels.clickclackGuideFooter'),
fields: [
{ key: 'baseUrl', label: 'Base URL', placeholder: 'https://clickclack.example.com', required: true, hint: t('channels.clickclackBaseUrlHint') },
{ key: 'token', label: 'Token', placeholder: t('channels.clickclackTokenPh'), secret: true, required: true },
{ key: 'workspace', label: 'Workspace', placeholder: 'ops', required: true, hint: t('channels.clickclackWorkspaceHint') },
{ key: 'name', label: t('channels.accountName'), placeholder: t('channels.optionalEg', { example: 'ops' }), required: false },
{ key: 'botUserId', label: 'Bot User ID', placeholder: t('channels.optionalEg', { example: 'bot-1' }), required: false },
{ key: 'agentId', label: 'Agent ID', placeholder: t('channels.optionalEg', { example: 'default' }), required: false },
{ key: 'replyMode', label: 'Reply Mode', type: 'select', options: [
{ value: '', label: t('channels.policyDefault') },
{ value: 'agent', label: 'Agent' },
{ value: 'model', label: 'Model' },
], required: false },
{ key: 'model', label: 'Model', placeholder: t('channels.optionalEg', { example: 'claude-sonnet-4-5' }), required: false },
{ key: 'systemPrompt', label: 'System Prompt', placeholder: t('channels.clickclackSystemPromptPh'), multiline: true, required: false },
{ key: 'timeoutSeconds', label: 'Timeout Seconds', placeholder: '120', required: false, hint: t('channels.clickclackTimeoutHint') },
{ key: 'toolsAllow', label: 'Tools Allow', placeholder: 'shell, browser.search', required: false, hint: t('channels.clickclackToolsAllowHint') },
{ key: 'senderIsOwner', label: t('channels.clickclackSenderIsOwner'), type: 'select', options: BOOLEAN_OPTIONS, required: false, hint: t('channels.clickclackSenderIsOwnerHint') },
{ key: 'defaultTo', label: 'Default To', placeholder: 'channel:general', required: false, hint: t('channels.clickclackDefaultToHint') },
{ key: 'allowFrom', label: 'Allow From', placeholder: '*, channel:general, dm:alice', required: false, hint: t('channels.clickclackAllowFromHint') },
{ key: 'reconnectMs', label: 'Reconnect MS', placeholder: '1500', required: false },
],
configKey: 'clickclack',
pairingChannel: 'clickclack',
pluginId: 'clickclack',
},
'synology-chat': {
label: 'Synology Chat',
iconName: 'message-square',
@@ -796,7 +832,7 @@ function applyRouteIntent(page, state) {
// ── 已配置平台渲染 ──
// ── 多账号支持的平台:与 OpenClaw 的 accounts/defaultAccount 配置模型保持一致 ──
const MULTI_INSTANCE_PLATFORMS = ['telegram', 'discord', 'slack', 'feishu', 'dingtalk', 'dingtalk-connector', 'qqbot', 'zalo', 'zalouser', 'line', 'mattermost', 'synology-chat', 'googlechat', 'signal']
const MULTI_INSTANCE_PLATFORMS = ['telegram', 'discord', 'slack', 'feishu', 'dingtalk', 'dingtalk-connector', 'qqbot', 'zalo', 'zalouser', 'line', 'mattermost', 'clickclack', 'synology-chat', 'googlechat', 'signal']
function supportsMessagingMultiAccount(pid) {
return MULTI_INSTANCE_PLATFORMS.includes(pid)