Appearance
Bngeuit API
cn.org.bukkit.bngeuit.Bngeuit 是静态门面类。绝大多数常用操作都有对应静态方法。
msgSeq 参数
所有发送方法都要求传入 msgSeq(消息序号),用于去重/排序。被动回复时可用事件中的 seq,简单场景传自增计数即可。
Bngeuit 静态方法速查
群聊 — 文本
java
Bngeuit.sendGroupText(gid, msgSeq, "你好"); // 主动发送
Bngeuit.sendGroupText(gid, msgSeq, "你好", keyboard); // 带键盘(自动以 Markdown 发送)
Bngeuit.replyGroupText(gid, msgId, msgSeq, "回复"); // 被动回复(设 msgId,不带气泡)
Bngeuit.quoteGroupText(gid, refIdx, msgSeq, "引用"); // 引用回复,带气泡(refIdx 见下)群聊 — Markdown
java
Bngeuit.sendGroupMarkdown(gid, msgSeq, "**md**");
Bngeuit.sendGroupMarkdown(gid, msgSeq, "**md**", keyboard);
Bngeuit.replyGroupMarkdown(gid, msgId, msgSeq, "**md**");
Bngeuit.quoteGroupMarkdown(gid, refIdx, msgSeq, "**md**");群聊 — 富媒体(ByUrl 公网 URL / ByFile 本地文件)
java
Bngeuit.sendGroupImageByUrl(gid, msgSeq, "https://.../img.png"); // 图片
Bngeuit.sendGroupImageByFile(gid, msgSeq, new File("img.png")); // 本地文件(自动分片上传)
Bngeuit.sendGroupVideoByUrl(gid, msgSeq, "https://.../video.mp4");
Bngeuit.sendGroupVideoByFile(gid, msgSeq, new File("video.mp4"));
Bngeuit.sendGroupVoiceByUrl(gid, msgSeq, "https://.../voice.silk");
Bngeuit.sendGroupVoiceByFile(gid, msgSeq, new File("voice.silk"));
Bngeuit.sendGroupFileByUrl(gid, msgSeq, "https://.../file.rar");
Bngeuit.sendGroupFileByFile(gid, msgSeq, new File("file.rar"));群聊 — 卡片
java
Bngeuit.sendGroupCard(gid, msgSeq, "标题", "描述", "图片URL", "跳转URL");
// 跳转 URL 需 QQ 白名单域名,传 null 可展示不可点击私聊 — 文本
java
Bngeuit.sendC2CText(openid, msgSeq, "你好");
Bngeuit.sendC2CText(openid, msgSeq, "你好", keyboard);
Bngeuit.replyC2CText(openid, msgId, msgSeq, "回复");
Bngeuit.quoteC2CText(openid, refIdx, msgSeq, "引用");私聊 — Markdown
java
Bngeuit.sendC2CMarkdown(openid, msgSeq, "**md**");
Bngeuit.sendC2CMarkdown(openid, msgSeq, "**md**", keyboard);
Bngeuit.replyC2CMarkdown(openid, msgId, msgSeq, "**md**");
Bngeuit.quoteC2CMarkdown(openid, refIdx, msgSeq, "**md**");私聊 — 富媒体
java
Bngeuit.sendC2CImageByUrl(openid, msgSeq, "https://.../img.png");
Bngeuit.sendC2CImageByFile(openid, msgSeq, new File("img.png"));
Bngeuit.sendC2CVideoByUrl(openid, msgSeq, "https://.../video.mp4");
Bngeuit.sendC2CVideoByFile(openid, msgSeq, new File("video.mp4"));
Bngeuit.sendC2CVoiceByUrl(openid, msgSeq, "https://.../voice.silk");
Bngeuit.sendC2CVoiceByFile(openid, msgSeq, new File("voice.silk"));
Bngeuit.sendC2CFileByUrl(openid, msgSeq, "https://.../file.rar");
Bngeuit.sendC2CFileByFile(openid, msgSeq, new File("file.rar"));其他
java
Bngeuit.sendC2CTyping(openid, 5); // "正在输入..."
Bngeuit.deleteGroupMessage(gid, messageId); // 撤回群消息
Bngeuit.deleteC2CMessage(openid, messageId); // 撤回私聊
Bngeuit.respondInteraction(interactionId, BotApi.InteractionResponseCode.SUCCESS); // 互动响应时间工具
RFC3339 与时间戳互转(东八区):
java
// 毫秒时间戳 → RFC3339
long expireAt = System.currentTimeMillis() + 30 * 60 * 1000;
String rfc3339 = Bngeuit.toRfc3339(expireAt);
// => "2026-08-05T11:23:05+08:00"
// RFC3339 → 毫秒时间戳
long millis = Bngeuit.fromRfc3339("2026-08-05T11:23:05+08:00");
// 秒级时间戳转换
String rfc = Bngeuit.toRfc3339FromSeconds(1691234567);
long seconds = Bngeuit.fromRfc3339ToSeconds("2026-08-05T11:23:05+08:00");引用回复(quote)与被动回复(reply)
reply使用消息 ID(msg_id,ROBOT1.0_...格式),不带引用气泡。quote使用引用索引(REFIDX_...格式),带引用气泡。不是消息 ID!- 引用别人的消息:用事件
e.getMessageScene().msgIdx() - 引用自己的消息:用发送响应
resp.extInfo().refIdx()
- 引用别人的消息:用事件
高级场景:BotApi
上传、流式消息等多步操作,通过 Bngeuit.api() 获取原始 BotApi:
java
BotApi api = Bngeuit.api();
// 富媒体上传(URL 方式),返回 UploadResponse(含 fileInfo)
UploadResponse r = api.uploadGroupFile(gid, FileType.IMAGE, url, false);
UploadResponse r = api.uploadC2CFile(openid, FileType.IMAGE, url, false);
// 本地文件分片上传(自动 预上传→分片 PUT→确认→合并)
UploadResponse r = api.uploadGroupFileByFile(gid, FileType.IMAGE, new File("img.jpg"));
UploadResponse r = api.uploadC2CFileByFile(openid, FileType.IMAGE, new File("img.jpg"));
// 自定义消息
api.sendGroupMessage(GroupMessageRequest.builder()
.groupOpenid(gid).msgType(MsgType.TEXT).content("Hello").msgSeq(1).build());
// 群信息
GroupInfo info = api.getGroupInfo(gid);
BotGroupState state = api.getBotGroupState(gid);私聊流式消息
java
import cn.org.bukkit.bngeuit.dto.message.*;
import cn.org.bukkit.bngeuit.dto.message.panel.*;
StreamMessageRequest req = StreamMessageRequest.builder()
.id(msgId)
.content("**流式内容...**")
.contentType(StreamContentType.MARKDOWN) // StreamContentType.TEXT / MARKDOWN
.inputMode(InputMode.REPLACE) // InputMode.APPEND / REPLACE
.build();
api.createStreamMessage(openid, req);UploadResponse
UploadResponse 是富媒体上传的统一响应(record):
| 方法 | 返回类型 | 说明 |
|---|---|---|
fileInfo() | String | file_info,发给 media 字段用于发送 |
fileUuid() | String | 文件唯一标识 |
ttl() | int | 文件有效期(秒),0 = 可长期使用 |
id() | String | 消息 ID(仅 srv_send_msg=true 时返回) |
rawUrl() | String | 文件下载链接(分片上传合并后返回) |
互动响应码
BotApi.InteractionResponseCode:
| 枚举 | 值 | 说明 |
|---|---|---|
SUCCESS | 0 | 操作成功 |
FAILED | 1 | 操作失败 |
TOO_FREQUENT | 2 | 操作频繁 |
DUPLICATE | 3 | 重复操作 |
NO_PERMISSION | 4 | 没有权限 |
ADMIN_ONLY | 5 | 仅管理员操作 |
