Appearance
事件类型参考
事件分两大体系:18 种接收事件(event/receive/,网关推送 + 2 个生命周期就绪事件)+ 23 种发送事件(event/send/,操作前触发、可取消)。
事件层级
Event (抽象基类,含 metadata 系统)
├── ReceiveEvent (抽象,携带 Session 快照)
│ ├── ReadyEvent # 每分片连接就绪(仅 WebSocket 模式,网关 READY)
│ ├── WebhookReadyEvent # Webhook 回调服务就绪(仅 Webhook 模式,触发一次)
│ ├── ResumedEvent # 断线重连会话恢复(仅 WebSocket 模式)
│ ├── GroupMessageEvent # 群普通消息
│ ├── GroupAtMessageEvent # 群 @ 消息
│ ├── C2CMessageEvent # 私聊消息
│ ├── InteractionEvent # 互动事件(按钮点击等)
│ ├── FriendAddEvent # 好友新增
│ ├── FriendDelEvent # 好友删除
│ ├── GroupAddRobotEvent # 机器人被加入群
│ ├── GroupDelRobotEvent # 机器人被移出群
│ ├── GroupMemberAddEvent # 群成员增加
│ ├── GroupMemberRemoveEvent # 群成员移除
│ ├── GroupMsgReceiveEvent # 群消息接收开关:开启
│ ├── GroupMsgRejectEvent # 群消息接收开关:关闭
│ ├── C2CMsgReceiveEvent # 私聊消息接收开关:开启
│ ├── C2CMsgRejectEvent # 私聊消息接收开关:关闭
│ └── GroupJoinRequestEvent # 用户申请入群
└── SendEvent (抽象,可取消)
├── GroupMessageSendEvent # 群消息发送前
├── C2CMessageSendEvent # 私聊消息发送前
├── C2CStreamMessageSendEvent # 私聊流式消息发送前
├── GroupFileSendEvent # 群文件发送前(uploadGroupFile)
├── C2CFileSendEvent # 私聊文件发送前(uploadC2CFile)
├── GroupUploadPrepareEvent # 群分片预上传前
├── GroupUploadPartFinishEvent # 群分片确认前
├── GroupUploadChunkedEvent # 群分片合并前
├── C2CUploadPrepareEvent # 私聊分片预上传前
├── C2CUploadPartFinishEvent # 私聊分片确认前
├── C2CUploadChunkedEvent # 私聊分片合并前
├── GroupMessageDeleteEvent # 撤回群消息前
├── C2CMessageDeleteEvent # 撤回私聊消息前
├── InteractionRespondEvent # 互动响应前
├── GroupMemberMuteEvent # 群成员禁言前
├── JoinRequestApproveEvent # 入群申请批准前
├── JoinRequestDeclineEvent # 入群申请拒绝前
├── UrlLinkGenerateEvent # 分享链接生成前
├── MenuUpdateEvent # C2C 菜单修改前
├── PanelCreateEvent # 指令面板创建前
├── PanelUpdateEvent # 指令面板修改前
├── PanelDeleteEvent # 指令面板删除前
└── PanelTargetUpdateEvent # 指令面板关联对象修改前ReceiveEvent 公共方法(会话快照)
所有接收事件在创建时对 Session 做只读快照,事件自带连接上下文:
| 方法 | 返回类型 | 说明 |
|---|---|---|
getSessionId() | String | 会话 ID(断线重连恢复用,首连 READY 前为空串) |
getLastSeq() | int | 触发事件时的最后消息序列号 |
getIntent() | int | 订阅事件的意图位掩码 |
getUrl() | String | WebSocket 网关地址 |
getHeartbeatInterval() | int | 心跳间隔(毫秒) |
getShardId() | int | 当前分片 ID(从 0 开始) |
getShardCount() | int | 总分片数(1 = 未分片) |
分片
多分片时每个连接各自触发事件,用 getShardId() 区分来源。ReadyEvent 每片触发一次(仅 WebSocket 模式),全局初始化只在 getShardId() == 0 时做——插件做「机器人上线」初始化更推荐实现 Plugin.onActive()(两模式统一触发一次,无需判断分片)。
群消息事件
GroupAtMessageEvent
用户 @机器人 时触发。事件名:GROUP_AT_MESSAGE_CREATE
| 方法 | 返回类型 | 说明 |
|---|---|---|
getId() | String | 消息 ID(用于回复/撤回) |
getAuthor() | Author | 发送者信息 |
getContent() | String | 文本内容(已去除 @ 前缀) |
getGroupOpenid() | String | 群 OpenID |
getTimestamp() | long | Unix 秒级时间戳 |
getMessageType() | int | 0=普通, 3=结构化卡片, 103=引用 |
getAttachments() | List<Attachment> | 附件列表 |
getMessageScene() | MessageScene | 消息场景上下文(含 msg_idx 用于引用回复/去重) |
getArkData() | ARKData | 结构化卡片数据(message_type=3 时有值) |
getMsgElements() | List<MsgElement> | 消息元素列表(引用消息时有值) |
getMentions() | List<Author> | 被 @ 的用户列表 |
Author 记录
java
public record Author(
String id, // 用户 OpenID
String username, // 昵称
boolean bot, // 是否机器人
String unionOpenid, // 跨应用统一 OpenID
String unionUserAccount, // 跨应用统一账号
String memberOpenid, // 群成员 OpenID
String memberRole // 群内角色:member / admin / owner
) {}Attachment 记录
java
public record Attachment(
String url, // 附件下载 URL
String filename, // 文件名
int width, int height,// 宽高(px)
int size, // 字节数
String contentType, // MIME 类型
String voiceWavUrl, // 语音转 WAV URL
String asrReferText // 语音识别文本
) {}私聊消息事件
C2CMessageEvent
事件名:C2C_MESSAGE_CREATE
| 方法 | 返回类型 | 说明 |
|---|---|---|
getId() | String | 消息 ID |
getAuthor() | C2CAuthor | 发送者(注意:是 C2CAuthor,含 userOpenid) |
getContent() | String | 文本内容 |
getTimestamp() | long | 时间戳 |
getMessageType() | int | 消息类型 |
getAttachments() | List<C2CAttachment> | 附件列表 |
getMessageScene() | MessageScene | 消息场景上下文(含 msg_idx) |
getArkData() | ARKData | 结构化卡片数据 |
getMsgElements() | List<MsgElement> | 消息元素列表 |
C2CAuthor 记录
java
public record C2CAuthor(
String id, // 用户 OpenID
String username, // 昵称
boolean bot, // 是否机器人
String unionOpenid, // 跨应用统一 OpenID
String unionUserAccount, // 跨应用统一账号
String userOpenid // 用户 OpenID(单聊场景)
) {}互动事件
InteractionEvent
用户点击按钮、快捷菜单等时触发。必须调用 Bngeuit.respondInteraction() 响应,否则客户端一直 loading:
java
import cn.org.bukkit.bngeuit.Bngeuit;
import cn.org.bukkit.bngeuit.core.BotApi;
import cn.org.bukkit.bngeuit.event.SubscribeEvent;
import cn.org.bukkit.bngeuit.event.receive.InteractionEvent;
@SubscribeEvent
public void onInteraction(InteractionEvent e) {
Bngeuit.respondInteraction(e.getId(),
BotApi.InteractionResponseCode.SUCCESS);
// 按钮回调数据在 button_data
if (e.isButtonClick() && "/confirm".equals(e.getButtonData())) {
Bngeuit.sendGroupText(e.getGroupOpenid(), 1, "已确认");
}
}常用方法:
| 方法 | 返回类型 | 说明 |
|---|---|---|
getId() | String | 互动事件 ID(用于响应) |
getType() | InteractionType | 互动类型(按钮=11、快捷菜单=12 等) |
getScene() | InteractionScene | 场景(GROUP / C2C / GUILD) |
getChatType() | ChatType | 聊天类型(群=1、私聊=2) |
getUserOpenid() | String | 操作用户 OpenID |
getGroupOpenid() | String | 群 OpenID(群场景有值) |
getButtonId() | String | 被点击按钮 ID |
getButtonData() | String | 按钮回调数据(与创建按钮时一致) |
isButtonClick() | boolean | 是否为消息按钮点击(type=11) |
isFromGroup() | boolean | 是否来自群聊 |
好友与群管理
| 事件 | 触发时机 |
|---|---|
FriendAddEvent | 用户添加机器人为好友 |
FriendDelEvent | 用户删除机器人好友 |
GroupAddRobotEvent | 机器人被拉入群 |
GroupDelRobotEvent | 机器人被移出群 |
GroupMemberAddEvent | 新成员加入群 |
GroupMemberRemoveEvent | 成员退出群 |
GroupJoinRequestEvent | 用户申请入群 |
GroupJoinRequestEvent
用户申请入群时触发。事件名:GROUP_JOIN_REQUEST。机器人需拥有群管理员身份。
java
@SubscribeEvent
public void onJoinRequest(GroupJoinRequestEvent e) {
// 批准入群
Bngeuit.approveJoinRequest(e.getGroupOpenid(), e.getMemberOpenid(), e.getJoinRequestId());
// 或拒绝入群
Bngeuit.declineJoinRequest(e.getGroupOpenid(), e.getMemberOpenid(),
e.getJoinRequestId(), "不符合入群条件", false);
}| 方法 | 返回类型 | 说明 |
|---|---|---|
getGroupOpenid() | String | 群 OpenID |
getMemberOpenid() | String | 申请人 OpenID |
getUsername() | String | 申请人昵称 |
getJoinRequestId() | String | 申请 ID(用于传给审批 API) |
getApplyAt() | long | 申请时间(Unix 秒) |
getApplySource() | ApplySource | 申请来源:SELF_APPLY(直接申请)/ INVITED(被邀请) |
getInvitedBy() | String | 邀请人 OpenID(仅 INVITED 时有值) |
isBot() | boolean | 申请人是否为机器人 |
getRiskTips() | String | QQ 安全系统风险提示 |
getVerifyInfo() | VerifyInfo | 入群验证信息 |
getAutoApproved() | AutoApproved | 自动审批信息(策略命中时有值) |
isAutoApproved() | boolean | 是否被自动审批策略通过 |
系统事件
- ReadyEvent — 每个分片连接鉴权完成各触发一次(仅 WebSocket 模式,网关真实 READY)
- WebhookReadyEvent — Webhook 回调服务启动完成后触发一次(仅 Webhook 模式,无伪造 ReadyEvent)
- ResumedEvent — 断线重连(RESUME)成功(仅 WebSocket 模式)
插件推荐:onActive()
做「机器人已上线」的初始化(启动定时推送、上报在线状态等)时,推荐实现 Plugin.onActive():该生命周期在两种接入模式统一触发一次(WS 全部分片就绪 / Webhook 回调服务就绪),无需关心接入方式与分片,也无需自行防重。
发送事件(可取消)
所有发送事件实现 Cancellable,在 HTTP 调用前触发,取消则操作跳过、API 返回 null。常用字段示例(以 GroupMessageSendEvent 为例):
| 方法 | 返回类型 | 说明 |
|---|---|---|
getGroupOpenid() | String | 目标群 |
getMsgType() | int | 消息类型 |
getContent() | String | 文本内容 |
getMarkdown() | MessageMarkdown | Markdown 负载 |
getKeyboard() | Keyboard | 内嵌键盘 |
getCard() | Card | 图文卡片 |
getMedia() | MediaInfo | 富媒体信息 |
setCancelled(boolean) | — | 取消本次操作 |
C2CStreamMessageSendEvent
私聊流式消息发送事件,字段使用枚举类型:
| 方法 | 返回类型 | 说明 |
|---|---|---|
getOpenid() | String | 目标用户 |
getInputMode() | InputMode | 输入模式(InputMode.APPEND / InputMode.REPLACE) |
getContentType() | StreamContentType | 内容类型(StreamContentType.TEXT / StreamContentType.MARKDOWN) |
getContent() | String | 消息内容 |
分片上传事件携带 File 对象:GroupUploadChunkedEvent.getFile() / getFileName() / getFilePath()。
GroupMemberMuteEvent
群成员禁言操作前触发。取消可阻止禁言操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getGroupOpenid() | String | 群 OpenID |
getMembers() | List<SetMemberMuteState> | 禁言设置列表(含 op、memberOpenid、muteExpireAt) |
JoinRequestApproveEvent
批准入群申请前触发。取消可阻止批准操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getGroupOpenid() | String | 群 OpenID |
getMemberOpenid() | String | 申请人 OpenID |
getJoinRequestId() | String | 申请 ID |
JoinRequestDeclineEvent
拒绝入群申请前触发。取消可阻止拒绝操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getGroupOpenid() | String | 群 OpenID |
getMemberOpenid() | String | 申请人 OpenID |
getJoinRequestId() | String | 申请 ID |
getRejectReason() | String | 拒绝理由 |
isAddToBlacklist() | boolean | 是否加入黑名单 |
UrlLinkGenerateEvent
生成分享链接前触发。取消可阻止生成操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getCallbackData() | String | 回调数据(链接被点击时携带) |
MenuUpdateEvent
修改 C2C 自定义菜单前触发。取消可阻止修改操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getMenu() | Menu | 新菜单配置 |
PanelCreateEvent
创建指令面板前触发。取消可阻止创建操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getScope() | String | 生效场景("c2c" / "group") |
getTargetType() | String | 作用范围("all" / "specific") |
getUserOpenids() | List<String> | 关联用户列表(C2C + specific 时有效) |
getGroupOpenids() | List<String> | 关联群列表(group + specific 时有效) |
getPanel() | Panel | 面板配置 |
PanelUpdateEvent
修改指令面板前触发。取消可阻止修改操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getPanelId() | String | 面板 ID |
getPanel() | Panel | 新面板配置 |
PanelDeleteEvent
删除指令面板前触发。取消可阻止删除操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getPanelId() | String | 面板 ID |
PanelTargetUpdateEvent
修改指令面板关联对象前触发。取消可阻止修改操作。
| 方法 | 返回类型 | 说明 |
|---|---|---|
getPanelId() | String | 面板 ID |
getRequest() | PanelTargetRequest | 关联对象修改请求(含 op、userOpenids、groupOpenids) |
