fix(channels): hard-delete placeholder seeds; localize wizard verify+identity strings

This commit is contained in:
matevip 2026-04-30 07:00:06 +08:00
parent 3db4230142
commit 0c5c5bc2c2
9 changed files with 107 additions and 606 deletions

View File

@ -1204,163 +1204,18 @@ Automatically activate when user message contains:
Use read_skill_file to access references/ for more background material.' WHERE id = 1000000015;
-- ==================== Channel Seed Data ====================
-- MateClaw supports multiple channels
-- Only the Web channel is seeded — it's always-on and needs no
-- credentials. Other channel types are added through the wizard
-- (ChannelTypePicker → ChannelOnboardingWizard) so the list page
-- doesn't start with 8 empty placeholders staring at the user.
-- See V64__cleanup_unused_channel_seeds.sql for the matching cleanup
-- of those placeholders on existing installs.
-- 1. Web Console (enabled by default)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000001, 'Web Console', 'web', 1000000001, '', '{}', TRUE,
'Default Web console channel with browser SSE streaming', NOW(), NOW(), 0);
-- 2. DingTalk (disabled by default, requires client_id/client_secret)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000002, 'DingTalk Bot', 'dingtalk', 1000000001, '', '{
"client_id": "",
"client_secret": "",
"robot_code": "",
"message_type": "markdown",
"card_template_id": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'DingTalk bot channel. Supports Stream callback and sessionWebhook reply. Create app on DingTalk Open Platform and set Webhook URL to /api/v1/channels/webhook/dingtalk', NOW(), NOW(), 0);
-- 3. Feishu (disabled by default, requires app_id/app_secret)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000003, 'Feishu Bot', 'feishu', 1000000001, '', '{
"app_id": "",
"app_secret": "",
"encrypt_key": "",
"verification_token": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Feishu bot channel. Supports event subscription callback. Create app on Feishu Open Platform and set event callback URL to /api/v1/channels/webhook/feishu', NOW(), NOW(), 0);
-- 4. Telegram (disabled by default, requires bot_token)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000004, 'Telegram Bot', 'telegram', 1000000001, '', '{
"bot_token": "",
"http_proxy": "",
"show_typing": true,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Telegram bot channel. Get Token from @BotFather, set Webhook URL to /api/v1/channels/webhook/telegram', NOW(), NOW(), 0);
-- 5. Discord (disabled by default, requires bot_token)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000005, 'Discord Bot', 'discord', 1000000001, '!mc ', '{
"bot_token": "",
"http_proxy": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Discord bot channel. Create Bot and get Token from Discord Developer Portal. Use !mc prefix in group chats', NOW(), NOW(), 0);
-- 6. WeCom Bot (disabled by default, requires bot_id/secret)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000006, 'WeCom Bot', 'wecom', 1000000001, '', '{
"bot_id": "",
"secret": "",
"welcome_text": "",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto",
"max_reconnect_attempts": -1
}', FALSE,
'WeCom smart bot channel (WebSocket long connection). Create a smart bot in WeCom admin console, select API mode with long connection, get bot_id and secret. No public IP needed', NOW(), NOW(), 0);
-- 7. QQ Bot (disabled by default, requires app_id/client_secret)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000007, 'QQ Bot', 'qq', 1000000001, '', '{
"app_id": "",
"client_secret": "",
"markdown_enabled": true,
"max_reconnect_attempts": 100,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'QQ bot channel (WebSocket long connection). Create a bot app on QQ Open Platform, get AppID and AppSecret. No public IP needed', NOW(), NOW(), 0);
-- 8. WeChat iLink Bot (disabled by default, requires QR code scan for bot_token)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000008, 'WeChat', 'weixin', 1000000001, '', '{
"bot_token": "",
"base_url": "https://ilinkai.weixin.qq.com",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'WeChat personal account channel (iLink Bot HTTP long polling). Get bot_token by scanning QR code to login, or enter existing token. Based on iLink Bot API, supports text, image, voice (ASR), file, and video messages', NOW(), NOW(), 0);
-- 9. Slack (disabled by default, requires bot_token / app_token)
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000009, 'Slack Bot', 'slack', 1000000001, '', '{
"bot_token": "",
"app_token": "",
"signing_secret": "",
"dm_policy": "open",
"group_policy": "mention",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Slack channel (Socket Mode). Get Bot Token (xoxb-) and App-Level Token (xapp-) from Slack App settings, enable Socket Mode to start using.', NOW(), NOW(), 0);
-- ==================== Example Cron Jobs ====================
MERGE INTO mate_cron_job (id, name, cron_expression, timezone, agent_id, task_type, trigger_message, request_body, enabled, create_time, update_time, deleted)
KEY (id)

