feat(channels): add IRC config compatibility

This commit is contained in:
晴天
2026-05-24 00:57:37 +08:00
parent 326c5597df
commit 7e3bb71fca
6 changed files with 836 additions and 12 deletions

View File

@@ -190,6 +190,29 @@ export default {
nostrDefaultAccountHint: _('上游当前通过根节点配置生成隐式账号,通常保持 default 即可。', 'Upstream currently derives an implicit account from the root config; default is usually enough.'),
nostrProfileAboutPh: _('可选,展示在 Nostr Profile 中的机器人介绍', 'Optional bot introduction shown in the Nostr profile'),
nostrProfileUrlHint: _('上游 Profile URL 字段要求使用 https:// 地址。', 'Upstream profile URL fields require https:// URLs.'),
ircDesc: _('接入 IRC 网络支持服务器账号、NickServ 登录、频道白名单和提及策略', 'Connect IRC networks with server accounts, NickServ login, channel allowlists, and mention policy'),
ircGuide1: _('准备 IRC 服务器地址,例如 <code>irc.libera.chat</code>,并确认 Gateway 网络可以连接', 'Prepare the IRC server host, for example <code>irc.libera.chat</code>, and make sure Gateway can connect'),
ircGuide2: _('填写机器人 Nick如服务器需要 SASL 或密码,可填写 Server Password 或文件路径', 'Fill the bot Nick; if the server requires SASL or a password, provide Server Password or a file path'),
ircGuide3: _('如账号已注册,开启 NickServ 并填写密码或密码文件;需要自动注册时再开启 Register', 'If the account is registered, enable NickServ and provide password or password file; enable Register only when automatic registration is needed'),
ircGuide4: _('填写自动加入频道和允许频道,保存后面板会安装 IRC 插件并重载 Gateway', 'Fill auto-join channels and allowed channels; after saving, the panel installs the IRC plugin and reloads Gateway'),
ircGuideFooter: _('<div style="margin-top:8px;font-size:var(--font-size-xs);color:var(--text-tertiary)">IRC 最小配置需要 Host 与 Nick真实连接状态以 Gateway 日志或 channels status 为准。</div>', '<div style="margin-top:8px;font-size:var(--font-size-xs);color:var(--text-tertiary)">IRC minimally requires Host and Nick; verify real connectivity through Gateway logs or channels status.</div>'),
ircHostHint: _('IRC 服务器主机名,不包含 irc:// 前缀。', 'IRC server host name without the irc:// prefix.'),
ircPortHint: _('常见 TLS 端口为 6697非 TLS 常见端口为 6667。', 'Common TLS port is 6697; common non-TLS port is 6667.'),
ircTlsHint: _('连接支持 TLS 的服务器时建议开启。', 'Recommended when connecting to servers that support TLS.'),
ircNickHint: _('机器人在 IRC 网络中的昵称,必须符合服务器昵称规则。', 'Bot nickname on the IRC network; it must satisfy server nickname rules.'),
ircPasswordHint: _('服务器连接密码或 SASL 密码;生产环境建议使用 SecretRef。', 'Server connection password or SASL password; prefer SecretRef in production.'),
ircPasswordFileHint: _('服务器密码文件路径;与 Server Password 二选一。', 'Path to the server password file; use this or Server Password.'),
ircNickservEnabled: _('启用 NickServ', 'Enable NickServ'),
ircNickservHint: _('用于向 NickServ 识别已注册昵称可填写明文、SecretRef 或密码文件。', 'Used to identify a registered nick with NickServ; supports plain text, SecretRef, or password file.'),
ircNickservRegister: _('自动注册昵称', 'Auto-register nick'),
ircNickservRegisterHint: _('仅在你确认服务器允许机器人自动注册时开启。', 'Enable only when the server allows bot auto-registration.'),
ircChannelsHint: _('连接后自动加入的频道,使用 # 开头,多个值用逗号分隔。', 'Channels to auto-join after connect; use # prefixes and separate multiple values with commas.'),
ircGroupsHint: _('允许机器人响应的频道列表Require Mention 会写入每个频道配置。', 'Channels where the bot may respond; Require Mention is written into each channel config.'),
ircGroupAllowFromHint: _('可选,限制频道内允许触发机器人的 nick 或 hostmask。', 'Optional nick or hostmask allowlist for channel messages.'),
ircRequireMention: _('频道要求提及机器人', 'Require mention in channels'),
ircMentionPatternsHint: _('额外提及模式,例如 openclaw: 或 @openclaw。', 'Additional mention patterns, for example openclaw: or @openclaw.'),
ircNameMatching: _('允许名称匹配', 'Allow name matching'),
ircNameMatchingHint: _('仅在无法使用稳定 hostmask 时开启;开启后同名用户存在误匹配风险。', 'Enable only when stable hostmasks are unavailable; duplicate nicks can be matched incorrectly.'),
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

@@ -418,6 +418,59 @@ const PLATFORM_REGISTRY = {
pluginRequired: '@openclaw/nostr@latest',
pluginId: 'nostr',
},
irc: {
label: 'IRC',
iconName: 'hash',
desc: t('channels.ircDesc'),
guide: [
t('channels.ircGuide1'),
t('channels.ircGuide2'),
t('channels.ircGuide3'),
t('channels.ircGuide4'),
],
guideFooter: t('channels.ircGuideFooter'),
fields: [
{ key: 'host', label: 'Host', placeholder: 'irc.libera.chat', required: true, hint: t('channels.ircHostHint') },
{ key: 'port', label: 'Port', placeholder: '6697', required: false, hint: t('channels.ircPortHint') },
{ key: 'tls', label: 'TLS', type: 'select', options: BOOLEAN_OPTIONS, required: false, hint: t('channels.ircTlsHint') },
{ key: 'nick', label: 'Nick', placeholder: 'openclaw-bot', required: true, hint: t('channels.ircNickHint') },
{ key: 'username', label: 'Username', placeholder: 'openclaw', required: false },
{ key: 'realname', label: 'Real Name', placeholder: 'OpenClaw Bot', required: false },
{ key: 'password', label: 'Server Password', placeholder: t('channels.optionalEg', { example: 'server-password' }), secret: true, required: false, hint: t('channels.ircPasswordHint') },
{ key: 'passwordFile', label: 'Server Password File', placeholder: '/run/secrets/irc-password', required: false, hint: t('channels.ircPasswordFileHint') },
{ key: 'nickservEnabled', label: t('channels.ircNickservEnabled'), type: 'select', options: BOOLEAN_OPTIONS, required: false, hint: t('channels.ircNickservHint') },
{ key: 'nickservService', label: 'NickServ Service', placeholder: 'NickServ', required: false },
{ key: 'nickservPassword', label: 'NickServ Password', placeholder: t('channels.optionalEg', { example: 'nickserv-password' }), secret: true, required: false, hint: t('channels.ircNickservHint') },
{ key: 'nickservPasswordFile', label: 'NickServ Password File', placeholder: '/run/secrets/irc-nickserv', required: false },
{ key: 'nickservRegister', label: t('channels.ircNickservRegister'), type: 'select', options: BOOLEAN_OPTIONS, required: false, hint: t('channels.ircNickservRegisterHint') },
{ key: 'nickservRegisterEmail', label: 'NickServ Register Email', placeholder: 'bot@example.com', required: false },
{ key: 'channels', label: 'Auto Join Channels', placeholder: '#openclaw, #ops', required: false, hint: t('channels.ircChannelsHint') },
{ key: 'dmPolicy', label: t('channels.dmPolicy'), type: 'select', options: DM_POLICY_OPTIONS, required: false },
{ key: 'allowFrom', label: 'Allow From', placeholder: 'alice!ident@example.org, bob', required: false, hint: t('channels.allowFromHint') },
{ key: 'defaultTo', label: 'Default To', placeholder: '#openclaw', required: false },
{ key: 'groupPolicy', label: t('channels.groupPolicy'), type: 'select', options: GROUP_POLICY_OPTIONS(t('channels.groupAllChannels')), required: false },
{ key: 'groups', label: 'Allowed Channels', placeholder: '#openclaw, #ops', required: false, hint: t('channels.ircGroupsHint') },
{ key: 'groupAllowFrom', label: 'Group Allow From', placeholder: 'alice!ident@example.org', required: false, hint: t('channels.ircGroupAllowFromHint') },
{ key: 'requireMention', label: t('channels.ircRequireMention'), type: 'select', options: BOOLEAN_OPTIONS, required: false },
{ key: 'mentionPatterns', label: 'Mention Patterns', placeholder: 'openclaw:, @openclaw', required: false, hint: t('channels.ircMentionPatternsHint') },
{ key: 'historyLimit', label: 'History Limit', placeholder: '80', required: false },
{ key: 'dmHistoryLimit', label: 'DM History Limit', placeholder: '20', required: false },
{ key: 'mediaMaxMb', label: 'Media Max MB', placeholder: '25', required: false },
{ key: 'textChunkLimit', label: 'Text Chunk Limit', placeholder: '350', required: false },
{ key: 'chunkMode', label: 'Chunk Mode', type: 'select', options: [
{ value: '', label: t('channels.policyDefault') },
{ value: 'length', label: 'Length' },
{ value: 'newline', label: 'Newline' },
], required: false },
{ key: 'blockStreaming', label: t('channels.signalBlockStreaming'), type: 'select', options: BOOLEAN_OPTIONS, required: false },
{ key: 'responsePrefix', label: 'Response Prefix', placeholder: t('channels.optionalEg', { example: '[IRC]' }), required: false },
{ key: 'dangerouslyAllowNameMatching', label: t('channels.ircNameMatching'), type: 'select', options: BOOLEAN_OPTIONS, required: false, hint: t('channels.ircNameMatchingHint') },
],
configKey: 'irc',
pairingChannel: 'irc',
pluginRequired: '@openclaw/irc@latest',
pluginId: 'irc',
},
'synology-chat': {
label: 'Synology Chat',
iconName: 'message-square',
@@ -940,7 +993,7 @@ function applyRouteIntent(page, state) {
// ── 已配置平台渲染 ──
// ── 多账号支持的平台:与 OpenClaw 的 accounts/defaultAccount 配置模型保持一致 ──
const MULTI_INSTANCE_PLATFORMS = ['telegram', 'discord', 'slack', 'feishu', 'dingtalk', 'dingtalk-connector', 'qqbot', 'zalo', 'zalouser', 'line', 'mattermost', 'clickclack', 'nextcloud-talk', 'twitch', 'synology-chat', 'googlechat', 'signal']
const MULTI_INSTANCE_PLATFORMS = ['telegram', 'discord', 'slack', 'feishu', 'dingtalk', 'dingtalk-connector', 'qqbot', 'zalo', 'zalouser', 'line', 'mattermost', 'clickclack', 'nextcloud-talk', 'twitch', 'irc', 'synology-chat', 'googlechat', 'signal']
function supportsMessagingMultiAccount(pid) {
return MULTI_INSTANCE_PLATFORMS.includes(pid)