diff --git a/astrbot/dashboard/routes/platform.py b/astrbot/dashboard/routes/platform.py index 2b3a9c7f8..e30265858 100644 --- a/astrbot/dashboard/routes/platform.py +++ b/astrbot/dashboard/routes/platform.py @@ -3,6 +3,9 @@ 提供统一的 webhook 回调入口,支持多个平台使用同一端口接收回调。 """ +import secrets +import string + from quart import request from astrbot.core import logger @@ -25,6 +28,10 @@ from astrbot.core.platform.sources.weixin_oc.login_registration import ( from .route import Response, Route, RouteContext +def _random_platform_id_suffix() -> str: + return "_" + "".join(secrets.choice(string.ascii_lowercase) for _ in range(4)) + + class PlatformRoute(Route): """统一 Webhook 路由""" @@ -233,6 +240,8 @@ class PlatformRoute(Route): if not device_code: return Response().error("Missing device_code").__dict__, 400 result = await poll_dingtalk_app_registration_once(device_code) + if result.get("status") == "created": + result["platform_id_suffix"] = _random_platform_id_suffix() return Response().ok(result).__dict__ return Response().error(f"Unsupported action: {action}").__dict__, 400 @@ -269,6 +278,8 @@ class PlatformRoute(Route): platform_config=platform_config, qrcode=qrcode, ) + if result.get("status") == "created": + result["platform_id_suffix"] = _random_platform_id_suffix() return Response().ok(result).__dict__ return Response().error(f"Unsupported action: {action}").__dict__, 400 diff --git a/dashboard/src/components/platform/AddNewPlatform.vue b/dashboard/src/components/platform/AddNewPlatform.vue index f079b1a68..b5466a25c 100644 --- a/dashboard/src/components/platform/AddNewPlatform.vue +++ b/dashboard/src/components/platform/AddNewPlatform.vue @@ -961,16 +961,48 @@ export default { this.$emit('show-toast', { message: message, type: 'error' }); }, + buildRandomPlatformIdSuffix() { + const letters = 'abcdefghijklmnopqrstuvwxyz'; + let suffix = '_'; + for (let i = 0; i < 4; i += 1) { + suffix += letters[Math.floor(Math.random() * letters.length)]; + } + return suffix; + }, + handlePlatformRegistrationCreated(data) { - if (!this.selectedPlatformConfig || !data?.bot_name) { + if (!this.selectedPlatformConfig || !data) { return; } const currentId = String(this.selectedPlatformConfig.id || '').trim(); - const safeBotName = String(data.bot_name || '').trim().replace(/[!:]/g, '_'); - if (!currentId || !safeBotName) { + const platformType = this.selectedPlatformConfig.type; + if (!currentId) { return; } - const suffix = `-${safeBotName}`; + + let suffix = ''; + const explicitSuffix = String(data.platform_id_suffix || '').trim().replace(/[!:]/g, '_'); + if (explicitSuffix) { + suffix = explicitSuffix.startsWith('_') || explicitSuffix.startsWith('-') + ? explicitSuffix + : `_${explicitSuffix}`; + } else if (data.bot_name) { + const safeBotName = String(data.bot_name || '').trim().replace(/[!:]/g, '_'); + if (safeBotName) { + suffix = `-${safeBotName}`; + } + } else if (platformType === 'weixin_oc' || platformType === 'dingtalk') { + suffix = this.buildRandomPlatformIdSuffix(); + } + + if (!suffix) { + return; + } + + if ((platformType === 'weixin_oc' || platformType === 'dingtalk') && /_[a-z]{4}$/.test(currentId)) { + return; + } + this.selectedPlatformConfig.id = currentId.endsWith(suffix) ? currentId : `${currentId}${suffix}`;