@agent-wechat/agent-wechat 1.0.0-beta.7 → 1.0.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +24 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -448,15 +448,16 @@ var NativeWeChatClient = class {
|
|
|
448
448
|
}
|
|
449
449
|
async mediaContent(accountId, assetId, options = {}) {
|
|
450
450
|
const max = options.maxBytes ?? 128 * 1024 * 1024;
|
|
451
|
-
if (!Number.isInteger(max) || max < 1 || max > 128 * 1024 * 1024 || options.range && !/^bytes=(?:\d+-\d*|-\d+)$/.test(options.range))
|
|
451
|
+
if (!Number.isInteger(max) || max < 1 || max > 128 * 1024 * 1024 || options.range && !/^bytes=(?:\d+-\d*|-\d+)$/.test(options.range) || options.representation != null && !["original", "preview"].includes(options.representation))
|
|
452
452
|
throw new Error("Invalid bounded content request");
|
|
453
|
-
const
|
|
453
|
+
const query = options.representation === "preview" ? "?representation=preview" : "";
|
|
454
|
+
const response = await this.response(`v1/accounts/${id(accountId)}/media/${id(assetId)}/content${query}`, { signal: options.signal, headers: options.range ? { Range: options.range } : {} });
|
|
454
455
|
const length = response.headers.get("content-length");
|
|
455
456
|
if (length && (!/^\d+$/.test(length) || Number(length) > max)) {
|
|
456
457
|
await response.body?.cancel();
|
|
457
458
|
throw new Error("Native media response exceeds its bound");
|
|
458
459
|
}
|
|
459
|
-
return { bytes: await this.readBounded(response, max), contentType: response.headers.get("content-type") ?? "application/octet-stream", etag: response.headers.get("etag"), contentRange: response.headers.get("content-range"), status: response.status };
|
|
460
|
+
return { bytes: await this.readBounded(response, max), contentType: response.headers.get("content-type") ?? "application/octet-stream", etag: response.headers.get("etag"), contentRange: response.headers.get("content-range"), sourceSha256: response.headers.get("x-source-sha256"), status: response.status };
|
|
460
461
|
}
|
|
461
462
|
markRead(accountId, threadId2, expectedVersion) {
|
|
462
463
|
if (typeof expectedVersion !== "string" || !expectedVersion || expectedVersion.length > 128)
|
|
@@ -1285,13 +1286,27 @@ async function prepareNativeAttachment(params) {
|
|
|
1285
1286
|
};
|
|
1286
1287
|
let suppliedPath = saved.path, suppliedMime = mime, suppliedHash = hash, suppliedLength = content.bytes.length;
|
|
1287
1288
|
let body = renderAttachmentBody("", attachment);
|
|
1288
|
-
if (attachmentKind === "image" && params.cfg) {
|
|
1289
|
-
|
|
1290
|
-
|
|
1289
|
+
if (attachmentKind === "image" && (params.cfg || mime === "image/x-wxgf")) {
|
|
1290
|
+
let imageBytes = Buffer.from(content.bytes), imageMime = mime;
|
|
1291
|
+
const wxgf = mime === "image/x-wxgf";
|
|
1292
|
+
if (wxgf) {
|
|
1293
|
+
const preview = asset.preview;
|
|
1294
|
+
if (!preview || preview.sourceSha256 !== hash || !/^[a-f0-9]{64}$/.test(preview.sha256) || !Number.isInteger(preview.byteLength) || preview.byteLength <= 0 || preview.byteLength > 16 * 1024 * 1024 || !["image/jpeg", "image/png"].includes(preview.contentType)) throw Error("Native WXGF preview metadata did not verify");
|
|
1295
|
+
await authorize();
|
|
1296
|
+
const derived = await client.mediaContent(accountId, asset.id, { maxBytes: preview.byteLength, representation: "preview", signal: params.signal });
|
|
1297
|
+
guard();
|
|
1298
|
+
const derivedMime = derived.contentType.split(";", 1)[0].trim().toLowerCase();
|
|
1299
|
+
if (derived.sourceSha256 !== hash || derivedMime !== preview.contentType || derived.bytes.length !== preview.byteLength || createHash4("sha256").update(derived.bytes).digest("hex") !== preview.sha256) throw Error("Native WXGF preview integrity did not verify");
|
|
1300
|
+
imageBytes = Buffer.from(derived.bytes);
|
|
1301
|
+
imageMime = derivedMime;
|
|
1302
|
+
}
|
|
1303
|
+
const representation = await prepareImageRepresentation(imageBytes, imageMime, params.cfg);
|
|
1304
|
+
if (wxgf || representation.preview) {
|
|
1305
|
+
const extension = representation.mime === "image/png" ? "png" : "jpg";
|
|
1291
1306
|
const normalized = await saveManagedAttachment({
|
|
1292
1307
|
data: representation.bytes.toString("base64"),
|
|
1293
1308
|
mime: representation.mime,
|
|
1294
|
-
filename: `${filename}.model
|
|
1309
|
+
filename: `${filename}.model.${extension}`,
|
|
1295
1310
|
maxBytes: 5 * 1024 * 1024,
|
|
1296
1311
|
saveMediaBuffer: core.channel.media.saveMediaBuffer
|
|
1297
1312
|
});
|
|
@@ -1299,7 +1314,8 @@ async function prepareNativeAttachment(params) {
|
|
|
1299
1314
|
suppliedMime = representation.mime;
|
|
1300
1315
|
suppliedHash = normalized.sha256;
|
|
1301
1316
|
suppliedLength = normalized.size;
|
|
1302
|
-
body += `
|
|
1317
|
+
body += wxgf ? `
|
|
1318
|
+
[Model image: WXGF still preview; original retained separately; animation and transparency are not represented]` : `
|
|
1303
1319
|
[Model image: prepared still preview; original retained separately]`;
|
|
1304
1320
|
}
|
|
1305
1321
|
}
|