Add files via upload

This commit is contained in:
公明
2026-07-06 13:55:51 +08:00
committed by GitHub
parent a425df2607
commit ecc75ee326
8 changed files with 870 additions and 36 deletions
+34
View File
@@ -1316,6 +1316,40 @@
"appSecretPlaceholder": "Lark/Feishu App Secret",
"verifyTokenLabel": "Verify Token (Optional)",
"verifyTokenPlaceholder": "Event subscription Verification Token"
},
"telegram": {
"title": "Telegram",
"subtitle": "Bot API long polling; direct chat and group @",
"enabled": "Enable Telegram bot",
"botToken": "Bot Token",
"botTokenHint": "Receives via getUpdates long poll; no public callback URL needed",
"botUsername": "Bot Username (optional)",
"allowGroup": "Allow group chat (respond to @ only)"
},
"slack": {
"title": "Slack",
"subtitle": "Socket Mode; no public callback URL needed",
"enabled": "Enable Slack bot",
"botToken": "Bot Token (xoxb-)",
"appToken": "App-Level Token (xapp-)",
"appTokenHint": "Requires connections:write scope for Socket Mode"
},
"discord": {
"title": "Discord",
"subtitle": "Gateway WebSocket; DMs and server @",
"enabled": "Enable Discord bot",
"botToken": "Bot Token",
"botTokenHint": "Create bot in Developer Portal; enable Message Content Intent",
"allowGuild": "Allow guild channels (respond to @ only)"
},
"qq": {
"title": "QQ Bot",
"subtitle": "QQ Open Platform WebSocket; C2C and group @",
"enabled": "Enable QQ bot",
"appId": "App ID",
"clientSecret": "Client Secret",
"secretHint": "From QQ Bot Open Platform; use sandbox before going live",
"sandbox": "Sandbox environment"
}
},
"apply": {
+34
View File
@@ -1304,6 +1304,40 @@
"appSecretPlaceholder": "飞书应用 App Secret",
"verifyTokenLabel": "Verify Token(可选)",
"verifyTokenPlaceholder": "事件订阅 Verification Token"
},
"telegram": {
"title": "Telegram",
"subtitle": "Bot API 长轮询,私聊与群聊 @",
"enabled": "启用 Telegram 机器人",
"botToken": "Bot Token",
"botTokenHint": "通过 getUpdates 长轮询收消息,无需公网回调",
"botUsername": "Bot Username(可选)",
"allowGroup": "允许群聊(仅响应 @ 机器人)"
},
"slack": {
"title": "Slack",
"subtitle": "Socket Mode,无需公网回调",
"enabled": "启用 Slack 机器人",
"botToken": "Bot Token (xoxb-)",
"appToken": "App-Level Token (xapp-)",
"appTokenHint": "需 connections:write 权限,用于 Socket Mode"
},
"discord": {
"title": "Discord",
"subtitle": "Gateway WebSocket,私聊与服务器 @",
"enabled": "启用 Discord 机器人",
"botToken": "Bot Token",
"botTokenHint": "开发者门户创建 Bot,开启 Message Content Intent",
"allowGuild": "允许服务器频道(仅响应 @ 机器人)"
},
"qq": {
"title": "QQ 机器人",
"subtitle": "QQ 开放平台 WebSocketC2C 与群 @",
"enabled": "启用 QQ 机器人",
"appId": "App ID",
"clientSecret": "Client Secret",
"secretHint": "从 QQ 机器人开放平台获取;上线前可勾选沙箱",
"sandbox": "沙箱环境"
}
},
"apply": {
+75 -2
View File
@@ -35,6 +35,18 @@ function getRobotStatus(type) {
} else if (type === 'lark') {
configured = !!(value('robot-lark-app-id') && value('robot-lark-app-secret'));
enabled = checked('robot-lark-enabled');
} else if (type === 'telegram') {
configured = !!value('robot-telegram-bot-token');
enabled = checked('robot-telegram-enabled');
} else if (type === 'slack') {
configured = !!(value('robot-slack-bot-token') && value('robot-slack-app-token'));
enabled = checked('robot-slack-enabled');
} else if (type === 'discord') {
configured = !!value('robot-discord-bot-token');
enabled = checked('robot-discord-enabled');
} else if (type === 'qq') {
configured = !!(value('robot-qq-app-id') && value('robot-qq-client-secret'));
enabled = checked('robot-qq-enabled');
}
if (enabled) {
@@ -47,7 +59,7 @@ function getRobotStatus(type) {
}
function refreshRobotManager() {
['wechat', 'wecom', 'dingtalk', 'lark'].forEach((type) => {
['wechat', 'wecom', 'dingtalk', 'lark', 'telegram', 'slack', 'discord', 'qq'].forEach((type) => {
const status = getRobotStatus(type);
const pill = document.getElementById(`robot-card-${type}-status`);
if (pill) {
@@ -95,7 +107,11 @@ function bindRobotManagerEvents() {
'robot-wechat-enabled', 'robot-wechat-ilink-bot-id',
'robot-wecom-enabled', 'robot-wecom-token', 'robot-wecom-corp-id', 'robot-wecom-secret', 'robot-wecom-agent-id',
'robot-dingtalk-enabled', 'robot-dingtalk-client-id', 'robot-dingtalk-client-secret',
'robot-lark-enabled', 'robot-lark-app-id', 'robot-lark-app-secret'
'robot-lark-enabled', 'robot-lark-app-id', 'robot-lark-app-secret',
'robot-telegram-enabled', 'robot-telegram-bot-token', 'robot-telegram-bot-username', 'robot-telegram-allow-group',
'robot-slack-enabled', 'robot-slack-bot-token', 'robot-slack-app-token',
'robot-discord-enabled', 'robot-discord-bot-token', 'robot-discord-allow-guild',
'robot-qq-enabled', 'robot-qq-app-id', 'robot-qq-client-secret', 'robot-qq-sandbox'
];
robotInputIds.forEach((id) => {
const el = document.getElementById(id);
@@ -608,6 +624,10 @@ async function loadConfig(loadTools = true) {
const wecom = robots.wecom || {};
const dingtalk = robots.dingtalk || {};
const lark = robots.lark || {};
const telegram = robots.telegram || {};
const slack = robots.slack || {};
const discord = robots.discord || {};
const qq = robots.qq || {};
const wechatEnabled = document.getElementById('robot-wechat-enabled');
if (wechatEnabled) wechatEnabled.checked = wechat.enabled === true;
const wechatBase = document.getElementById('robot-wechat-base-url');
@@ -647,6 +667,34 @@ async function loadConfig(loadTools = true) {
if (larkAppSecret) larkAppSecret.value = lark.app_secret || '';
const larkVerify = document.getElementById('robot-lark-verify-token');
if (larkVerify) larkVerify.value = lark.verify_token || '';
const telegramEnabled = document.getElementById('robot-telegram-enabled');
if (telegramEnabled) telegramEnabled.checked = telegram.enabled === true;
const telegramToken = document.getElementById('robot-telegram-bot-token');
if (telegramToken) telegramToken.value = telegram.bot_token || '';
const telegramUsername = document.getElementById('robot-telegram-bot-username');
if (telegramUsername) telegramUsername.value = telegram.bot_username || '';
const telegramAllowGroup = document.getElementById('robot-telegram-allow-group');
if (telegramAllowGroup) telegramAllowGroup.checked = telegram.allow_group_messages === true;
const slackEnabled = document.getElementById('robot-slack-enabled');
if (slackEnabled) slackEnabled.checked = slack.enabled === true;
const slackBotToken = document.getElementById('robot-slack-bot-token');
if (slackBotToken) slackBotToken.value = slack.bot_token || '';
const slackAppToken = document.getElementById('robot-slack-app-token');
if (slackAppToken) slackAppToken.value = slack.app_token || '';
const discordEnabled = document.getElementById('robot-discord-enabled');
if (discordEnabled) discordEnabled.checked = discord.enabled === true;
const discordToken = document.getElementById('robot-discord-bot-token');
if (discordToken) discordToken.value = discord.bot_token || '';
const discordAllowGuild = document.getElementById('robot-discord-allow-guild');
if (discordAllowGuild) discordAllowGuild.checked = discord.allow_guild_messages === true;
const qqEnabled = document.getElementById('robot-qq-enabled');
if (qqEnabled) qqEnabled.checked = qq.enabled === true;
const qqAppId = document.getElementById('robot-qq-app-id');
if (qqAppId) qqAppId.value = qq.app_id || '';
const qqSecret = document.getElementById('robot-qq-client-secret');
if (qqSecret) qqSecret.value = qq.client_secret || '';
const qqSandbox = document.getElementById('robot-qq-sandbox');
if (qqSandbox) qqSandbox.checked = qq.sandbox === true;
bindRobotManagerEvents();
refreshRobotManager();
@@ -1535,6 +1583,31 @@ async function applySettings() {
app_secret: document.getElementById('robot-lark-app-secret')?.value.trim() || '',
verify_token: document.getElementById('robot-lark-verify-token')?.value.trim() || '',
allow_chat_id_fallback: !!(prevRobots.lark && prevRobots.lark.allow_chat_id_fallback)
},
telegram: {
enabled: document.getElementById('robot-telegram-enabled')?.checked === true,
bot_token: document.getElementById('robot-telegram-bot-token')?.value.trim() || '',
bot_username: document.getElementById('robot-telegram-bot-username')?.value.trim() || '',
allow_group_messages: document.getElementById('robot-telegram-allow-group')?.checked === true,
...(prevRobots.telegram && typeof prevRobots.telegram === 'object' ? {
update_offset: prevRobots.telegram.update_offset || 0
} : {})
},
slack: {
enabled: document.getElementById('robot-slack-enabled')?.checked === true,
bot_token: document.getElementById('robot-slack-bot-token')?.value.trim() || '',
app_token: document.getElementById('robot-slack-app-token')?.value.trim() || ''
},
discord: {
enabled: document.getElementById('robot-discord-enabled')?.checked === true,
bot_token: document.getElementById('robot-discord-bot-token')?.value.trim() || '',
allow_guild_messages: document.getElementById('robot-discord-allow-guild')?.checked === true
},
qq: {
enabled: document.getElementById('robot-qq-enabled')?.checked === true,
app_id: document.getElementById('robot-qq-app-id')?.value.trim() || '',
client_secret: document.getElementById('robot-qq-client-secret')?.value.trim() || '',
sandbox: document.getElementById('robot-qq-sandbox')?.checked === true
}
},
tools: []
+165
View File
@@ -3357,6 +3357,46 @@
<span class="robot-card-action" data-i18n="settings.robots.configure">配置</span>
</span>
</button>
<button type="button" class="robot-card" data-robot-card="telegram" onclick="openRobotEditor('telegram')">
<span class="robot-card-main">
<span class="robot-card-title" data-i18n="settings.robots.telegram.title">Telegram</span>
<span class="robot-card-desc" data-i18n="settings.robots.telegram.subtitle">Bot API 长轮询,私聊与群聊 @</span>
</span>
<span class="robot-card-meta">
<span id="robot-card-telegram-status" class="robot-status-pill robot-status-pill--idle" data-i18n="settings.robots.statusNotConfigured">未配置</span>
<span class="robot-card-action" data-i18n="settings.robots.configure">配置</span>
</span>
</button>
<button type="button" class="robot-card" data-robot-card="slack" onclick="openRobotEditor('slack')">
<span class="robot-card-main">
<span class="robot-card-title" data-i18n="settings.robots.slack.title">Slack</span>
<span class="robot-card-desc" data-i18n="settings.robots.slack.subtitle">Socket Mode,无需公网回调</span>
</span>
<span class="robot-card-meta">
<span id="robot-card-slack-status" class="robot-status-pill robot-status-pill--idle" data-i18n="settings.robots.statusNotConfigured">未配置</span>
<span class="robot-card-action" data-i18n="settings.robots.configure">配置</span>
</span>
</button>
<button type="button" class="robot-card" data-robot-card="discord" onclick="openRobotEditor('discord')">
<span class="robot-card-main">
<span class="robot-card-title" data-i18n="settings.robots.discord.title">Discord</span>
<span class="robot-card-desc" data-i18n="settings.robots.discord.subtitle">Gateway WebSocket,私聊与服务器 @</span>
</span>
<span class="robot-card-meta">
<span id="robot-card-discord-status" class="robot-status-pill robot-status-pill--idle" data-i18n="settings.robots.statusNotConfigured">未配置</span>
<span class="robot-card-action" data-i18n="settings.robots.configure">配置</span>
</span>
</button>
<button type="button" class="robot-card" data-robot-card="qq" onclick="openRobotEditor('qq')">
<span class="robot-card-main">
<span class="robot-card-title" data-i18n="settings.robots.qq.title">QQ 机器人</span>
<span class="robot-card-desc" data-i18n="settings.robots.qq.subtitle">QQ 开放平台 WebSocketC2C 与群 @</span>
</span>
<span class="robot-card-meta">
<span id="robot-card-qq-status" class="robot-status-pill robot-status-pill--idle" data-i18n="settings.robots.statusNotConfigured">未配置</span>
<span class="robot-card-action" data-i18n="settings.robots.configure">配置</span>
</span>
</button>
</div>
</div>
@@ -3522,6 +3562,115 @@
</div>
</div>
<!-- Telegram -->
<div class="settings-subsection robot-editor-panel" data-robot-editor="telegram" hidden>
<h4 data-i18n="settings.robots.telegram.title">Telegram</h4>
<div class="settings-form">
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="robot-telegram-enabled" class="modern-checkbox" />
<span class="checkbox-custom"></span>
<span class="checkbox-text" data-i18n="settings.robots.telegram.enabled">启用 Telegram 机器人</span>
</label>
</div>
<div class="form-group">
<label for="robot-telegram-bot-token" data-i18n="settings.robots.telegram.botToken">Bot Token</label>
<input type="password" id="robot-telegram-bot-token" autocomplete="off" placeholder="从 @BotFather 获取" />
<small class="form-hint" data-i18n="settings.robots.telegram.botTokenHint">通过 getUpdates 长轮询收消息,无需公网回调</small>
</div>
<div class="form-group">
<label for="robot-telegram-bot-username" data-i18n="settings.robots.telegram.botUsername">Bot Username(可选)</label>
<input type="text" id="robot-telegram-bot-username" autocomplete="off" placeholder="不含 @,留空则自动 getMe" />
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="robot-telegram-allow-group" class="modern-checkbox" />
<span class="checkbox-custom"></span>
<span class="checkbox-text" data-i18n="settings.robots.telegram.allowGroup">允许群聊(仅响应 @ 机器人)</span>
</label>
</div>
</div>
</div>
<!-- Slack -->
<div class="settings-subsection robot-editor-panel" data-robot-editor="slack" hidden>
<h4 data-i18n="settings.robots.slack.title">Slack</h4>
<div class="settings-form">
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="robot-slack-enabled" class="modern-checkbox" />
<span class="checkbox-custom"></span>
<span class="checkbox-text" data-i18n="settings.robots.slack.enabled">启用 Slack 机器人</span>
</label>
</div>
<div class="form-group">
<label for="robot-slack-bot-token" data-i18n="settings.robots.slack.botToken">Bot Token (xoxb-)</label>
<input type="password" id="robot-slack-bot-token" autocomplete="off" />
</div>
<div class="form-group">
<label for="robot-slack-app-token" data-i18n="settings.robots.slack.appToken">App-Level Token (xapp-)</label>
<input type="password" id="robot-slack-app-token" autocomplete="off" />
<small class="form-hint" data-i18n="settings.robots.slack.appTokenHint">需 connections:write 权限,用于 Socket Mode</small>
</div>
</div>
</div>
<!-- Discord -->
<div class="settings-subsection robot-editor-panel" data-robot-editor="discord" hidden>
<h4 data-i18n="settings.robots.discord.title">Discord</h4>
<div class="settings-form">
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="robot-discord-enabled" class="modern-checkbox" />
<span class="checkbox-custom"></span>
<span class="checkbox-text" data-i18n="settings.robots.discord.enabled">启用 Discord 机器人</span>
</label>
</div>
<div class="form-group">
<label for="robot-discord-bot-token" data-i18n="settings.robots.discord.botToken">Bot Token</label>
<input type="password" id="robot-discord-bot-token" autocomplete="off" />
<small class="form-hint" data-i18n="settings.robots.discord.botTokenHint">开发者门户创建 Bot,开启 Message Content Intent</small>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="robot-discord-allow-guild" class="modern-checkbox" />
<span class="checkbox-custom"></span>
<span class="checkbox-text" data-i18n="settings.robots.discord.allowGuild">允许服务器频道(仅响应 @ 机器人)</span>
</label>
</div>
</div>
</div>
<!-- QQ -->
<div class="settings-subsection robot-editor-panel" data-robot-editor="qq" hidden>
<h4 data-i18n="settings.robots.qq.title">QQ 机器人</h4>
<div class="settings-form">
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="robot-qq-enabled" class="modern-checkbox" />
<span class="checkbox-custom"></span>
<span class="checkbox-text" data-i18n="settings.robots.qq.enabled">启用 QQ 机器人</span>
</label>
</div>
<div class="form-group">
<label for="robot-qq-app-id" data-i18n="settings.robots.qq.appId">App ID</label>
<input type="text" id="robot-qq-app-id" autocomplete="off" />
</div>
<div class="form-group">
<label for="robot-qq-client-secret" data-i18n="settings.robots.qq.clientSecret">Client Secret</label>
<input type="password" id="robot-qq-client-secret" autocomplete="off" />
<small class="form-hint" data-i18n="settings.robots.qq.secretHint">从 QQ 机器人开放平台获取;上线前可勾选沙箱</small>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="robot-qq-sandbox" class="modern-checkbox" />
<span class="checkbox-custom"></span>
<span class="checkbox-text" data-i18n="settings.robots.qq.sandbox">沙箱环境</span>
</label>
</div>
</div>
</div>
<div id="robot-create-modal" class="modal" role="dialog" aria-modal="true" aria-labelledby="robot-create-title">
<div class="modal-content robot-create-modal-content">
<div class="modal-header">
@@ -3547,6 +3696,22 @@
<span data-i18n="settings.robots.lark.title">飞书 (Lark)</span>
<small data-i18n="settings.robots.lark.subtitle">企业应用机器人</small>
</button>
<button type="button" class="robot-type-option" onclick="selectRobotType('telegram')">
<span data-i18n="settings.robots.telegram.title">Telegram</span>
<small data-i18n="settings.robots.telegram.subtitle">Bot API 长轮询</small>
</button>
<button type="button" class="robot-type-option" onclick="selectRobotType('slack')">
<span data-i18n="settings.robots.slack.title">Slack</span>
<small data-i18n="settings.robots.slack.subtitle">Socket Mode</small>
</button>
<button type="button" class="robot-type-option" onclick="selectRobotType('discord')">
<span data-i18n="settings.robots.discord.title">Discord</span>
<small data-i18n="settings.robots.discord.subtitle">Gateway WebSocket</small>
</button>
<button type="button" class="robot-type-option" onclick="selectRobotType('qq')">
<span data-i18n="settings.robots.qq.title">QQ 机器人</span>
<small data-i18n="settings.robots.qq.subtitle">QQ 开放平台</small>
</button>
</div>
</div>
</div>