import logging import xml.etree.ElementTree as ET from yuxi.channel.extensions.wecom.types import InboundWeComMessage logger = logging.getLogger(__name__) def parse_xml_to_message(xml_text: str) -> InboundWeComMessage: root = ET.fromstring(xml_text) def _text(tag: str) -> str: el = root.find(tag) return (el.text or "").strip() if el is not None else "" def _int(tag: str, default: int = 0) -> int: try: return int(_text(tag)) except (ValueError, TypeError): return default msg_type = _text("MsgType") msg = InboundWeComMessage( msg_id=_text("MsgId"), msg_type=msg_type, from_user=_text("FromUserName"), to_user=_text("ToUserName"), create_time=_int("CreateTime"), agent_id=_int("AgentID"), chat_type=_text("ChatType") or "single", chat_id=_text("ChatId"), content=_text("Content"), pic_url=_text("PicUrl"), media_id=_text("MediaId"), event=_text("Event"), event_key=_text("EventKey"), raw_xml={el.tag: (el.text or "").strip() for el in root}, ) logger.debug( "Parsed WeCom msg: type=%s chat=%s from=%s msgid=%s", msg.msg_type, msg.chat_type, msg.from_user, msg.msg_id, ) return msg def extract_content(msg: InboundWeComMessage) -> str: if msg.msg_type == "text": return msg.content if msg.msg_type == "voice": return msg.media_id if msg.msg_type == "image": return msg.media_id or msg.pic_url if msg.msg_type == "event": return f"event:{msg.event}" if msg.msg_type == "video": return msg.media_id or f"video:{msg.msg_id}" if msg.msg_type == "file": return msg.media_id or f"file:{msg.msg_id}" if msg.msg_type == "location": return f"location:{msg.content}" if msg.msg_type == "link": return f"link:{msg.content}" return ""