ForcePilot/backend/package/yuxi/channels/adapters/telegram/message_actions.py
Kris 71fec609bb feat(telegram-adapter): 实现完整的Telegram适配器基础代码
新增了Telegram适配器的全套基础模块,包括:
1.  核心适配器入口与会话工具
2.  账号管理、认证与配置系统
3.  连接相关的轮询、Webhook、更新偏移管理
4.  话题路由、管理与缓存系统
5.  消息反抖动、超时配置与工具类
6.  响应式UI与命令交互系统
7.  反应表情与通知系统
8.  审批与安全审计模块
9.  健康检查与状态监控
10. 贴纸缓存与视觉工具
11. 流式响应与协作功能
12. 群组迁移与目标归一化处理
2026-05-12 00:49:52 +08:00

368 lines
11 KiB
Python

from __future__ import annotations
from typing import Any
TELEGRAM_MESSAGE_ACTIONS: dict[str, dict[str, Any]] = {
"send": {
"status": "implemented",
"description": "发送消息到指定聊天",
"api": "sendMessage",
},
"sendAttachment": {
"status": "implemented",
"description": "发送图片/视频/音频/文件/语音 附件消息",
"api": "sendPhoto / sendVideo / sendAudio / sendDocument / sendVoice",
},
"sendMediaGroup": {
"status": "implemented",
"description": "发送媒体组消息(多张图片/视频批量发送)",
"api": "sendMediaGroup",
},
"sendLocation": {
"status": "implemented",
"description": "发送位置信息",
"api": "sendLocation",
},
"sendContact": {
"status": "implemented",
"description": "发送联系人信息",
"api": "sendContact",
},
"sendPoll": {
"status": "implemented",
"description": "发送投票",
"api": "sendPoll",
},
"sendSticker": {
"status": "implemented",
"description": "发送贴纸",
"api": "sendSticker",
},
"sendDice": {
"status": "implemented",
"description": "发送骰子/飞镖等表情互动",
"api": "sendDice",
},
"sendInvoice": {
"status": "unsupported",
"description": "发送支付账单",
"api": "sendInvoice",
},
"sendGame": {
"status": "unsupported",
"description": "发送HTML5游戏",
"api": "sendGame",
},
"reply": {
"status": "implemented",
"description": "回复指定消息(通过 reply_to_message_id 参数)",
"api": "sendMessage + reply_to_message_id",
},
"forward": {
"status": "implemented",
"description": "转发消息",
"api": "forwardMessage",
},
"copy": {
"status": "implemented",
"description": "复制消息到其他聊天(不转发展示来源)",
"api": "copyMessage",
},
"edit": {
"status": "implemented",
"description": "编辑已发送的文本消息",
"api": "editMessageText",
},
"editCaption": {
"status": "implemented",
"description": "编辑已发送媒体的标题",
"api": "editMessageCaption",
},
"editMedia": {
"status": "unsupported",
"description": "替换已发送的媒体附件内容",
"api": "editMessageMedia",
},
"editInline": {
"status": "implemented",
"description": "更新 Inline Keyboard 按钮",
"api": "editMessageReplyMarkup",
},
"delete": {
"status": "implemented",
"description": "删除消息(Bot 能删除 48h 内的消息)",
"api": "deleteMessage",
},
"pin": {
"status": "implemented",
"description": "置顶消息(需要置顶权限)",
"api": "pinChatMessage",
},
"unpin": {
"status": "implemented",
"description": "取消置顶消息",
"api": "unpinChatMessage",
},
"unpinAll": {
"status": "implemented",
"description": "取消所有置顶消息",
"api": "unpinAllChatMessages",
},
"react": {
"status": "implemented",
"description": "发送emoji 反应(Bot API 7.0+)",
"api": "setMessageReaction",
},
"typing": {
"status": "implemented",
"description": "显示输入状态(打字/上传文件等)",
"api": "sendChatAction",
},
"thread": {
"status": "implemented",
"description": "创建论坛主题(Forum Topic)",
"api": "createForumTopic",
},
"closeThread": {
"status": "implemented",
"description": "关闭 Forum Topic",
"api": "closeForumTopic",
},
"reopenThread": {
"status": "implemented",
"description": "重新打开已关闭的 Forum Topic",
"api": "reopenForumTopic",
},
"deleteThread": {
"status": "implemented",
"description": "删除 Forum Topic",
"api": "deleteForumTopic",
},
"streamChunk": {
"status": "implemented",
"description": "流式输出消息(通过消息编辑逐步展示)",
"api": "editMessageText (streaming)",
},
"inlineButtons": {
"status": "implemented",
"description": "发送内联按钮(InlineKeyboardMarkup)",
"api": "InlineKeyboardMarkup + CallbackQuery",
},
"replyMarkup": {
"status": "implemented",
"description": "发送自定义回复键盘",
"api": "ReplyKeyboardMarkup",
},
"forceReply": {
"status": "implemented",
"description": "强制用户回复",
"api": "ForceReply",
},
"addParticipant": {
"status": "unsupported",
"description": "添加成员到群组(Bot API 不支持)",
"api": "N/A",
},
"removeParticipant": {
"status": "unsupported",
"description": "从群组移除成员(Bot API 不支持)",
"api": "N/A",
},
"kick": {
"status": "implemented",
"description": "踢出群成员(先封禁再解封实现)",
"api": "banChatMember + unbanChatMember",
},
"ban": {
"status": "implemented",
"description": "封禁用户",
"api": "banChatMember",
},
"unban": {
"status": "implemented",
"description": "解封用户",
"api": "unbanChatMember",
},
"mute": {
"status": "implemented",
"description": "禁言群成员",
"api": "restrictChatMember (can_send_messages=False)",
},
"unmute": {
"status": "implemented",
"description": "解除禁言",
"api": "restrictChatMember (can_send_messages=True)",
},
"promoteAdmin": {
"status": "implemented",
"description": "提升成员为管理员",
"api": "promoteChatMember",
},
"demoteAdmin": {
"status": "implemented",
"description": "撤销管理员权限",
"api": "promoteChatMember (reset)",
},
"setPermissions": {
"status": "implemented",
"description": "设置群权限",
"api": "setChatPermissions",
},
"setChatPhoto": {
"status": "implemented",
"description": "设置群头像",
"api": "setChatPhoto",
},
"deleteChatPhoto": {
"status": "implemented",
"description": "删除群头像",
"api": "deleteChatPhoto",
},
"setTitle": {
"status": "implemented",
"description": "设置群标题",
"api": "setChatTitle",
},
"setDescription": {
"status": "implemented",
"description": "设置群描述",
"api": "setChatDescription",
},
"leave": {
"status": "implemented",
"description": "Bot 退出群聊",
"api": "leaveChat",
},
"inviteLink": {
"status": "implemented",
"description": "创建/导出群邀请链接",
"api": "exportChatInviteLink / createChatInviteLink",
},
"revokeInviteLink": {
"status": "unsupported",
"description": "撤销邀请链接",
"api": "revokeChatInviteLink",
},
"broadcast": {
"status": "unsupported",
"description": "群发消息(Telegram Bot API 不直接支持)",
"api": "N/A",
},
"getMe": {
"status": "implemented",
"description": "获取 Bot 基本信息",
"api": "getMe",
},
"getChat": {
"status": "implemented",
"description": "获取聊天基本信息",
"api": "getChat",
},
"getChatAdmins": {
"status": "implemented",
"description": "获取群组管理员列表",
"api": "getChatAdministrators",
},
"getChatMemberCount": {
"status": "implemented",
"description": "获取聊天成员数量",
"api": "getChatMemberCount",
},
"getChatMember": {
"status": "implemented",
"description": "获取指定成员信息",
"api": "getChatMember",
},
"downloadFile": {
"status": "implemented",
"description": "下载文件",
"api": "getFile + file_path",
},
"uploadFile": {
"status": "implemented",
"description": "上传文件",
"api": "sendDocument (file upload)",
},
}
_TELEGRAM_ACTION_MAPPING: dict[str, str] = {
"send": "send",
"sendAttachment": "send_attachment",
"sendMediaGroup": "send_media_group",
"sendLocation": "send_location",
"sendContact": "send_contact",
"sendPoll": "create_poll",
"sendSticker": "sticker",
"sendDice": "send_dice",
"reply": "reply",
"forward": "forward",
"copy": "copy",
"edit": "edit",
"editCaption": "edit_caption",
"editInline": "edit_inline",
"delete": "delete",
"pin": "pin",
"unpin": "unpin",
"unpinAll": "unpin_all",
"react": "react",
"typing": "typing",
"thread": "thread_create",
"closeThread": "close_thread",
"reopenThread": "reopen_thread",
"deleteThread": "delete_thread",
"streamChunk": "stream",
"addParticipant": "add_participant",
"removeParticipant": "remove_participant",
"kick": "kick",
"ban": "ban",
"unban": "unban",
"mute": "mute",
"unmute": "unmute",
"setTitle": "rename_group",
"setChatPhoto": "set_group_icon",
"deleteChatPhoto": "delete_chat_photo",
"setDescription": "set_chat_description",
"leave": "leave_group",
"broadcast": "broadcast",
"inviteLink": "invite_link",
"getMe": "get_me",
"getChat": "channel_info",
"getChatAdmins": "role_info",
"getChatMemberCount": "channel_list",
"getChatMember": "member_info",
"downloadFile": "download_file",
"uploadFile": "upload_file",
"setPermissions": "permissions",
"promoteAdmin": "role_add",
"demoteAdmin": "role_remove",
"createEvent": "event_create",
}
def register_telegram_actions() -> None:
from yuxi.channels.message_actions import ActionDeclaration, ActionRegistry, ActionStatus, MessageAction
declarations: dict[MessageAction, ActionDeclaration] = {}
for action_name, info in TELEGRAM_MESSAGE_ACTIONS.items():
mapped = _TELEGRAM_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("telegram", declarations)