View File

@ -1244,163 +1244,13 @@ Automatically activate when user message contains:
Use read_skill_file to access references/ for more background material.' WHERE id = 1000000015;
-- ==================== Channel Seed Data ====================
-- MateClaw supports multiple channels
-- Only the Web channel is seeded — see data-en.sql for rationale.
-- 1. Web Console (enabled by default)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000001, 'Web Console', 'web', 1000000001, '', '{}', TRUE,
'Default Web console channel with browser SSE streaming', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 2. DingTalk (disabled by default, requires client_id/client_secret)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000002, 'DingTalk Bot', 'dingtalk', 1000000001, '', '{
"client_id": "",
"client_secret": "",
"robot_code": "",
"message_type": "markdown",
"card_template_id": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'DingTalk bot channel. Supports Stream callback and sessionWebhook reply. Create app on DingTalk Open Platform and set Webhook URL to /api/v1/channels/webhook/dingtalk', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 3. Feishu (disabled by default, requires app_id/app_secret)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000003, 'Feishu Bot', 'feishu', 1000000001, '', '{
"app_id": "",
"app_secret": "",
"encrypt_key": "",
"verification_token": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Feishu bot channel. Supports event subscription callback. Create app on Feishu Open Platform and set event callback URL to /api/v1/channels/webhook/feishu', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 4. Telegram (disabled by default, requires bot_token)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000004, 'Telegram Bot', 'telegram', 1000000001, '', '{
"bot_token": "",
"http_proxy": "",
"show_typing": true,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Telegram bot channel. Get Token from @BotFather, set Webhook URL to /api/v1/channels/webhook/telegram', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 5. Discord (disabled by default, requires bot_token)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000005, 'Discord Bot', 'discord', 1000000001, '!mc ', '{
"bot_token": "",
"http_proxy": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Discord bot channel. Create Bot and get Token from Discord Developer Portal. Use !mc prefix in group chats', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 6. WeCom Bot (disabled by default, requires bot_id/secret)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000006, 'WeCom Bot', 'wecom', 1000000001, '', '{
"bot_id": "",
"secret": "",
"welcome_text": "",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto",
"max_reconnect_attempts": -1
}', FALSE,
'WeCom smart bot channel (WebSocket long connection). Create a smart bot in WeCom admin console, select API mode with long connection, get bot_id and secret. No public IP needed', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 7. QQ Bot (disabled by default, requires app_id/client_secret)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000007, 'QQ Bot', 'qq', 1000000001, '', '{
"app_id": "",
"client_secret": "",
"markdown_enabled": true,
"max_reconnect_attempts": 100,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'QQ bot channel (WebSocket long connection). Create a bot app on QQ Open Platform, get AppID and AppSecret. No public IP needed', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 8. WeChat iLink Bot (disabled by default, requires QR code scan for bot_token)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000008, 'WeChat', 'weixin', 1000000001, '', '{
"bot_token": "",
"base_url": "https://ilinkai.weixin.qq.com",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'WeChat personal account channel (iLink Bot HTTP long polling). Get bot_token by scanning QR code to login, or enter existing token. Based on iLink Bot API, supports text, image, voice (ASR), file, and video messages', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 9. Slack (disabled by default, requires bot_token / app_token)
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000009, 'Slack Bot', 'slack', 1000000001, '', '{
"bot_token": "",
"app_token": "",
"signing_secret": "",
"dm_policy": "open",
"group_policy": "mention",
"allow_from": [],
"deny_message": "Sorry, you do not have permission",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Slack channel (Socket Mode). Get Bot Token (xoxb-) and App-Level Token (xapp-) from Slack App settings, enable Socket Mode to start using.', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- ==================== Example Cron Jobs ====================
INSERT INTO mate_cron_job (id, name, cron_expression, timezone, agent_id, task_type, trigger_message, request_body, enabled, create_time, update_time, deleted)
VALUES (1000100001, 'Daily Greeting', '0 9 * * *', 'Asia/Shanghai', 1000000001, 'text', 'Good morning! Please give me today''s weather report and an inspirational quote.', NULL, TRUE, NOW(), NOW(), 0)

View File

@ -1245,163 +1245,13 @@ UPDATE mate_skill SET skill_content = '# Steve Jobs · 思维操作系统
read_skill_file references/ ' WHERE id = 1000000015;
-- ==================== 渠道种子数据 ====================
-- 参考 MateClaw 13 种渠道MateClaw 首批支持 6 种
-- Only the Web channel is seeded — see data-zh.sql for rationale.
-- 1. Web Console默认启用
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000001, 'Web 控制台', 'web', 1000000001, '', '{}', TRUE,
'默认 Web 控制台渠道,通过浏览器 SSE 流式交互', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 2. 钉钉(默认禁用,需配置 client_id/client_secret
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000002, '钉钉机器人', 'dingtalk', 1000000001, '', '{
"client_id": "",
"client_secret": "",
"robot_code": "",
"message_type": "markdown",
"card_template_id": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'钉钉机器人渠道。支持 Stream 回调和 sessionWebhook 回复,需在钉钉开放平台创建应用并配置 Webhook 地址为 /api/v1/channels/webhook/dingtalk', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 3. 飞书(默认禁用,需配置 app_id/app_secret
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000003, '飞书机器人', 'feishu', 1000000001, '', '{
"app_id": "",
"app_secret": "",
"encrypt_key": "",
"verification_token": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'飞书机器人渠道。支持事件订阅回调,需在飞书开放平台创建应用并配置事件回调地址为 /api/v1/channels/webhook/feishu', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 4. Telegram默认禁用需配置 bot_token
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000004, 'Telegram 机器人', 'telegram', 1000000001, '', '{
"bot_token": "",
"http_proxy": "",
"show_typing": true,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Telegram 机器人渠道。从 @BotFather 获取 Token配置 Webhook 地址为 /api/v1/channels/webhook/telegram国内需代理', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 5. Discord默认禁用需配置 bot_token
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000005, 'Discord 机器人', 'discord', 1000000001, '!mc ', '{
"bot_token": "",
"http_proxy": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Discord 机器人渠道。从 Discord Developer Portal 创建 Bot 并获取 Token群聊中使用 !mc 前缀触发', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 6. 企业微信智能机器人(默认禁用,需配置 bot_id/secret
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000006, '企业微信机器人', 'wecom', 1000000001, '', '{
"bot_id": "",
"secret": "",
"welcome_text": "",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto",
"max_reconnect_attempts": -1
}', FALSE,
'企业微信智能机器人渠道WebSocket 长连接)。在企业微信后台创建「智能机器人」→ 选择「API 模式 → 配置长连接」→ 获得 bot_id 和 secret 填入即可,无需公网 IP', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 7. QQ 机器人(默认禁用,需配置 app_id/client_secret
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000007, 'QQ 机器人', 'qq', 1000000001, '', '{
"app_id": "",
"client_secret": "",
"markdown_enabled": true,
"max_reconnect_attempts": 100,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'QQ 机器人渠道WebSocket 长连接)。前往 QQ 开放平台创建机器人应用,获取 AppID 和 AppSecret 填入即可,无需公网 IP', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 8. 微信个人号 iLink Bot默认禁用需扫码获取 bot_token
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000008, '微信', 'weixin', 1000000001, '', '{
"bot_token": "",
"base_url": "https://ilinkai.weixin.qq.com",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'微信个人号渠道iLink Bot HTTP 长轮询)。通过扫描二维码登录获取 bot_token或直接填入已有 token。基于 iLink Bot API支持文本、图片、语音ASR、文件、视频消息', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- 9. Slack默认禁用需配置 bot_token / app_token
INSERT INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
VALUES (1000000009, 'Slack 机器人', 'slack', 1000000001, '', '{
"bot_token": "",
"app_token": "",
"signing_secret": "",
"dm_policy": "open",
"group_policy": "mention",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Slack 渠道Socket Mode。在 Slack App 后台获取 Bot Tokenxoxb-)和 App-Level Tokenxapp-),启用 Socket Mode 后即可使用。', NOW(), NOW(), 0)
ON DUPLICATE KEY UPDATE name=VALUES(name), channel_type=VALUES(channel_type), agent_id=VALUES(agent_id), bot_prefix=VALUES(bot_prefix), config_json=VALUES(config_json), enabled=VALUES(enabled), description=VALUES(description), update_time=VALUES(update_time), deleted=VALUES(deleted);
-- ==================== 示例定时任务 ====================
INSERT INTO mate_cron_job (id, name, cron_expression, timezone, agent_id, task_type, trigger_message, request_body, enabled, create_time, update_time, deleted)
VALUES (1000100001, '每日问候', '0 9 * * *', 'Asia/Shanghai', 1000000001, 'text', '早上好!请给我今天的天气播报和一句励志名言。', NULL, TRUE, NOW(), NOW(), 0)

View File

@ -1208,163 +1208,18 @@ UPDATE mate_skill SET skill_content = '# Steve Jobs · 思维操作系统
read_skill_file references/ ' WHERE id = 1000000015;
-- ==================== 渠道种子数据 ====================
-- 参考 MateClaw 13 种渠道MateClaw 首批支持 6 种
-- Only the Web channel is seeded — it's always-on and needs no
-- credentials. Other channel types are added through the wizard
-- (ChannelTypePicker → ChannelOnboardingWizard) so the list page
-- doesn't start with 8 empty placeholders staring at the user.
-- See V64__cleanup_unused_channel_seeds.sql for the matching cleanup
-- of those placeholders on existing installs.
-- 1. Web Console默认启用
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000001, 'Web 控制台', 'web', 1000000001, '', '{}', TRUE,
'默认 Web 控制台渠道,通过浏览器 SSE 流式交互', NOW(), NOW(), 0);
-- 2. 钉钉(默认禁用,需配置 client_id/client_secret
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000002, '钉钉机器人', 'dingtalk', 1000000001, '', '{
"client_id": "",
"client_secret": "",
"robot_code": "",
"message_type": "markdown",
"card_template_id": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'钉钉机器人渠道。支持 Stream 回调和 sessionWebhook 回复,需在钉钉开放平台创建应用并配置 Webhook 地址为 /api/v1/channels/webhook/dingtalk', NOW(), NOW(), 0);
-- 3. 飞书(默认禁用,需配置 app_id/app_secret
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000003, '飞书机器人', 'feishu', 1000000001, '', '{
"app_id": "",
"app_secret": "",
"encrypt_key": "",
"verification_token": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'飞书机器人渠道。支持事件订阅回调,需在飞书开放平台创建应用并配置事件回调地址为 /api/v1/channels/webhook/feishu', NOW(), NOW(), 0);
-- 4. Telegram默认禁用需配置 bot_token
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000004, 'Telegram 机器人', 'telegram', 1000000001, '', '{
"bot_token": "",
"http_proxy": "",
"show_typing": true,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Telegram 机器人渠道。从 @BotFather 获取 Token配置 Webhook 地址为 /api/v1/channels/webhook/telegram国内需代理', NOW(), NOW(), 0);
-- 5. Discord默认禁用需配置 bot_token
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000005, 'Discord 机器人', 'discord', 1000000001, '!mc ', '{
"bot_token": "",
"http_proxy": "",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Discord 机器人渠道。从 Discord Developer Portal 创建 Bot 并获取 Token群聊中使用 !mc 前缀触发', NOW(), NOW(), 0);
-- 6. 企业微信智能机器人(默认禁用,需配置 bot_id/secret
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000006, '企业微信机器人', 'wecom', 1000000001, '', '{
"bot_id": "",
"secret": "",
"welcome_text": "",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto",
"max_reconnect_attempts": -1
}', FALSE,
'企业微信智能机器人渠道WebSocket 长连接)。在企业微信后台创建「智能机器人」→ 选择「API 模式 → 配置长连接」→ 获得 bot_id 和 secret 填入即可,无需公网 IP', NOW(), NOW(), 0);
-- 7. QQ 机器人(默认禁用,需配置 app_id/client_secret
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000007, 'QQ 机器人', 'qq', 1000000001, '', '{
"app_id": "",
"client_secret": "",
"markdown_enabled": true,
"max_reconnect_attempts": 100,
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"require_mention": false,
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'QQ 机器人渠道WebSocket 长连接)。前往 QQ 开放平台创建机器人应用,获取 AppID 和 AppSecret 填入即可,无需公网 IP', NOW(), NOW(), 0);
-- 8. 微信个人号 iLink Bot默认禁用需扫码获取 bot_token
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000008, '微信', 'weixin', 1000000001, '', '{
"bot_token": "",
"base_url": "https://ilinkai.weixin.qq.com",
"media_download_enabled": true,
"media_dir": "data/media",
"dm_policy": "open",
"group_policy": "open",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'微信个人号渠道iLink Bot HTTP 长轮询)。通过扫描二维码登录获取 bot_token或直接填入已有 token。基于 iLink Bot API支持文本、图片、语音ASR、文件、视频消息', NOW(), NOW(), 0);
-- 9. Slack默认禁用需配置 bot_token / app_token
MERGE INTO mate_channel (id, name, channel_type, agent_id, bot_prefix, config_json, enabled, description, create_time, update_time, deleted)
KEY (id)
VALUES (1000000009, 'Slack 机器人', 'slack', 1000000001, '', '{
"bot_token": "",
"app_token": "",
"signing_secret": "",
"dm_policy": "open",
"group_policy": "mention",
"allow_from": [],
"deny_message": "抱歉,您没有使用权限",
"filter_thinking": true,
"filter_tool_messages": true,
"message_format": "auto"
}', FALSE,
'Slack 渠道Socket Mode。在 Slack App 后台获取 Bot Tokenxoxb-)和 App-Level Tokenxapp-),启用 Socket Mode 后即可使用。', NOW(), NOW(), 0);
-- ==================== 示例定时任务 ====================
MERGE INTO mate_cron_job (id, name, cron_expression, timezone, agent_id, task_type, trigger_message, request_body, enabled, create_time, update_time, deleted)
KEY (id)

