通用事件基础
约 728 字大约 2 分钟
2026-03-19
BaseEvent 基类、Mixin Trait 协议、事件工厂。所有平台的事件实体通用基础设施。
导入路径: from ncatbot.event import BaseEvent, create_entity, Replyable, HasSender, ...
源码: ncatbot/event/common/
BaseEvent
所有事件实体的基类。包装 数据模型(BaseEventData)+ API 客户端。
class BaseEvent:
def __init__(self, data: BaseEventData, api: IAPIClient): ...属性
| 属性 | 类型 | 说明 |
|---|---|---|
data | BaseEventData | 底层数据模型 |
api | IAPIClient | API 客户端实例 |
time | int | 事件时间戳 |
self_id | str | Bot 自身 ID |
post_type | str | 事件顶层类型 |
platform | str | 平台标识("qq", "bilibili" 等) |
Mixin Traits
事件行为通过 Mixin 组合实现。平台事件实体多继承所需 Trait,插件代码可用 isinstance 检查能力。
from ncatbot.event import Replyable, HasSender
if isinstance(event, Replyable):
await event.reply(text="收到")
if isinstance(event, HasSender):
print(f"来自 {event.user_id}")Replyable
支持回复的事件。
async def reply(self, **kwargs) -> Any: ...不同平台的 reply() 签名不同:
- QQ MessageEvent:
reply(text=, *, at=, image=, video=, rtf=, at_sender=True) - Bilibili DanmuMsgEvent:
reply(text, **kwargs) - Bilibili BiliPrivateMessageEvent:
reply(text, **kwargs) - Bilibili BiliCommentEvent:
reply(text, **kwargs)
Deletable
支持撤回/删除。
async def delete(self) -> Any: ...HasSender
包含发送者信息。
@property
def user_id(self) -> str: ...
@property
def sender(self) -> Any: ...GroupScoped
属于群/频道/直播间的事件。
@property
def group_id(self) -> str: ...Bilibili 直播间事件的
group_id返回room_id。
Kickable
支持踢出成员。
async def kick(self, **kwargs) -> Any: ...Bannable
支持禁言。
async def ban(self, duration: int = 1800, **kwargs) -> Any: ...Approvable
支持同意/拒绝请求。
async def approve(self, **kwargs) -> Any: ...
async def reject(self, **kwargs) -> Any: ...HasAttachments
携带可下载附件的事件。返回 AttachmentList(list 子类),包含类型化的附件对象,支持按类型过滤。
async def get_attachments(self) -> AttachmentList: ...附件子类层级:
| 类型 | kind | 特有字段 | to_segment() 返回 |
|---|---|---|---|
Attachment | OTHER | — | File |
ImageAttachment | IMAGE | width, height | Image |
VideoAttachment | VIDEO | duration | Video |
AudioAttachment | AUDIO | duration | Record |
FileAttachment | FILE | — | File |
AttachmentList 过滤方法:images(), videos(), audios(), files(), by_kind(), by_content_type(), first(), largest(), smallest(), download_all()。
附件转换方法:to_segment(), to_local_segment(cache_dir), as_bytes(), download(dest)。
示例:
from ncatbot.event import HasAttachments
if isinstance(event, HasAttachments):
atts = await event.get_attachments()
for img in atts.images():
path = await img.download("./images")
for vid in atts.videos():
seg = vid.to_segment() # 转为 Video 消息段用于转发当前实现了 HasAttachments 的事件:
GitHubReleaseEvent— 将 Release Assets 转为 AttachmentQQ MessageEvent— 将消息中的 Image/Video/Record/File 段转为类型化附件
事件工厂
create_entity() 将数据模型转换为事件实体,自动路由到各平台工厂。
from ncatbot.event import create_entity
entity = create_entity(data, api)
# data.platform == "qq" → QQ 工厂
# data.platform == "bilibili" → Bilibili 工厂
# 未知平台 → 返回 BaseEvent路由策略
- 精确映射:根据数据模型类(如
GroupMessageEventData)找到对应实体类(如GroupMessageEvent) - 降级匹配:根据
post_type找到该类别的基础实体类(如PostType.MESSAGE→MessageEvent) - 兜底:返回
BaseEvent
注册平台工厂
from ncatbot.event import register_platform_factory
register_platform_factory("my_platform", my_factory_func)工厂签名:(data: BaseEventData, api: IAPIClient) -> Optional[BaseEvent]
交叉引用
- QQ 事件实体 — QQ 平台事件完整参考
- Bilibili 事件实体 — Bilibili 平台事件完整参考
- 类型参考 — 数据模型与消息段
版权所有
版权归属:huan-yp
