Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/更新日志.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
V7.12.11
更新时间 2026-05-03

* OneBot 修复 send_group_ai_record API 返回无效的 message_id

=================
V7.12.10
更新时间 2026-04-30

Expand Down
2 changes: 1 addition & 1 deletion package-dist.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"name":"llonebot-dist","version":"7.12.10","type":"module","description":"","main":"llbot.js","author":"linyuchen","repository":{"type":"git","url":"https://github.com/LLOneBot/LuckyLilliaBot"}}
{"name":"llonebot-dist","version":"7.12.11","type":"module","description":"","main":"llbot.js","author":"linyuchen","repository":{"type":"git","url":"https://github.com/LLOneBot/LuckyLilliaBot"}}
4 changes: 3 additions & 1 deletion src/main/pmhq/mixins/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,17 @@ export function MessageMixin<T extends new (...args: any[]) => PMHQBase>(Base: T
}

async getGroupGenerateAiRecord(groupId: number, character: string, text: string, chatType: number) {
const msgRandom = randomBytes(4).readUInt32BE(0)
const body = Oidb.GetGroupGenerateAiRecordReq.encode({
groupId,
voiceId: character,
text,
chatType,
clientMsgInfo: { msgRandom: randomBytes(4).readUInt32BE(0) },
clientMsgInfo: { msgRandom },
})
const data = Oidb.Base.encode({ command: 0x929b, subCommand: 0, body })
await this.httpSendPB('OidbSvcTrpcTcp.0x929b_0', data)
return { msgRandom }
}
}
}
16 changes: 16 additions & 0 deletions src/ntqqapi/services/NodeIKernelMsgService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,20 @@ export interface NodeIKernelMsgService {
setContactLocalTop(peer: Peer, isTop: boolean): Promise<GeneralCallResult>

sendShowInputStatusReq(chatType: ChatType, eventType: number, toUid: string): Promise<GeneralCallResult>

clickInlineKeyboardButton(inlineKeyboardClickInfo: {
guildId: string
dmFlag: number
peerId: string
chatType: ChatType
botAppid: string
msgSeq: string
buttonId: string
callback_data: string
}): Promise<GeneralCallResult & {
status: number
promptText: string
promptType: number
promptIcon: number
}>
}
13 changes: 11 additions & 2 deletions src/onebot11/action/llbot/msg/SendGroupAiRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@ export class SendGroupAiRecord extends BaseAction<Payload, Response> {
})

async _handle(payload: Payload) {
await this.ctx.pmhq.getGroupGenerateAiRecord(+payload.group_id, payload.character, payload.text, +payload.chat_type)
return { message_id: 0 }
const res = await this.ctx.pmhq.getGroupGenerateAiRecord(+payload.group_id, payload.character, payload.text, +payload.chat_type)
const targetMsgRandom = res.msgRandom.toString()
const { promise, resolve } = Promise.withResolvers<Response>()
const dispose = this.ctx.on('nt/message-created', (msg) => {
if (msg.msgRandom === targetMsgRandom) {
dispose()
const shortId = this.ctx.store.createMsgShortId(msg)
resolve({ message_id: shortId })
}
})
return promise
Comment on lines +26 to +35
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): 如果对应的 nt/message-created 事件未被触发,这个 promise 可能永远不会被 settle。

如果 AI 记录消息从未被创建,或者事件被错过(例如网络问题、服务错误、进程重启),这个 promise 将既不会 resolve 也不会 reject,使得该操作无限期地挂起。建议添加超时和/或显式的错误路径(例如在 N 秒后 reject 并清理监听器),这样调用方可以处理失败,而不是一直被挂住。

Original comment in English

suggestion (bug_risk): The promise may never settle if the corresponding nt/message-created event is not emitted.

If the AI record message is never created or the event is missed (e.g., network issue, service error, process restart), this promise will never resolve or reject, leaving the action hanging indefinitely. Consider adding a timeout and/or explicit error path (e.g., reject after N seconds and dispose the listener) so callers can handle failures instead of hanging forever.

}
}
10 changes: 7 additions & 3 deletions src/onebot11/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,16 @@ export namespace OB11Entities {
} else {
operatorUin = await ctx.ntUserApi.getUinByUid(revokeElement.operatorUid)
}
if (msg.senderUin === '0' || !msg.senderUin) {
ctx.logger.warn(`发生异常 senderUin: ${msg.senderUin}`)
let senderUin = msg.senderUin
if (msg.senderUin === '0') {
senderUin = await ctx.ntUserApi.getUinByUid(revokeElement.origMsgSenderUid)
if (revokeElement.operatorUid === revokeElement.origMsgSenderUid) {
operatorUin = senderUin
}
}
return new OB11GroupRecallNoticeEvent(
Number(msg.peerUid),
Number(msg.senderUin),
Number(senderUin),
Number(operatorUin),
shortId,
)
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const version = '7.12.10'
export const version = '7.12.11'
Loading