View File

@ -0,0 +1,26 @@
-- RFC-084 follow-up: clean up the 8 placeholder channel rows that older
-- seed scripts inserted for dingtalk / feishu / telegram / discord / wecom /
-- qq / weixin / slack. Those rows have been removed from data-*.sql, but
-- existing installs still carry them as id 1000000002..1000000009.
--
-- The predicate is conservative on three independent signals:
-- 1. id is in the known seed range (1000000002..1000000009)
-- 2. channel_type is one of the 8 placeholder types
-- 3. enabled = false (user never activated)
--
-- Hard-delete is fine here: no FK constraints on mate_channel, and a user
-- who actually used a placeholder would have flipped enabled=true (which
-- excludes them from this DELETE). An earlier soft-delete attempt with a
-- config_json LIKE filter ran but matched 0 rows, so this version drops
-- the LIKE and just removes the rows outright.
--
-- FlywayRepairConfig auto-fixes the checksum if this file changes again,
-- so no manual repair step is needed on installs that already ran an
-- earlier version of V64.
DELETE FROM mate_channel
WHERE id IN (1000000002, 1000000003, 1000000004, 1000000005,
1000000006, 1000000007, 1000000008, 1000000009)
AND channel_type IN ('dingtalk', 'feishu', 'telegram', 'discord',
'wecom', 'qq', 'weixin', 'slack')
AND enabled = FALSE;

