ForcePilot/backend/package/yuxi/channels/adapters/whatsapp/message_actions.py
Kris 1f78c44b03 refactor: 整理并清理项目中的冗余代码与格式问题
这是一个批量整理提交,包含以下主要改动:
1.  删除多处冗余的空行和未使用的导入
2.  修复文件末尾缺少换行符的问题
3.  调整部分模块的导入顺序与代码排版
4.  修复部分配置默认值与策略逻辑
5.  新增多个功能模块与辅助工具
6.  完善异常处理与日志记录
7.  修复速率限制、消息缓存、权限校验等逻辑bug
8.  废弃部分旧有API与配置项并添加警告提示
2026-05-12 14:51:53 +08:00

187 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from typing import Any
WHATSAPP_MESSAGE_ACTIONS: dict[str, dict[str, Any]] = {
"send": {
"status": "implemented",
"description": "发送文本消息,支持 Markdown 转换和长文本自动分块",
"api": "sendMessage",
},
"sendAttachment": {
"status": "implemented",
"description": "发送图片/视频/音频/文件/贴纸,通过 DSM API 上传",
"api": "sendMessage + media",
},
"sendPoll": {
"status": "implemented",
"description": "创建投票(最多 12 选项),基于 Baileys poll 原生支持",
"api": "sendMessage + poll",
},
"sendSticker": {
"status": "implemented",
"description": "发送贴纸,通过专用 API 发送 WebP 格式贴纸",
"api": "sendSticker",
},
"sendLocation": {
"status": "implemented",
"description": "发送地理位置消息,支持经纬度和地点名称",
"api": "sendLocation",
},
"sendContact": {
"status": "implemented",
"description": "发送联系人名片,支持 vCard 格式",
"api": "sendContact",
},
"reply": {
"status": "implemented",
"description": "引用回复消息,通过 reply_to 参数绑定",
"api": "sendMessage + context",
},
"edit": {
"status": "unsupported",
"description": "WhatsApp 不支持消息编辑",
"api": "N/A",
},
"delete": {
"status": "implemented",
"description": "通过 Baileys Bridge revoke 实现消息删除",
"api": "sendMessage + delete",
},
"react": {
"status": "implemented",
"description": "发送 emoji 反应消息",
"api": "sendReaction",
},
"pin": {
"status": "unsupported",
"description": "WhatsApp 不支持消息置顶",
"api": "N/A",
},
"unpin": {
"status": "unsupported",
"description": "WhatsApp 不支持取消置顶",
"api": "N/A",
},
"broadcast": {
"status": "unsupported",
"description": "群发消息WhatsApp 限制较多,暂未实现",
"api": "N/A",
},
"typing": {
"status": "implemented",
"description": "发送 '正在输入' 指示",
"api": "markAsRead + typing indicator",
},
"streamChunk": {
"status": "implemented",
"description": "流式输出块,通过 typing indicator + 最终发送实现",
"api": "sendMessage (streaming via edit)",
},
"thread": {
"status": "unsupported",
"description": "WhatsApp 不支持线程",
"api": "N/A",
},
"kick": {
"status": "unsupported",
"description": "WhatsApp 不支持踢人(仅 Cloud API 群管理支持)",
"api": "N/A (Cloud API group admin)",
},
"ban": {
"status": "unsupported",
"description": "WhatsApp 不支持封禁",
"api": "N/A",
},
"mute": {
"status": "unsupported",
"description": "WhatsApp 不支持禁言",
"api": "N/A",
},
"leave": {
"status": "unsupported",
"description": "Bot 不支持主动退群",
"api": "N/A",
},
"addParticipant": {
"status": "unsupported",
"description": "WhatsApp 不支持通过 Bot 添加成员",
"api": "N/A",
},
"removeParticipant": {
"status": "unsupported",
"description": "WhatsApp 不支持通过 Bot 移除成员",
"api": "N/A",
},
"downloadFile": {
"status": "implemented",
"description": "下载媒体文件",
"api": "retrieveMediaUrl + download",
},
"uploadFile": {
"status": "implemented",
"description": "上传媒体文件",
"api": "uploadMedia + sendMessage",
},
"getContact": {
"status": "implemented",
"description": "获取联系人信息",
"api": "contact lookup",
},
}
_WHATSAPP_ACTION_MAPPING: dict[str, str] = {
"send": "send",
"sendAttachment": "send_attachment",
"sendPoll": "create_poll",
"sendSticker": "send_sticker",
"sendLocation": "send_location",
"sendContact": "send_contact",
"reply": "reply",
"edit": "edit",
"delete": "delete",
"react": "react",
"pin": "pin",
"unpin": "unpin",
"broadcast": "broadcast",
"streamChunk": "stream",
"thread": "thread_create",
"kick": "kick",
"ban": "ban",
"mute": "mute",
"leave": "leave_group",
"addParticipant": "add_participant",
"removeParticipant": "remove_participant",
"downloadFile": "download_file",
"uploadFile": "upload_file",
"getContact": "member_info",
}
def register_whatsapp_actions() -> None:
from yuxi.channels.message_actions import ActionDeclaration, ActionRegistry, ActionStatus, MessageAction
declarations: dict[MessageAction, ActionDeclaration] = {}
for action_name, info in WHATSAPP_MESSAGE_ACTIONS.items():
mapped = _WHATSAPP_ACTION_MAPPING.get(action_name)
if mapped is None:
continue
try:
action_enum = MessageAction(mapped)
except ValueError:
continue
status_str = info.get("status", "unsupported")
status = {
"implemented": ActionStatus.SUPPORTED,
"planned": ActionStatus.PARTIAL,
"unsupported": ActionStatus.UNSUPPORTED,
}.get(status_str, ActionStatus.UNSUPPORTED)
declarations[action_enum] = ActionDeclaration(
action=action_enum,
status=status,
reason=info.get("description", ""),
impl=info.get("api", ""),
)
ActionRegistry.register_channel_actions("whatsapp", declarations)