mirror of
				https://github.com/nonebot/nonebot2.git
				synced 2025-10-31 06:56:39 +00:00 
			
		
		
		
	✨ implement event parser
This commit is contained in:
		| @@ -1,5 +1,10 @@ | ||||
| from typing import List, Literal | ||||
| from pydantic import BaseModel, root_validator | ||||
| import inspect | ||||
| import json | ||||
| from nonebot import message | ||||
|  | ||||
| from typing import Any, List, Literal, Optional, Type, Union | ||||
| from pygtrie import StringTrie | ||||
| from pydantic import BaseModel, root_validator, Field | ||||
|  | ||||
| from nonebot.adapters import Event as BaseEvent | ||||
| from nonebot.typing import overrides | ||||
| @@ -7,6 +12,15 @@ from nonebot.typing import overrides | ||||
| from .message import Message, MessageSegment | ||||
|  | ||||
|  | ||||
| class EventHeader(BaseModel): | ||||
|     event_id: str | ||||
|     event_type: str | ||||
|     create_time: str | ||||
|     token: str | ||||
|     app_id: str | ||||
|     tenant_key: str | ||||
|  | ||||
|  | ||||
| class Event(BaseEvent): | ||||
|     """ | ||||
|     飞书协议事件。各事件字段参考 `飞书文档`_ | ||||
| @@ -14,16 +28,18 @@ class Event(BaseEvent): | ||||
|     .. _飞书事件列表文档: | ||||
|         https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-list | ||||
|     """ | ||||
|     app_id: int | ||||
|     event_type: str | ||||
|     __event__ = "" | ||||
|     schema_: str = Field("", alias='schema') | ||||
|     header: EventHeader | ||||
|     event: Any | ||||
|  | ||||
|     @overrides(BaseEvent) | ||||
|     def get_type(self) -> str: | ||||
|         return self.event_type | ||||
|         return self.header.event_type | ||||
|  | ||||
|     @overrides(BaseEvent) | ||||
|     def get_event_name(self) -> str: | ||||
|         return self.event_type | ||||
|         return self.header.event_type | ||||
|  | ||||
|     @overrides(BaseEvent) | ||||
|     def get_event_description(self) -> str: | ||||
| @@ -69,39 +85,31 @@ class Mention(BaseModel): | ||||
|     tenant_key: str | ||||
|  | ||||
|  | ||||
| class MessageBody(BaseModel): | ||||
| class EventMessage(BaseModel): | ||||
|     message_id: str | ||||
|     root_id: str | ||||
|     parent_id: str | ||||
|     root_id: Optional[str] | ||||
|     parent_id: Optional[str] | ||||
|     create_time: str | ||||
|     chat_id: str | ||||
|     chat_type: str | ||||
|     message_type: str | ||||
|     content: Message | ||||
|     mentions: List[Mention] | ||||
|  | ||||
|     plaintext: str | ||||
|     mentions: Optional[List[Mention]] | ||||
|  | ||||
|     @root_validator(pre=True) | ||||
|     def gen_message(cls, values: dict): | ||||
|         content = [] | ||||
|         for piece in values["content"]: | ||||
|             for segment in piece: | ||||
|                 content.append( | ||||
|                     MessageSegment(segment["tag"], segment.pop('name', segment))) | ||||
|  | ||||
|         values["content"] = Message(content) | ||||
|     def parse_message(cls, values: dict): | ||||
|         values["content"] = json.loads(values["content"]) | ||||
|         return values | ||||
|  | ||||
|     @root_validator | ||||
|     def gen_plaintext(cls, values: dict): | ||||
|         values["plaintext"] = str(values["content"]) | ||||
|         return values | ||||
|  | ||||
| class MessageEventDetail(BaseModel): | ||||
|     sender: Sender | ||||
|     message: EventMessage | ||||
|  | ||||
|  | ||||
| class MessageEvent(Event): | ||||
|     sender: Sender | ||||
|     message: MessageBody | ||||
|     __event__ = "im.message.receive_v1" | ||||
|     event: MessageEventDetail | ||||
|  | ||||
|     @overrides(Event) | ||||
|     def get_type(self) -> Literal["message", "notice", "meta_event"]: | ||||
| @@ -115,32 +123,40 @@ class MessageEvent(Event): | ||||
|     def get_event_description(self) -> str: | ||||
|         return ( | ||||
|             f"Message[{super().get_type()}]" | ||||
|             f" {self.message.message_id} from {self.sender.sender_id.user_id}" | ||||
|             f" {self.message.content}") | ||||
|             f" {self.event.message.message_id} from {self.event.sender.sender_id.user_id}" | ||||
|             f" {self.event.message.content}") | ||||
|  | ||||
|     @overrides(Event) | ||||
|     def get_message(self) -> Message: | ||||
|         return self.message.content | ||||
|         return self.event.message.content | ||||
|  | ||||
|     @overrides(Event) | ||||
|     def get_plaintext(self) -> str: | ||||
|         return self.message.plaintext | ||||
|         return str(self.event.message.content) | ||||
|  | ||||
|     @overrides(Event) | ||||
|     def get_user_id(self) -> str: | ||||
|         return self.sender.sender_id.user_id | ||||
|         return self.event.sender.sender_id.user_id | ||||
|  | ||||
|     @overrides(Event) | ||||
|     def get_session_id(self) -> str: | ||||
|         return self.sender.sender_id.user_id | ||||
|         return self.event.sender.sender_id.user_id | ||||
|  | ||||
|  | ||||
| class PrivateMessageEvent(MessageEvent): | ||||
|     ... | ||||
| class MessageReader(BaseModel): | ||||
|     reader_id: UserId | ||||
|     read_time: str | ||||
|     tenant_key: str | ||||
|  | ||||
|  | ||||
| class GroupMessageEvent(MessageEvent): | ||||
|     ... | ||||
| class MessageReadEventDetail(BaseModel): | ||||
|     reader: MessageReader | ||||
|     message_id_list: List[str] | ||||
|  | ||||
|  | ||||
| class MessageReadEvent(Event): | ||||
|     __event__ = "im.message.message_read_v1" | ||||
|     event: MessageReadEventDetail | ||||
|  | ||||
|  | ||||
| class NoticeEvent(Event): | ||||
| @@ -149,3 +165,26 @@ class NoticeEvent(Event): | ||||
|  | ||||
| class MetaEvent(Event): | ||||
|     ... | ||||
|  | ||||
|  | ||||
| _t = StringTrie(separator=".") | ||||
|  | ||||
| # define `model` first to avoid globals changing while `for` | ||||
| model = None | ||||
| for model in globals().values(): | ||||
|     if not inspect.isclass(model) or not issubclass(model, Event): | ||||
|         continue | ||||
|     _t["." + model.__event__] = model | ||||
|  | ||||
|  | ||||
| def get_event_model(event_name) -> List[Type[Event]]: | ||||
|     """ | ||||
|     :说明: | ||||
|  | ||||
|       根据事件名获取对应 ``Event Model`` 及 ``FallBack Event Model`` 列表 | ||||
|  | ||||
|     :返回: | ||||
|  | ||||
|       - ``List[Type[Event]]`` | ||||
|     """ | ||||
|     return [model.value for model in _t.prefixes("." + event_name)][::-1] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user