import logging from datetime import datetime from yuxi.channel.extensions.weibo.types import InboundWeiboMessage logger = logging.getLogger(__name__) def parse_weibo_message(body: dict, app_key: str) -> InboundWeiboMessage: broad_type = body.get("type", "message") if broad_type == "event": msg_type = "event" sub_type = body.get("sub_type", "") event_key = body.get("event_key", "") else: msg_type = body.get("sub_type", "text") sub_type = "" event_key = "" sender_id = str(body.get("sender_id", "")) receiver_id = str(body.get("receiver_id", "")) text_content = body.get("text", "") msg_id = str(body.get("id", "")) create_time = _parse_created_at(body.get("created_at", "")) if not create_time: from datetime import datetime, timezone create_time = int(datetime.now(timezone.utc).timestamp()) pic_url = "" media_id = "" longitude = "" latitude = "" attachment = body.get("attachment", []) if attachment and isinstance(attachment, list): att = attachment[0] if attachment else {} if att.get("type") == "image": pic_url = att.get("url", "") media_id = att.get("tovfid", "") elif att.get("type") == "voice": media_id = att.get("tovfid", "") elif att.get("type") == "position": longitude = att.get("longitude", "") latitude = att.get("latitude", "") return InboundWeiboMessage( msg_id=msg_id, msg_type=msg_type, sender_id=sender_id, receiver_id=receiver_id, sub_type=sub_type, event_key=event_key, create_time=create_time, content=text_content, pic_url=pic_url, media_id=media_id, longitude=longitude, latitude=latitude, raw_json=body, ) def extract_content(raw_msg: InboundWeiboMessage) -> str: msg_type = raw_msg.msg_type if msg_type == "text": return raw_msg.content or "" if msg_type == "image": return "[图片消息]" if msg_type == "voice": return "[语音消息]" if msg_type == "position": lon = raw_msg.longitude or "未知" lat = raw_msg.latitude or "未知" return f"[位置消息] 经度:{lon} 纬度:{lat}" if msg_type == "event": sub = raw_msg.sub_type if sub == "follow": return "[关注事件]" if sub == "unfollow": return "[取关事件]" if sub == "subscribe": return "[订阅事件]" if sub == "unsubscribe": return "[取消订阅事件]" if sub == "click": key = raw_msg.event_key or "未指定" return f"[菜单点击: {key}]" if sub == "scan": key = raw_msg.event_key or "未指定" ticket = raw_msg.raw_json.get("ticket", "") return f"[扫码事件] key={key}" + (f" ticket={ticket}" if ticket else "") if sub == "scan_follow": key = raw_msg.event_key or "未指定" return f"[扫码关注] key={key}" if sub == "masssend": status = raw_msg.raw_json.get("status", "") msg_id = raw_msg.raw_json.get("msg_id", "") return f"[群发结果] status={status} msg_id={msg_id}" return f"[事件: {sub}]" if msg_type == "mention": mention_text = raw_msg.raw_json.get("text", "") return f"[@消息] {mention_text}" return raw_msg.content or "" def _parse_created_at(created_at: str) -> int: if not created_at: return 0 try: dt = datetime.strptime(created_at, "%a %b %d %H:%M:%S %z %Y") return int(dt.timestamp()) except ValueError: pass try: dt = datetime.strptime(created_at, "%Y-%m-%dT%H:%M:%S%z") return int(dt.timestamp()) except ValueError: logger.warning("Failed to parse created_at: %s", created_at) return 0