ForcePilot/backend/package/yuxi/channels/adapters/mattermost/slash_commands.py

94 lines
2.8 KiB
Python
Raw Normal View History

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,
)
SLASH_COMMAND_TEAM_DELAY_S = 0.2
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(SLASH_COMMAND_TEAM_DELAY_S)
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)