fix(bridge): preserve full ext-biz-info on media upload round-trip
The NTV2 upload-response decoder used stub schemas that omitted fields
QQ NT echoes back (notably video.fromScene/toScene, pic.fromScene/
toScene/oldFileId, the ptt scene/waveform set), so finalizeMediaMsgInfo
re-encoded the commonElem.pbElem with those fields missing. For c2c
video this triggered `send private message rejected: result=79` on
every send_private_msg [{type:'video'}] call — the upload itself
fast-pathed fine but the follow-up SendMessage was rejected by NT.
Drop the duplicate NTV2 placeholder schemas and route NTV2ExtBizInfo
through the element-side PicExtBizInfo / VideoExtBizInfo /
PttExtBizInfo, which are field-complete. Also zero out the main
video sub-file's width/height/time/videoFormat in the upload request
to mirror NapCat — those fields belong on the thumb, not the source
mp4, and non-zero values trip schema validation on c2c sends.
This commit is contained in:
@@ -460,10 +460,14 @@ export async function uploadVideoMsgInfo(
|
||||
fileHash: video.md5Hex,
|
||||
fileSha1: video.sha1Hex,
|
||||
fileName: 'nya.mp4',
|
||||
type: { type: 2, picFormat: 0, videoFormat: video.videoFormat, voiceFormat: 0 },
|
||||
height: video.height,
|
||||
width: video.width,
|
||||
time: video.duration,
|
||||
// NapCat sends type.videoFormat=0 and width/height/time=0
|
||||
// for the main video sub-file (only the thumb carries
|
||||
// dimensions). The QQ NT server treats non-zero values
|
||||
// here as a schema mismatch on c2c sends.
|
||||
type: { type: 2, picFormat: 0, videoFormat: 0, voiceFormat: 0 },
|
||||
height: 0,
|
||||
width: 0,
|
||||
time: 0,
|
||||
original: 0,
|
||||
},
|
||||
subFileType: 0,
|
||||
|
||||
@@ -234,35 +234,17 @@ export const NTV2UploadInfoSchema = {
|
||||
subFileType: { field: 2, type: 'uint32' as const },
|
||||
} satisfies ProtoSchema;
|
||||
|
||||
export const NTV2PicReserveC2CSchema = {
|
||||
subType: { field: 1, type: 'uint32' as const },
|
||||
} satisfies ProtoSchema;
|
||||
|
||||
export const NTV2PicReserveTroopSchema = {
|
||||
subType: { field: 1, type: 'uint32' as const },
|
||||
} satisfies ProtoSchema;
|
||||
|
||||
export const NTV2PicExtBizInfoSchema = {
|
||||
bizType: { field: 1, type: 'uint32' as const },
|
||||
textSummary: { field: 2, type: 'string' as const },
|
||||
reserveC2c: { field: 11, type: 'message' as const, schema: NTV2PicReserveC2CSchema },
|
||||
reserveTroop: { field: 12, type: 'message' as const, schema: NTV2PicReserveTroopSchema },
|
||||
} satisfies ProtoSchema;
|
||||
|
||||
export const NTV2VideoExtBizInfoSchema = {
|
||||
bytesPbReserve: { field: 3, type: 'bytes' as const },
|
||||
} satisfies ProtoSchema;
|
||||
|
||||
export const NTV2PttExtBizInfoSchema = {
|
||||
bytesReserve: { field: 11, type: 'bytes' as const },
|
||||
bytesPbReserve: { field: 12, type: 'bytes' as const },
|
||||
bytesGeneralFlags: { field: 13, type: 'bytes' as const },
|
||||
} satisfies ProtoSchema;
|
||||
|
||||
// The NTV2 upload request + response carry the same ExtBizInfo shape that
|
||||
// element-side incoming-message decoding uses. Pulling those schemas in
|
||||
// directly (instead of redefining stub copies) keeps the round-trip
|
||||
// `server response → finalizeMediaMsgInfo → commonElem.pbElem` from
|
||||
// silently dropping fields the QQ NT server later validates against —
|
||||
// the video `fromScene`/`toScene` drop was already responsible for c2c
|
||||
// `result=79` rejections on `send_private_msg [{type:'video'}]`.
|
||||
export const NTV2ExtBizInfoSchema = {
|
||||
pic: { field: 1, type: 'message' as const, schema: NTV2PicExtBizInfoSchema },
|
||||
video: { field: 2, type: 'message' as const, schema: NTV2VideoExtBizInfoSchema },
|
||||
ptt: { field: 3, type: 'message' as const, schema: NTV2PttExtBizInfoSchema },
|
||||
pic: { field: 1, type: 'message' as const, schema: PicExtBizInfoSchema },
|
||||
video: { field: 2, type: 'message' as const, schema: VideoExtBizInfoSchema },
|
||||
ptt: { field: 3, type: 'message' as const, schema: PttExtBizInfoSchema },
|
||||
busiType: { field: 10, type: 'uint32' as const },
|
||||
} satisfies ProtoSchema;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user