mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-01-18 22:40:28 +00:00
feat: support msg_seq parameter in reply message construction
- Add optional 'seq' parameter to OB11MessageReply for using msg_seq - Prioritize seq over id for querying reply messages - Maintain backward compatibility with existing id parameter - Update type definitions across backend and frontend - Update validation schemas for message nodes close #1523
This commit is contained in:
parent
5284e0ac5a
commit
b296d50d4a
@ -587,15 +587,33 @@ export class OneBotMsgApi {
|
|||||||
return at(atQQ, uid, NTMsgAtType.ATTYPEONE, info.nick || '');
|
return at(atQQ, uid, NTMsgAtType.ATTYPEONE, info.nick || '');
|
||||||
},
|
},
|
||||||
|
|
||||||
[OB11MessageDataType.reply]: async ({ data: { id } }) => {
|
[OB11MessageDataType.reply]: async ({ data: { id, seq } }, context) => {
|
||||||
|
let replyMsg: RawMessage | undefined;
|
||||||
|
let replyMsgPeer: Peer | undefined;
|
||||||
|
|
||||||
|
// 优先使用 seq
|
||||||
|
if (seq) {
|
||||||
|
const msgList = (await this.core.apis.MsgApi.getMsgsBySeqAndCount(
|
||||||
|
context.peer, seq.toString(), 1, true, true
|
||||||
|
)).msgList;
|
||||||
|
replyMsg = msgList[0];
|
||||||
|
replyMsgPeer = context.peer;
|
||||||
|
} else if (id) {
|
||||||
|
// 降级使用 id
|
||||||
const replyMsgM = MessageUnique.getMsgIdAndPeerByShortId(parseInt(id));
|
const replyMsgM = MessageUnique.getMsgIdAndPeerByShortId(parseInt(id));
|
||||||
if (!replyMsgM) {
|
if (!replyMsgM) {
|
||||||
this.core.context.logger.logWarn('回复消息不存在', id);
|
this.core.context.logger.logWarn('回复消息不存在', id);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const replyMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(
|
replyMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(
|
||||||
replyMsgM.Peer, [replyMsgM.MsgId])).msgList[0];
|
replyMsgM.Peer, [replyMsgM.MsgId])).msgList[0];
|
||||||
return replyMsg
|
replyMsgPeer = replyMsgM.Peer;
|
||||||
|
} else {
|
||||||
|
this.core.context.logger.logWarn('回复消息缺少id或seq参数');
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return replyMsg && replyMsgPeer
|
||||||
? {
|
? {
|
||||||
elementType: ElementType.REPLY,
|
elementType: ElementType.REPLY,
|
||||||
elementId: '',
|
elementId: '',
|
||||||
@ -605,7 +623,7 @@ export class OneBotMsgApi {
|
|||||||
senderUin: replyMsg.senderUin,
|
senderUin: replyMsg.senderUin,
|
||||||
senderUinStr: replyMsg.senderUin,
|
senderUinStr: replyMsg.senderUin,
|
||||||
replyMsgClientSeq: replyMsg.clientSeq,
|
replyMsgClientSeq: replyMsg.clientSeq,
|
||||||
_replyMsgPeer: replyMsgM.Peer,
|
_replyMsgPeer: replyMsgPeer,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|||||||
@ -159,7 +159,8 @@ export interface OB11MessageAt {
|
|||||||
export interface OB11MessageReply {
|
export interface OB11MessageReply {
|
||||||
type: OB11MessageDataType.reply;
|
type: OB11MessageDataType.reply;
|
||||||
data: {
|
data: {
|
||||||
id: string;
|
id?: string; // msg_id 的短ID映射
|
||||||
|
seq?: number; // msg_seq,优先使用
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,8 @@ const messageNode = z.union([
|
|||||||
.object({
|
.object({
|
||||||
type: z.literal('reply'),
|
type: z.literal('reply'),
|
||||||
data: z.object({
|
data: z.object({
|
||||||
id: z.number(),
|
id: z.number().optional(),
|
||||||
|
seq: z.number().optional(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.describe('回复消息'),
|
.describe('回复消息'),
|
||||||
|
|||||||
@ -24,196 +24,197 @@ export type OB11SegmentType =
|
|||||||
| 'file';
|
| 'file';
|
||||||
|
|
||||||
export interface Segment {
|
export interface Segment {
|
||||||
type: OB11SegmentType
|
type: OB11SegmentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 纯文本 */
|
/** 纯文本 */
|
||||||
export interface TextSegment extends Segment {
|
export interface TextSegment extends Segment {
|
||||||
type: 'text'
|
type: 'text';
|
||||||
data: {
|
data: {
|
||||||
text: string
|
text: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** QQ表情 */
|
/** QQ表情 */
|
||||||
export interface FaceSegment extends Segment {
|
export interface FaceSegment extends Segment {
|
||||||
type: 'face'
|
type: 'face';
|
||||||
data: {
|
data: {
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 图片消息段 */
|
/** 图片消息段 */
|
||||||
export interface ImageSegment extends Segment {
|
export interface ImageSegment extends Segment {
|
||||||
type: 'image'
|
type: 'image';
|
||||||
data: {
|
data: {
|
||||||
file: string
|
file: string;
|
||||||
type?: 'flash'
|
type?: 'flash';
|
||||||
url?: string
|
url?: string;
|
||||||
cache?: 0 | 1
|
cache?: 0 | 1;
|
||||||
proxy?: 0 | 1
|
proxy?: 0 | 1;
|
||||||
timeout?: number
|
timeout?: number;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 语音消息段 */
|
/** 语音消息段 */
|
||||||
export interface RecordSegment extends Segment {
|
export interface RecordSegment extends Segment {
|
||||||
type: 'record'
|
type: 'record';
|
||||||
data: {
|
data: {
|
||||||
file: string
|
file: string;
|
||||||
magic?: 0 | 1
|
magic?: 0 | 1;
|
||||||
url?: string
|
url?: string;
|
||||||
cache?: 0 | 1
|
cache?: 0 | 1;
|
||||||
proxy?: 0 | 1
|
proxy?: 0 | 1;
|
||||||
timeout?: number
|
timeout?: number;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 短视频消息段 */
|
/** 短视频消息段 */
|
||||||
export interface VideoSegment extends Segment {
|
export interface VideoSegment extends Segment {
|
||||||
type: 'video'
|
type: 'video';
|
||||||
data: {
|
data: {
|
||||||
file: string
|
file: string;
|
||||||
url?: string
|
url?: string;
|
||||||
cache?: 0 | 1
|
cache?: 0 | 1;
|
||||||
proxy?: 0 | 1
|
proxy?: 0 | 1;
|
||||||
timeout?: number
|
timeout?: number;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @某人消息段 */
|
/** @某人消息段 */
|
||||||
export interface AtSegment extends Segment {
|
export interface AtSegment extends Segment {
|
||||||
type: 'at'
|
type: 'at';
|
||||||
data: {
|
data: {
|
||||||
qq: string | 'all'
|
qq: string | 'all';
|
||||||
name?: string
|
name?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 猜拳魔法表情消息段 */
|
/** 猜拳魔法表情消息段 */
|
||||||
export interface RpsSegment extends Segment {
|
export interface RpsSegment extends Segment {
|
||||||
type: 'rps'
|
type: 'rps';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 掷骰子魔法表情消息段 */
|
/** 掷骰子魔法表情消息段 */
|
||||||
export interface DiceSegment extends Segment {
|
export interface DiceSegment extends Segment {
|
||||||
type: 'dice'
|
type: 'dice';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 窗口抖动(戳一戳)消息段 */
|
/** 窗口抖动(戳一戳)消息段 */
|
||||||
export interface ShakeSegment extends Segment {
|
export interface ShakeSegment extends Segment {
|
||||||
type: 'shake'
|
type: 'shake';
|
||||||
data: object
|
data: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 戳一戳消息段 */
|
/** 戳一戳消息段 */
|
||||||
export interface PokeSegment extends Segment {
|
export interface PokeSegment extends Segment {
|
||||||
type: 'poke'
|
type: 'poke';
|
||||||
data: {
|
data: {
|
||||||
type: string
|
type: string;
|
||||||
id: string
|
id: string;
|
||||||
name?: string
|
name?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 匿名发消息消息段 */
|
/** 匿名发消息消息段 */
|
||||||
export interface AnonymousSegment extends Segment {
|
export interface AnonymousSegment extends Segment {
|
||||||
type: 'anonymous'
|
type: 'anonymous';
|
||||||
data: {
|
data: {
|
||||||
ignore?: 0 | 1
|
ignore?: 0 | 1;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 链接分享消息段 */
|
/** 链接分享消息段 */
|
||||||
export interface ShareSegment extends Segment {
|
export interface ShareSegment extends Segment {
|
||||||
type: 'share'
|
type: 'share';
|
||||||
data: {
|
data: {
|
||||||
url: string
|
url: string;
|
||||||
title: string
|
title: string;
|
||||||
content?: string
|
content?: string;
|
||||||
image?: string
|
image?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 推荐好友/群消息段 */
|
/** 推荐好友/群消息段 */
|
||||||
export interface ContactSegment extends Segment {
|
export interface ContactSegment extends Segment {
|
||||||
type: 'contact'
|
type: 'contact';
|
||||||
data: {
|
data: {
|
||||||
type: 'qq' | 'group'
|
type: 'qq' | 'group';
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 位置消息段 */
|
/** 位置消息段 */
|
||||||
export interface LocationSegment extends Segment {
|
export interface LocationSegment extends Segment {
|
||||||
type: 'location'
|
type: 'location';
|
||||||
data: {
|
data: {
|
||||||
lat: string
|
lat: string;
|
||||||
lon: string
|
lon: string;
|
||||||
title?: string
|
title?: string;
|
||||||
content?: string
|
content?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 音乐分享消息段 */
|
/** 音乐分享消息段 */
|
||||||
export interface MusicSegment extends Segment {
|
export interface MusicSegment extends Segment {
|
||||||
type: 'music'
|
type: 'music';
|
||||||
data: {
|
data: {
|
||||||
type: 'qq' | '163' | 'xm'
|
type: 'qq' | '163' | 'xm';
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 音乐自定义分享消息段 */
|
/** 音乐自定义分享消息段 */
|
||||||
export interface CustomMusicSegment extends Segment {
|
export interface CustomMusicSegment extends Segment {
|
||||||
type: 'music'
|
type: 'music';
|
||||||
data: {
|
data: {
|
||||||
type: 'custom'
|
type: 'custom';
|
||||||
url: string
|
url: string;
|
||||||
audio: string
|
audio: string;
|
||||||
title: string
|
title: string;
|
||||||
content?: string
|
content?: string;
|
||||||
image?: string
|
image?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 回复消息段 */
|
/** 回复消息段 */
|
||||||
export interface ReplySegment extends Segment {
|
export interface ReplySegment extends Segment {
|
||||||
type: 'reply'
|
type: 'reply';
|
||||||
data: {
|
data: {
|
||||||
id: string
|
id?: string; // msg_id 的短ID映射
|
||||||
}
|
seq?: number; // msg_seq,优先使用
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileSegment extends Segment {
|
export interface FileSegment extends Segment {
|
||||||
type: 'file'
|
type: 'file';
|
||||||
data: {
|
data: {
|
||||||
file: string
|
file: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 合并转发消息段 */
|
/** 合并转发消息段 */
|
||||||
export interface ForwardSegment extends Segment {
|
export interface ForwardSegment extends Segment {
|
||||||
type: 'forward'
|
type: 'forward';
|
||||||
data: {
|
data: {
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** XML消息段 */
|
/** XML消息段 */
|
||||||
export interface XmlSegment extends Segment {
|
export interface XmlSegment extends Segment {
|
||||||
type: 'xml'
|
type: 'xml';
|
||||||
data: {
|
data: {
|
||||||
data: string
|
data: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** JSON消息段 */
|
/** JSON消息段 */
|
||||||
export interface JsonSegment extends Segment {
|
export interface JsonSegment extends Segment {
|
||||||
type: 'json'
|
type: 'json';
|
||||||
data: {
|
data: {
|
||||||
data: string
|
data: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** OneBot11消息段 */
|
/** OneBot11消息段 */
|
||||||
@ -242,23 +243,23 @@ export type OB11SegmentBase =
|
|||||||
|
|
||||||
/** 合并转发已有消息节点消息段 */
|
/** 合并转发已有消息节点消息段 */
|
||||||
export interface DirectNodeSegment extends Segment {
|
export interface DirectNodeSegment extends Segment {
|
||||||
type: 'node'
|
type: 'node';
|
||||||
data: {
|
data: {
|
||||||
id: string
|
id: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 合并转发自定义节点消息段 */
|
/** 合并转发自定义节点消息段 */
|
||||||
export interface CustomNodeSegments extends Segment {
|
export interface CustomNodeSegments extends Segment {
|
||||||
type: 'node'
|
type: 'node';
|
||||||
data: {
|
data: {
|
||||||
user_id: string
|
user_id: string;
|
||||||
nickname: string
|
nickname: string;
|
||||||
content: OB11Segment[]
|
content: OB11Segment[];
|
||||||
prompt?: string
|
prompt?: string;
|
||||||
summary?: string
|
summary?: string;
|
||||||
source?: string
|
source?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 合并转发消息段 */
|
/** 合并转发消息段 */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user