diff --git a/src/langbot_plugin/api/entities/builtin/platform/events.py b/src/langbot_plugin/api/entities/builtin/platform/events.py index d91320a..cf8dd4c 100644 --- a/src/langbot_plugin/api/entities/builtin/platform/events.py +++ b/src/langbot_plugin/api/entities/builtin/platform/events.py @@ -126,3 +126,98 @@ def model_dump(self, **kwargs): "message_chain": self.message_chain.model_dump(), "time": self.time, } + + +############################### +# Notice Event +class NoticeEvent(Event): + """通知事件。 + + notice_type 对应 OneBot v11 的 notice_type: + group_increase, group_decrease, group_admin, group_ban, + group_upload, group_recall, friend_recall, friend_add, notify + + sub_type 对应各通知的子类型: + group_increase: approve / invite + group_decrease: leave / kick / kick_me + group_admin: set / unset + group_ban: ban / lift_ban + notify: poke / lucky_king / honor + """ + + type: str = "NoticeEvent" + + notice_type: str = "" + """通知类型,如 group_increase, group_recall, notify 等。""" + + sub_type: str = "" + """子类型,如 approve, kick, poke 等。""" + + group_id: typing.Optional[typing.Union[int, str]] = None + """群号。""" + + user_id: typing.Optional[typing.Union[int, str]] = None + """触发事件的用户 ID。""" + + operator_id: typing.Optional[typing.Union[int, str]] = None + """操作者 ID(如踢人者、禁言操作者、撤回操作者)。""" + + target_id: typing.Optional[typing.Union[int, str]] = None + """目标 ID(如被戳者、运气王)。""" + + message_id: typing.Optional[typing.Union[int, str]] = None + """关联的消息 ID(撤回事件)。""" + + duration: typing.Optional[int] = None + """禁言时长(秒),0 表示解除禁言。""" + + file: typing.Optional[dict] = None + """文件信息(group_upload 事件),包含 id, name, size, busid。""" + + honor_type: typing.Optional[str] = None + """荣誉类型(notify/honor 事件): talkative / performer / emotion。""" + + time: float | None = None + """事件时间戳。""" + + source_platform_object: typing.Optional[typing.Any] = None + """原消息平台对象。""" + + +############################### +# Request Event +class RequestEvent(Event): + """请求事件。 + + request_type 对应 OneBot v11 的 request_type: + friend, group + + sub_type 对应各请求的子类型 (仅 group): + group: add / invite + """ + + type: str = "RequestEvent" + + request_type: str = "" + """请求类型: friend / group。""" + + sub_type: str = "" + """子类型: add / invite (仅 group 请求)。""" + + user_id: typing.Optional[typing.Union[int, str]] = None + """发送请求的用户 ID。""" + + group_id: typing.Optional[typing.Union[int, str]] = None + """群号 (仅 group 请求)。""" + + comment: str = "" + """验证信息/附言。""" + + flag: str = "" + """请求 flag,用于处理请求时传入。""" + + time: float | None = None + """事件时间戳。""" + + source_platform_object: typing.Optional[typing.Any] = None + """原消息平台对象。""" diff --git a/src/langbot_plugin/api/entities/builtin/platform/message.py b/src/langbot_plugin/api/entities/builtin/platform/message.py index b5381a0..35fb142 100644 --- a/src/langbot_plugin/api/entities/builtin/platform/message.py +++ b/src/langbot_plugin/api/entities/builtin/platform/message.py @@ -46,6 +46,8 @@ def _get_component_types(cls) -> dict[str, type[MessageComponent]]: "Voice": Voice, "Forward": Forward, "File": File, + "Notice": Notice, + "Request": Request, "WeChatMiniPrograms": WeChatMiniPrograms, "WeChatForwardMiniPrograms": WeChatForwardMiniPrograms, "WeChatEmoji": WeChatEmoji, @@ -460,7 +462,135 @@ def rps_data(self, face_id): return rps_dict[face_id] -# ================ 个人微信专用组件 ================ +class Notice(MessageComponent): + """通知消息组件。 + + notice_type 对应 OneBot v11 的 notice_type: + group_increase, group_decrease, group_admin, group_ban, + group_upload, group_recall, friend_recall, friend_add, notify + + sub_type 对应各通知的子类型: + group_increase: approve / invite + group_decrease: leave / kick / kick_me + group_admin: set / unset + group_ban: ban / lift_ban + notify: poke / lucky_king / honor + """ + + type: str = "Notice" + """消息组件类型。""" + notice_type: str = "" + """通知类型。""" + sub_type: str = "" + """子类型。""" + group_id: typing.Optional[typing.Union[int, str]] = None + """群号。""" + user_id: typing.Optional[typing.Union[int, str]] = None + """触发事件的用户 ID。""" + operator_id: typing.Optional[typing.Union[int, str]] = None + """操作者 ID。""" + target_id: typing.Optional[typing.Union[int, str]] = None + """目标 ID(被戳者、运气王等)。""" + message_id: typing.Optional[typing.Union[int, str]] = None + """关联的消息 ID(撤回事件)。""" + duration: typing.Optional[int] = None + """禁言时长(秒)。""" + file: typing.Optional[dict] = None + """文件信息(group_upload 事件)。""" + honor_type: typing.Optional[str] = None + """荣誉类型(notify/honor 事件)。""" + + def __str__(self): + notice_name = self._get_notice_name() + if self.sub_type: + sub_name = self._get_sub_type_name() + return f"[通知]{notice_name}-{sub_name}" + return f"[通知]{notice_name}" + + def _get_notice_name(self) -> str: + notice_name_dict = { + "group_increase": "群成员增加", + "group_decrease": "群成员减少", + "group_admin": "群管理员变动", + "group_ban": "群禁言", + "group_upload": "群文件上传", + "group_recall": "群消息撤回", + "group_card": "群名片更新", + "friend_recall": "私聊消息撤回", + "friend_add": "好友添加", + "notify": "提醒", + "essence": "群精华消息", + "group_msg_emoji_like": "群表情回应", + } + return notice_name_dict.get(self.notice_type, self.notice_type) + + def _get_sub_type_name(self) -> str: + sub_type_name_dict = { + "approve": "同意", + "invite": "邀请", + "leave": "主动退群", + "kick": "被踢", + "kick_me": "登录号被踢", + "set": "设置", + "unset": "取消", + "ban": "禁言", + "lift_ban": "解除禁言", + "poke": "戳一戳", + "lucky_king": "运气王", + "honor": "荣誉", + "add": "添加", + "input_status": "输入状态", + "title": "头衔变更", + "profile_like": "点赞", + } + return sub_type_name_dict.get(self.sub_type, self.sub_type) + + +class Request(MessageComponent): + """请求消息组件。 + + request_type 对应 OneBot v11 的 request_type: + friend, group + + sub_type 对应各请求的子类型 (仅 group): + group: add / invite + """ + + type: str = "Request" + """消息组件类型。""" + request_type: str = "" + """请求类型: friend / group。""" + sub_type: str = "" + """子类型: add / invite (仅 group 请求)。""" + user_id: typing.Optional[typing.Union[int, str]] = None + """发送请求的用户 ID。""" + group_id: typing.Optional[typing.Union[int, str]] = None + """群号 (仅 group 请求)。""" + comment: str = "" + """验证信息/附言。""" + flag: str = "" + """请求 flag,用于处理请求时传入。""" + + def __str__(self): + request_name = self._get_request_name() + if self.sub_type: + sub_name = self._get_sub_type_name() + return f"[请求]{request_name}-{sub_name}" + return f"[请求]{request_name}" + + def _get_request_name(self) -> str: + request_name_dict = { + "friend": "加好友", + "group": "加群", + } + return request_name_dict.get(self.request_type, self.request_type) + + def _get_sub_type_name(self) -> str: + sub_type_name_dict = { + "add": "主动加群", + "invite": "邀请入群", + } + return sub_type_name_dict.get(self.sub_type, self.sub_type) class WeChatMiniPrograms(MessageComponent): diff --git a/src/langbot_plugin/api/entities/events.py b/src/langbot_plugin/api/entities/events.py index ce1f53e..70e6e5f 100644 --- a/src/langbot_plugin/api/entities/events.py +++ b/src/langbot_plugin/api/entities/events.py @@ -102,8 +102,8 @@ def validate_message_event(cls, v): class _WithReplyMessageChain(BaseEventModel): """事件模型基类,包含回复消息链对象""" - reply_message_chain: typing.Optional[platform_message.MessageChain] = pydantic.Field( - serialization_alias="reply_message_chain", default=None + reply_message_chain: typing.Optional[platform_message.MessageChain] = ( + pydantic.Field(serialization_alias="reply_message_chain", default=None) ) """回复消息链对象,仅在阻止默认行为时有效""" @@ -157,9 +157,11 @@ def serialize_message_event(self, v, _info): def validate_message_event(cls, v): return platform_events.FriendMessage.model_validate(v) - user_message_alter: typing.Optional[typing.Union[provider_message.ContentElement, list[provider_message.ContentElement], str]] = pydantic.Field( - default=None - ) + user_message_alter: typing.Optional[ + typing.Union[ + provider_message.ContentElement, list[provider_message.ContentElement], str + ] + ] = pydantic.Field(default=None) """修改后的 LLM 消息对象,可用于改写用户消息""" @@ -199,9 +201,11 @@ def serialize_message_event(self, v, _info): def validate_message_event(cls, v): return platform_events.GroupMessage.model_validate(v) - user_message_alter: typing.Optional[typing.Union[provider_message.ContentElement, list[provider_message.ContentElement], str]] = pydantic.Field( - default=None - ) + user_message_alter: typing.Optional[ + typing.Union[ + provider_message.ContentElement, list[provider_message.ContentElement], str + ] + ] = pydantic.Field(default=None) """修改后的 LLM 消息对象,可用于改写用户消息""" @@ -272,6 +276,85 @@ class NormalMessageResponded(_WithReplyMessageChain): """调用的函数列表""" +class NoticeReceived(BaseEventModel): + """收到通知事件时触发(群成员变动、禁言、撤回、戳一戳等) + + notice_type 对应 OneBot v11 的 notice_type: + group_increase, group_decrease, group_admin, group_ban, + group_upload, group_recall, friend_recall, friend_add, notify + + sub_type 对应各通知的子类型: + group_increase: approve / invite + group_decrease: leave / kick / kick_me + group_admin: set / unset + group_ban: ban / lift_ban + notify: poke / lucky_king / honor + """ + + event_name: str = "NoticeReceived" + + notice_type: str + """通知类型,如 group_increase, group_recall, notify 等。""" + + sub_type: str = "" + """子类型,如 approve, kick, poke 等。""" + + group_id: typing.Optional[typing.Union[int, str]] = None + """群号。""" + + user_id: typing.Optional[typing.Union[int, str]] = None + """触发事件的用户 ID。""" + + operator_id: typing.Optional[typing.Union[int, str]] = None + """操作者 ID。""" + + target_id: typing.Optional[typing.Union[int, str]] = None + """目标 ID(被戳者、运气王等)。""" + + message_id: typing.Optional[typing.Union[int, str]] = None + """关联的消息 ID(撤回事件)。""" + + duration: typing.Optional[int] = None + """禁言时长(秒)。""" + + file: typing.Optional[dict] = None + """文件信息(group_upload 事件)。""" + + honor_type: typing.Optional[str] = None + """荣誉类型(notify/honor 事件)。""" + + +class RequestReceived(BaseEventModel): + """收到请求事件时触发(加好友请求、加群请求、邀请入群等) + + request_type 对应 OneBot v11 的 request_type: + friend, group + + sub_type 对应各请求的子类型 (仅 group): + group: add / invite + """ + + event_name: str = "RequestReceived" + + request_type: str + """请求类型: friend / group。""" + + sub_type: str = "" + """子类型: add / invite (仅 group 请求)。""" + + user_id: typing.Optional[typing.Union[int, str]] = None + """发送请求的用户 ID。""" + + group_id: typing.Optional[typing.Union[int, str]] = None + """群号 (仅 group 请求)。""" + + comment: str = "" + """验证信息/附言。""" + + flag: str = "" + """请求 flag,用于处理请求时传入。""" + + class PromptPreProcessing(BaseEventModel): """会话中的Prompt预处理时触发"""