ForcePilot/backend/package/yuxi/channels/adapters/matrix/direct_room.py
Kris 2063145ce1 feat(matrix): 新增完整的Matrix适配器工具集
新增了20+个Matrix相关工具模块,包含线程处理、自动加入、消息去重、配置管理、安全策略、媒体处理、命令解析等功能,完善Matrix适配器基础能力
2026-05-12 00:45:54 +08:00

122 lines
3.6 KiB
Python

from __future__ import annotations
from typing import TYPE_CHECKING
from yuxi.utils.logging_config import logger
if TYPE_CHECKING:
from nio import AsyncClient
_DIRECT_ROOM_TYPE = "m.direct"
async def inspect_direct_room(
client: AsyncClient,
room_id: str,
) -> dict:
try:
members_resp = await client.joined_members(room_id)
members = getattr(members_resp, "members", [])
name_resp = await client.room_get_state_event(room_id, "m.room.name")
name = getattr(name_resp, "name", "") if name_resp else ""
join_rules = await client.room_get_state_event(room_id, "m.room.join_rules")
rule = getattr(join_rules, "join_rule", "") if join_rules else ""
return {
"room_id": room_id,
"name": name,
"member_count": len(members),
"join_rule": rule,
"is_direct": _is_direct_room(client, room_id),
}
except Exception as e:
logger.debug(f"Matrix direct room inspect failed for {room_id}: {e}")
return {"room_id": room_id, "error": str(e)}
async def repair_direct_room(
client: AsyncClient,
room_id: str,
target_user_id: str,
) -> dict:
try:
await client.room_set_account_data(
room_id=room_id,
event_type="m.direct",
content={"room_id": room_id, "user_id": target_user_id},
)
return {
"status": "repaired",
"room_id": room_id,
"user_id": target_user_id,
"action": "set_account_data_m.direct",
}
except Exception as e:
logger.error(f"Matrix direct room repair failed for {room_id}: {e}")
return {"status": "error", "room_id": room_id, "error": str(e)}
async def promote_room_to_direct(
client: AsyncClient,
room_id: str,
user_id: str,
) -> dict:
try:
direct_rooms = await client.get_account_data(_DIRECT_ROOM_TYPE)
current = getattr(direct_rooms, "content", {}) if direct_rooms else {}
current.setdefault(user_id, [])
if room_id not in current[user_id]:
current[user_id].append(room_id)
await client.set_account_data(_DIRECT_ROOM_TYPE, current)
return {
"status": "promoted",
"room_id": room_id,
"user_id": user_id,
}
except Exception as e:
logger.error(f"Matrix promote to direct room failed: {e}")
return {"status": "error", "error": str(e)}
async def demote_direct_room(
client: AsyncClient,
room_id: str,
user_id: str,
) -> dict:
try:
direct_rooms = await client.get_account_data(_DIRECT_ROOM_TYPE)
current = getattr(direct_rooms, "content", {}) if direct_rooms else {}
if user_id in current and room_id in current[user_id]:
current[user_id].remove(room_id)
if not current[user_id]:
del current[user_id]
await client.set_account_data(_DIRECT_ROOM_TYPE, current)
return {"status": "demoted", "room_id": room_id, "user_id": user_id}
except Exception as e:
logger.error(f"Matrix demote direct room failed: {e}")
return {"status": "error", "error": str(e)}
def _is_direct_room(client: AsyncClient, room_id: str) -> bool:
try:
account_data = client.account_data if client else {}
if account_data:
direct_data = account_data.get("m.direct", {})
if isinstance(direct_data, dict):
for room_ids in direct_data.values():
if isinstance(room_ids, list) and room_id in room_ids:
return True
except Exception:
pass
return False