from __future__ import annotations from enum import StrEnum CHAT_ID_PREFIX_DM = "dingding:dm:" CHAT_ID_PREFIX_GROUP = "dingding:group:" CHAT_ID_PREFIX_THREAD = "dingding:thread:" CHAT_ID_PREFIX_GROUP_SENDER = "dingding:group_sender:" class SessionScope(StrEnum): DIRECT = "dm" GROUP = "group" GROUP_SENDER = "group_sender" TOPIC = "topic" class SessionMode(StrEnum): RAW = "raw" CHAT_RAW = "chat_raw" CHAT_RESOLVE = "chat_resolve" def generate_dingding_chat_id( raw: dict, chat_type: str, *, sender_id: str | None = None, scope: str = "group", ) -> str: raw_sender_id = sender_id or raw.get("senderId", "") if chat_type == "direct": return f"dm_{raw_sender_id}" conversation_id = raw.get("conversationId", "") if scope == "group_sender" and raw_sender_id: return f"{CHAT_ID_PREFIX_GROUP_SENDER}{conversation_id}:{raw_sender_id}" return f"group_{conversation_id}" def resolve_dingding_chat_type(raw: dict) -> str: is_group = raw.get("isGroupChat", False) return "group" if is_group else "direct" def generate_thread_key(channel_id: str, chat_id: str, *, scope: str = "group") -> str: if chat_id.startswith("dm_"): return f"{channel_id}:direct:{chat_id}" if scope == "group_sender": return f"{channel_id}:group_sender:{chat_id}" return f"{channel_id}:group:{chat_id}" def normalize_chat_id(chat_id: str) -> str: if chat_id.startswith("dingding:") or chat_id.startswith("dm_") or chat_id.startswith("group_"): return chat_id if chat_id.startswith("group_sender_"): return f"{CHAT_ID_PREFIX_GROUP_SENDER}{chat_id}" return f"{CHAT_ID_PREFIX_GROUP}{chat_id}" def resolve_session_scope(chat_id: str) -> str: if chat_id.startswith("dm_"): return SessionScope.DIRECT if CHAT_ID_PREFIX_GROUP_SENDER in chat_id: return SessionScope.GROUP_SENDER return SessionScope.GROUP def parse_chat_id(chat_id: str) -> dict[str, str]: if chat_id.startswith("dm_"): return {"type": "direct", "open_id": chat_id[3:]} if chat_id.startswith("group_"): return {"type": "group", "open_conversation_id": chat_id[6:]} if CHAT_ID_PREFIX_GROUP_SENDER in chat_id: parts = chat_id.split(":") if len(parts) >= 3: return {"type": "group_sender", "group_id": parts[-2], "sender_id": parts[-1]} return {"type": "unknown", "raw": chat_id}