implement event parser

This commit is contained in:
StarHeartHunt
2021-07-04 14:19:10 +08:00
parent 20c3c24a6d
commit 7a8f881b04
2 changed files with 134 additions and 39 deletions

View File

@ -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]