from __future__ import annotations import logging from datetime import datetime, UTC from yuxi.channel.extensions.zalo.types import ZaloAccount, ZaloMessage logger = logging.getLogger(__name__) def parse_update_to_unified(update: dict, account: ZaloAccount | dict) -> dict | None: event_name = update.get("event_name", "") message = update.get("message", {}) if not message: logger.debug("Zalo update without message field, skipping") return None sender = message.get("from", {}) if sender.get("is_bot"): logger.debug("Zalo skipping bot message from %s", sender.get("id")) return None chat = message.get("chat", {}) zm = ZaloMessage( event_name=event_name, message_id=message.get("message_id", ""), from_id=sender.get("id", ""), from_name=sender.get("name", ""), from_display_name=sender.get("display_name", sender.get("name", "")), from_avatar=sender.get("avatar", ""), chat_id=chat.get("id", ""), chat_type=chat.get("chat_type", "PRIVATE"), date=message.get("date", 0), text=message.get("text", ""), photo_url=message.get("photo", ""), caption=message.get("caption", ""), ) return _build_unified_message(zm, account, message) def parse_updates_to_unified(updates: list[dict], account: ZaloAccount | dict) -> list[dict]: results = [] for update in updates: unified = parse_update_to_unified(update, account) if unified: results.append(unified) return results def _build_unified_message(zm: ZaloMessage, account: ZaloAccount | dict, message: dict) -> dict | None: account_id = account.get("account_id", "default") if isinstance(account, dict) else account.account_id event_name = zm.event_name if event_name == "message.text.received": message_type = "TEXT" content = zm.text elif event_name == "message.image.received": message_type = "IMAGE" content = zm.caption or "[图片]" elif event_name == "message.sticker.received": message_type = "STICKER" sticker_id = message.get("sticker", "") content = f"[贴纸 {sticker_id}]" elif event_name == "message.unsupported.received": logger.debug("Zalo unsupported message received, skipping") return None else: logger.debug("Zalo unknown event: %s, skipping", event_name) return None is_group = zm.chat_type == "GROUP" timestamp = None if zm.date: timestamp = datetime.fromtimestamp(zm.date, tz=UTC) media_urls = [zm.photo_url] if zm.photo_url else [] if message_type == "STICKER": sticker_url = message.get("url", "") if sticker_url: media_urls.append(sticker_url) return { "msg_id": zm.message_id, "channel_type": "zalo", "account_id": account_id, "content": content, "message_type": message_type, "media_urls": media_urls, "sender": { "id": zm.from_id, "display_name": zm.from_display_name or zm.from_name, "kind": "GROUP" if is_group else "DIRECT", }, "group": {"id": zm.chat_id} if is_group else None, "timestamp": timestamp, "mentioned_ids": [], "reply_to_id": None, "raw_payload": { "event_name": event_name, "text": zm.text, "photo_url": zm.photo_url, "caption": zm.caption, }, }