新增 Mattermost 渠道完整实现,包含适配器核心、消息处理、交互回调、命令支持、安全校验、多账号管理等功能,支持机器人消息发送、交互按钮、命令注册、投票功能以及配置动态修改等特性。
110 lines
3.9 KiB
Python
110 lines
3.9 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
@dataclass
|
|
class MattermostAccount:
|
|
account_id: str
|
|
server_url: str = ""
|
|
bot_token: str = ""
|
|
nick: str = "ForcePilot"
|
|
username: str = ""
|
|
realname: str = ""
|
|
channels: list[str] = field(default_factory=list)
|
|
nickserv_password: str = ""
|
|
nickserv_register_email: str = ""
|
|
enabled: bool = True
|
|
|
|
@property
|
|
def configured(self) -> bool:
|
|
return bool(self.server_url and self.bot_token)
|
|
|
|
@classmethod
|
|
def from_config_entry(cls, account_id: str, entry: dict) -> MattermostAccount:
|
|
return cls(
|
|
account_id=account_id,
|
|
server_url=entry.get("server_url", "") or entry.get("host", ""),
|
|
bot_token=entry.get("bot_token", "") or entry.get("token", ""),
|
|
nick=entry.get("nick", "ForcePilot"),
|
|
username=entry.get("username", ""),
|
|
realname=entry.get("realname", ""),
|
|
channels=entry.get("channels", []),
|
|
nickserv_password=entry.get("nickserv_password", ""),
|
|
nickserv_register_email=entry.get("nickserv_register_email", ""),
|
|
enabled=entry.get("enabled", True),
|
|
)
|
|
|
|
|
|
DEFAULT_ACCOUNT_ID = "default"
|
|
|
|
|
|
@dataclass
|
|
class MultiAccountConfig:
|
|
accounts: dict[str, MattermostAccount] = field(default_factory=dict)
|
|
default_account_id: str = DEFAULT_ACCOUNT_ID
|
|
|
|
@classmethod
|
|
def from_config(cls, config: dict) -> MultiAccountConfig:
|
|
accounts_data = config.get("accounts", {})
|
|
if not accounts_data:
|
|
account = MattermostAccount.from_config_entry(
|
|
DEFAULT_ACCOUNT_ID,
|
|
{
|
|
"server_url": config.get("server_url", ""),
|
|
"bot_token": config.get("bot_token", ""),
|
|
"nick": config.get("nick", "ForcePilot"),
|
|
"username": config.get("username", ""),
|
|
"realname": config.get("realname", ""),
|
|
"channels": config.get("channels", []),
|
|
"nickserv_password": config.get("nickserv_password", ""),
|
|
"nickserv_register_email": config.get("nickserv_register_email", ""),
|
|
"enabled": True,
|
|
},
|
|
)
|
|
return cls(accounts={DEFAULT_ACCOUNT_ID: account}, default_account_id=DEFAULT_ACCOUNT_ID)
|
|
|
|
accounts = {}
|
|
for aid, entry in accounts_data.items():
|
|
accounts[aid] = MattermostAccount.from_config_entry(aid, entry)
|
|
|
|
default_id = config.get("default_account_id", DEFAULT_ACCOUNT_ID)
|
|
if default_id not in accounts and accounts:
|
|
default_id = next(iter(accounts))
|
|
|
|
return cls(accounts=accounts, default_account_id=default_id)
|
|
|
|
def resolve_account(self, account_id: str | None = None) -> MattermostAccount | None:
|
|
if account_id and account_id in self.accounts:
|
|
return self.accounts[account_id]
|
|
if self.default_account_id in self.accounts:
|
|
return self.accounts[self.default_account_id]
|
|
return None
|
|
|
|
def list_account_ids(self) -> list[str]:
|
|
return list(self.accounts.keys())
|
|
|
|
def list_configured_accounts(self) -> list[MattermostAccount]:
|
|
return [a for a in self.accounts.values() if a.configured and a.enabled]
|
|
|
|
|
|
def merge_config(
|
|
top_level: dict,
|
|
account_config: dict,
|
|
) -> dict:
|
|
merged = {**top_level, **account_config}
|
|
|
|
top_commands = top_level.get("commands", {})
|
|
account_commands = account_config.get("commands", {})
|
|
|
|
if top_commands or account_commands:
|
|
merged["commands"] = {**top_commands, **account_commands}
|
|
|
|
top_interactions = top_level.get("interactions", {})
|
|
account_interactions = account_config.get("interactions", {})
|
|
|
|
if top_interactions or account_interactions:
|
|
merged["interactions"] = {**top_interactions, **account_interactions}
|
|
|
|
return merged
|