import re from yuxi.channel.message.models import UnifiedMessage, PeerInfo, GroupContext from yuxi.channel.routing.models import PeerKind from yuxi.channel.extensions.webex.types import WebexMessage def payload_to_unified_message( webex_msg: WebexMessage, bot_person_id: str, account_id: str, ) -> UnifiedMessage | None: if webex_msg.person_id == bot_person_id: return None content = webex_msg.text or _extract_text_from_markdown(webex_msg.markdown) if not content and not webex_msg.files: return None was_mentioned = any(m.get("personId") == bot_person_id for m in webex_msg.mentions) msg_id = f"webex:{webex_msg.id}" sender = PeerInfo( kind=PeerKind.DIRECT if webex_msg.room_type == "direct" else PeerKind.GROUP, id=webex_msg.person_id, display_name=webex_msg.person_email, ) group = None if webex_msg.room_type == "group": group = GroupContext(id=webex_msg.room_id, kind="group") media_urls = webex_msg.files if webex_msg.files else [] return UnifiedMessage( msg_id=msg_id, channel_type="webex", account_id=account_id, content=content, sender=sender, group=group, was_mentioned=was_mentioned, reply_to_id=webex_msg.parent_id, media_urls=media_urls, raw_payload=webex_msg.raw, metadata={ "room_id": webex_msg.room_id, "room_type": webex_msg.room_type, "person_email": webex_msg.person_email, "debounce_key": f"webex:{webex_msg.person_id}:{webex_msg.room_id}", }, conversation_label=f"webex:{webex_msg.room_id}", native_direct_user_id=webex_msg.person_id, ) def _extract_text_from_markdown(md: str) -> str: if not md: return "" txt = md txt = re.sub(r"\*\*(.+?)\*\*", r"\1", txt) txt = re.sub(r"\*(.+?)\*", r"\1", txt) txt = re.sub(r"#{1,6}\s+", "", txt) return txt.strip()