新增 Mattermost 渠道完整实现,包含适配器核心、消息处理、交互回调、命令支持、安全校验、多账号管理等功能,支持机器人消息发送、交互按钮、命令注册、投票功能以及配置动态修改等特性。
92 lines
2.7 KiB
Python
92 lines
2.7 KiB
Python
from __future__ import annotations
|
||
|
||
import asyncio
|
||
from typing import Any
|
||
|
||
from yuxi.utils.logging_config import logger
|
||
|
||
from .slash import (
|
||
SlashCommandConfig,
|
||
build_command_payload,
|
||
get_supported_commands,
|
||
)
|
||
|
||
|
||
async def register_slash_commands_across_teams(
|
||
driver: Any,
|
||
bot_user_id: str,
|
||
callback_url: str = "",
|
||
auto_register: bool = False,
|
||
) -> list[dict[str, Any]]:
|
||
"""跨所有 Teams 自动注册 Slash Commands。
|
||
|
||
遍历 Bot 所属的所有 Team,为每个 Team 注册预定义的 Slash Commands。
|
||
返回注册结果列表。
|
||
"""
|
||
if not auto_register:
|
||
return []
|
||
|
||
if not driver:
|
||
return []
|
||
|
||
commands = get_supported_commands()
|
||
if not commands:
|
||
return []
|
||
|
||
try:
|
||
teams = driver.teams.get_user_teams(user_id=bot_user_id)
|
||
except Exception as e:
|
||
logger.error(f"[Mattermost] Failed to list teams for slash command registration: {e}")
|
||
return []
|
||
|
||
results: list[dict[str, Any]] = []
|
||
|
||
for team in teams:
|
||
team_id = team.get("id", "")
|
||
team_name = team.get("display_name", team.get("name", ""))
|
||
|
||
try:
|
||
existing = driver.commands.list_custom_commands(team_id=team_id)
|
||
existing_triggers = {cmd.get("trigger", "") for cmd in existing}
|
||
except Exception:
|
||
existing_triggers = set()
|
||
|
||
for cmd in commands:
|
||
trigger = cmd.command.lstrip("/")
|
||
if trigger in existing_triggers:
|
||
continue
|
||
|
||
try:
|
||
payload = build_command_payload(cmd, team_id, callback_url)
|
||
driver.commands.create_custom_command(team_id=team_id, options=payload)
|
||
results.append(
|
||
{
|
||
"team_id": team_id,
|
||
"team_name": team_name,
|
||
"command": cmd.command,
|
||
"status": "registered",
|
||
}
|
||
)
|
||
except Exception as e:
|
||
logger.warning(f"[Mattermost] Failed to register command '{cmd.command}' in team '{team_name}': {e}")
|
||
results.append(
|
||
{
|
||
"team_id": team_id,
|
||
"team_name": team_name,
|
||
"command": cmd.command,
|
||
"status": "failed",
|
||
"error": str(e),
|
||
}
|
||
)
|
||
|
||
await asyncio.sleep(0.2)
|
||
|
||
registered_count = sum(1 for r in results if r.get("status") == "registered")
|
||
logger.info(f"[Mattermost] Slash command registration complete: {registered_count}/{len(results)} registered")
|
||
|
||
return results
|
||
|
||
|
||
def get_command_config(config: dict) -> SlashCommandConfig:
|
||
return SlashCommandConfig.from_config(config)
|