ForcePilot/backend/package/yuxi/channels/adapters/yuanbao/setup.py
Kris 1f78c44b03 refactor: 整理并清理项目中的冗余代码与格式问题
这是一个批量整理提交,包含以下主要改动:
1.  删除多处冗余的空行和未使用的导入
2.  修复文件末尾缺少换行符的问题
3.  调整部分模块的导入顺序与代码排版
4.  修复部分配置默认值与策略逻辑
5.  新增多个功能模块与辅助工具
6.  完善异常处理与日志记录
7.  修复速率限制、消息缓存、权限校验等逻辑bug
8.  废弃部分旧有API与配置项并添加警告提示
2026-05-12 14:51:53 +08:00

164 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from dataclasses import dataclass, field
from yuxi.utils.logging_config import logger
@dataclass
class SetupStepResult:
step: str
success: bool
message: str = ""
data: dict | None = None
@dataclass
class SetupWizardResult:
app_key: str
app_secret: str
bot_app_id: str
verified: bool = False
error: str | None = None
bot_info: dict | None = None
steps: list[SetupStepResult] = field(default_factory=list)
def add_step(self, step: str, success: bool, message: str = "", data: dict | None = None) -> None:
self.steps.append(SetupStepResult(step=step, success=success, message=message, data=data))
async def run_setup_wizard(
token_manager,
http_client,
app_key: str,
app_secret: str,
bot_app_id: str = "",
) -> SetupWizardResult:
result = SetupWizardResult(
app_key=app_key,
app_secret=app_secret,
bot_app_id=bot_app_id,
)
if not app_key.strip() or not app_secret.strip():
result.error = "app_key 和 app_secret 不能为空"
result.add_step("input_validation", False, result.error)
return result
result.add_step("input_validation", True, "输入参数校验通过")
try:
import time
import hashlib
import hmac
import aiohttp
timestamp = int(time.time())
message = f"{app_key}{timestamp}"
signature = hmac.new(
app_secret.encode("utf-8"),
message.encode("utf-8"),
hashlib.sha256,
).hexdigest()
api_base = "https://open-api.yuanbao.tencent.com"
async with aiohttp.ClientSession() as session:
async with session.post(
f"{api_base}/api/auth/token",
json={
"app_key": app_key,
"timestamp": timestamp,
"signature": signature,
},
timeout=aiohttp.ClientTimeout(total=10),
) as resp:
if resp.status != 200:
result.error = f"认证失败: HTTP {resp.status}"
result.add_step("auth", False, result.error)
return result
token_data = await resp.json()
token = token_data.get("access_token", "")
expires_in = token_data.get("expires_in", 7200)
result.add_step("auth", True, f"认证成功token 有效期 {expires_in}s")
headers = {"Authorization": f"Bearer {token}"}
async with session.get(
f"{api_base}/api/v1/bot/info",
headers=headers,
timeout=aiohttp.ClientTimeout(total=10),
) as resp:
if resp.status == 200:
bot_info = await resp.json()
result.verified = True
result.bot_info = bot_info
result.bot_app_id = bot_info.get("bot_app_id", bot_app_id)
result.add_step(
"bot_verify",
True,
f"Bot 验证成功: {result.bot_app_id}",
bot_info,
)
logger.info(f"[Yuanbao] Setup wizard verified: bot_app_id={result.bot_app_id}")
elif resp.status in (401, 403):
result.error = "凭据验证失败,请检查 app_key 和 app_secret"
result.add_step("bot_verify", False, result.error)
else:
result.error = f"Bot 信息获取失败: HTTP {resp.status}"
result.add_step("bot_verify", False, result.error)
except Exception as e:
result.error = f"设置向导出错: {e}"
result.add_step("unexpected_error", False, result.error)
logger.error(f"[Yuanbao] Setup wizard error: {e}")
return result
def generate_config_snippet(app_key: str, app_secret: str, bot_app_id: str) -> str:
return f"""```yaml
channels:
yuanbao:
enabled: true
app_key: "{app_key}"
app_secret: "{app_secret}"
bot_app_id: "{bot_app_id}"
dm_policy: pairing
# 群聊中需要 @机器人 才响应(仅群组生效)
requireMention: true
overflowPolicy: split
replyToMode: first
```"""
def generate_config_snippet_with_accounts(
app_key: str,
app_secret: str,
bot_app_id: str,
accounts: list[dict] | None = None,
) -> str:
accounts_config = ""
if accounts:
for acct in accounts:
accounts_config += f"""
accounts.{acct["id"]}:
appKey: "{acct.get("app_key", "")}"
appSecret: "{acct.get("app_secret", "")}"
name: "{acct.get("name", acct["id"])}"
enabled: true"""
return f"""```yaml
channels:
yuanbao:
enabled: true
app_key: "{app_key}"
app_secret: "{app_secret}"
bot_app_id: "{bot_app_id}"
dm_policy: pairing
# 群聊中需要 @机器人 才响应(仅群组生效)
requireMention: true
overflowPolicy: split
replyToMode: first
defaultAccount: "default"{accounts_config}
```"""