View File

@ -0,0 +1,10 @@
-- RFC-084 follow-up: see h2/V64 for the rationale. MySQL accepts the
-- same DELETE directly — DELETE on no matching rows is a no-op, not an
-- error, so no INFORMATION_SCHEMA guard is needed.
DELETE FROM mate_channel
WHERE id IN (1000000002, 1000000003, 1000000004, 1000000005,
1000000006, 1000000007, 1000000008, 1000000009)
AND channel_type IN ('dingtalk', 'feishu', 'telegram', 'discord',
'wecom', 'qq', 'weixin', 'slack')
AND enabled = FALSE;

View File

@ -184,7 +184,14 @@
</div>
<div v-else-if="verifyResult?.ok" class="verify-card success">
<div class="verify-icon"></div>
<p class="verify-headline">{{ verifyResult.headline }}</p>
<!-- Frontend-localized success headline: backend's English
`verifyResult.headline` is intentionally not used here
(would leak English into Chinese builds). The failed
branch below still uses it, because diagnostic messages
from upstream APIs don't translate well. -->
<p class="verify-headline">
{{ t('channels.wizard.verifySuccessHeadline', { service: serviceName }) }}
</p>
<p v-if="verifyResult.durationMs" class="verify-detail">
{{ t('channels.wizard.durationMs', { n: verifyResult.durationMs }) }}
</p>
@ -670,7 +677,13 @@ function translateServiceName(type: string): string {
}
function formatIdentityKey(key: string): string {
// Turn camelCase keys into "Camel Case" for display.
// Look up the key's localized label in channels.wizard.identity.* first;
// when missing (e.g. a brand-new identity field a verifier just started
// returning, before i18n catches up), fall back to a camelCase-to-spaces
// conversion so the row still renders something readable.
const i18nKey = `channels.wizard.identity.${key}`
const translated = t(i18nKey)
if (translated !== i18nKey) return translated
return key
.replace(/([A-Z])/g, ' $1')
.replace(/^./, (s) => s.toUpperCase())

View File

@ -1795,6 +1795,11 @@ export default {
done: 'Done',
verifying: 'Verifying with {service}…',
verifySuccess: 'Connected',
// Used on Step 2 in place of the backend's English headline so the
// success line stays in the user's locale. Backend `headline` is
// still rendered on the failed path because diagnostic strings
// (errcodes, upstream error reasons) don't translate cleanly.
verifySuccessHeadline: 'Connected — {service} accepted the credentials',
verifyFailed: 'Verification failed',
verifySkipped: 'No live check needed',
verifySkippedDetail: "This channel type doesn't have credentials to verify. You can save and start it directly.",
@ -1809,6 +1814,26 @@ export default {
saveFailed: 'Could not save the channel',
noVerifierHint: 'No live check is available for {type}. Saving will start the channel; check the connection dot afterwards.',
oauthScanHint: 'After scanning, the credentials will be filled and verified automatically — you do not need to copy anything.',
// Identity field labels rendered on Step 3. Keys not listed here
// fall back to a camelCase-to-spaces conversion (formatIdentityKey),
// so adding a new identity field on a new verifier still renders
// — it just lacks the polished label until i18n catches up.
identity: {
accountId: 'Account ID',
accountName: 'Account',
firstName: 'First name',
team: 'Team',
teamId: 'Team ID',
botId: 'Bot ID',
transport: 'Transport',
region: 'Region',
tokenTtl: 'Token TTL',
baseUrl: 'Base URL',
isBot: 'Bot account',
verified: 'Verified',
canJoinGroups: 'Can join groups',
canReadAllGroupMessages: 'Reads all group messages',
},
},
},
skills: {

View File

@ -1805,6 +1805,7 @@ export default {
done: '完成',
verifying: '正在与 {service} 通信…',
verifySuccess: '连接成功',
verifySuccessHeadline: '已连接 — {service} 接受了凭证',
verifyFailed: '验证失败',
verifySkipped: '无需在线验证',
verifySkippedDetail: '该渠道类型没有需要验证的凭证,可以直接保存并启用。',
@ -1819,6 +1820,22 @@ export default {
saveFailed: '渠道保存失败',
noVerifierHint: '{type} 暂未支持在线验证。保存会直接启动渠道,请关注卡片上的连接状态指示。',
oauthScanHint: '扫码完成后会自动填充并验证凭证——你不需要手动复制任何东西。',
identity: {
accountId: '账号 ID',
accountName: '账号',
firstName: '名字',
team: '团队',
teamId: '团队 ID',
botId: '机器人 ID',
transport: '接入方式',
region: '地区',
tokenTtl: 'Token 有效期',
baseUrl: '接口地址',
isBot: '机器人账号',
verified: '已认证',
canJoinGroups: '可加入群聊',
canReadAllGroupMessages: '可读全部群消息',
},
},
},
skills: {