fengming 0.3.3 → 0.3.4
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/CHANGELOG.md +2 -3
- package/dist/build-info.json +2 -2
- package/dist/{bundled-channel-config-schema-DpdKMATU.d.ts → bundled-channel-config-schema-Bte--ZlY.d.ts} +26 -26
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/cli-startup-metadata.json +8 -8
- package/dist/control-ui/assets/{activity-B7yRLbf3.js → activity-CCu43qU8.js} +2 -2
- package/dist/control-ui/assets/{agents-E-3DAkaW.js → agents-DCvsB0yO.js} +2 -2
- package/dist/control-ui/assets/{channels-D0c7A9OX.js → channels-CpM2j5xT.js} +2 -2
- package/dist/control-ui/assets/{cron-B54j2Vmo.js → cron-CLXNfwYa.js} +2 -2
- package/dist/control-ui/assets/{debug-CRcGYNA9.js → debug-BcJ34lrC.js} +2 -2
- package/dist/control-ui/assets/{index-bZJJ7U8q.js → index-CuBn2YpX.js} +4 -4
- package/dist/control-ui/assets/{instances-RcBeqNzx.js → instances-Bu6NM_Hs.js} +2 -2
- package/dist/control-ui/assets/{nodes-BoWRh42t.js → nodes-Bd1WzVLK.js} +2 -2
- package/dist/control-ui/assets/{sessions-BmRQ932H.js → sessions-C2r8pbt7.js} +2 -2
- package/dist/control-ui/assets/{skills-BDn45kHZ.js → skills-DIjn93ee.js} +2 -2
- package/dist/control-ui/assets/{workboard-BwbcNuC5.js → workboard-CHb0if1l.js} +2 -2
- package/dist/control-ui/index.html +1 -1
- package/dist/control-ui/sw.js +1 -1
- package/dist/extensions/weixin/index.js +6 -6
- package/dist/gateway/protocol/index.d.ts +1 -1
- package/dist/{index-DhOQs6M_.d.ts → index-AZzJCgph.d.ts} +45 -45
- package/dist/{monitor-HjEwlqJs.js → monitor-2_c2Ttjf.js} +1 -1
- package/dist/plugin-sdk/.boundary-entry-shims.stamp +1 -1
- package/dist/plugin-sdk/agent-config-primitives.d.ts +1 -1
- package/dist/plugin-sdk/{bundled-channel-config-schema-C3pWWvwG.d.ts → bundled-channel-config-schema-UtIBjviA.d.ts} +40 -40
- package/dist/plugin-sdk/bundled-channel-config-schema.d.ts +3 -3
- package/dist/plugin-sdk/channel-config-primitives.d.ts +2 -2
- package/dist/plugin-sdk/channel-config-schema-legacy.d.ts +3 -3
- package/dist/plugin-sdk/channel-config-schema.d.ts +2 -2
- package/dist/plugin-sdk/channel-core.d.ts +1 -1
- package/dist/plugin-sdk/channel-plugin-common.d.ts +1 -1
- package/dist/plugin-sdk/compat.d.ts +2 -2
- package/dist/plugin-sdk/{config-schema-D7cABQ6o.d.ts → config-schema-DUddICQM.d.ts} +1 -1
- package/dist/plugin-sdk/config-schema.d.ts +2 -2
- package/dist/plugin-sdk/core.d.ts +1 -1
- package/dist/plugin-sdk/discord.d.ts +2 -2
- package/dist/plugin-sdk/tts-runtime.d.ts +1 -1
- package/dist/plugin-sdk/{zod-schema.core-CwBNqcXp.d.ts → zod-schema.core-B4_b2R5K.d.ts} +1 -1
- package/dist/plugins/runtime/index.js +2 -2
- package/dist/postinstall-inventory.json +19 -19
- package/dist/{send-media-Bl2ryo6a.js → send-media-OG5Gd31l.js} +252 -252
- package/dist/{zod-schema.core-Cuz0lz6m.d.ts → zod-schema.core-BGLctDlK.d.ts} +1 -1
- package/package.json +1 -1
|
@@ -400,7 +400,7 @@
|
|
|
400
400
|
"dist/bundled-CrjoAisB.js",
|
|
401
401
|
"dist/bundled-capability-runtime-CZQb-ZAX.js",
|
|
402
402
|
"dist/bundled-channel-config-schema-BrGYOHFf.js",
|
|
403
|
-
"dist/bundled-channel-config-schema-
|
|
403
|
+
"dist/bundled-channel-config-schema-Bte--ZlY.d.ts",
|
|
404
404
|
"dist/bundled-compat-CaniuKBf.js",
|
|
405
405
|
"dist/bundled-dir-BAh7mvXE.js",
|
|
406
406
|
"dist/bundled-dir-BVueUQUl.js",
|
|
@@ -847,30 +847,30 @@
|
|
|
847
847
|
"dist/control-ui-links-DxnAapN0.js",
|
|
848
848
|
"dist/control-ui-shared-AfP1FlbS.js",
|
|
849
849
|
"dist/control-ui/apple-touch-icon.png",
|
|
850
|
-
"dist/control-ui/assets/activity-
|
|
851
|
-
"dist/control-ui/assets/agents-
|
|
850
|
+
"dist/control-ui/assets/activity-CCu43qU8.js",
|
|
851
|
+
"dist/control-ui/assets/agents-DCvsB0yO.js",
|
|
852
852
|
"dist/control-ui/assets/channel-config-extras-GDGUjA2T.js",
|
|
853
|
-
"dist/control-ui/assets/channels-
|
|
853
|
+
"dist/control-ui/assets/channels-CpM2j5xT.js",
|
|
854
854
|
"dist/control-ui/assets/config-runtime-CCw2hptH.js",
|
|
855
|
-
"dist/control-ui/assets/cron-
|
|
856
|
-
"dist/control-ui/assets/debug-
|
|
855
|
+
"dist/control-ui/assets/cron-CLXNfwYa.js",
|
|
856
|
+
"dist/control-ui/assets/debug-BcJ34lrC.js",
|
|
857
857
|
"dist/control-ui/assets/gateway-runtime-CMyVbEq5.js",
|
|
858
858
|
"dist/control-ui/assets/i18n-BWPaSddY.js",
|
|
859
859
|
"dist/control-ui/assets/index-CA6DU6Rq.css",
|
|
860
|
-
"dist/control-ui/assets/index-
|
|
861
|
-
"dist/control-ui/assets/instances-
|
|
860
|
+
"dist/control-ui/assets/index-CuBn2YpX.js",
|
|
861
|
+
"dist/control-ui/assets/instances-Bu6NM_Hs.js",
|
|
862
862
|
"dist/control-ui/assets/lit-runtime-DA0-mbwP.js",
|
|
863
863
|
"dist/control-ui/assets/logs-atEFsTJJ.js",
|
|
864
864
|
"dist/control-ui/assets/markdown-runtime-C9Jq8Bu5.js",
|
|
865
|
-
"dist/control-ui/assets/nodes-
|
|
865
|
+
"dist/control-ui/assets/nodes-Bd1WzVLK.js",
|
|
866
866
|
"dist/control-ui/assets/preview-BBw3vauN.js",
|
|
867
867
|
"dist/control-ui/assets/push-subscription-CY8GxC_U.js",
|
|
868
868
|
"dist/control-ui/assets/rolldown-runtime-QTnfLwEv.js",
|
|
869
|
-
"dist/control-ui/assets/sessions-
|
|
870
|
-
"dist/control-ui/assets/skills-
|
|
869
|
+
"dist/control-ui/assets/sessions-C2r8pbt7.js",
|
|
870
|
+
"dist/control-ui/assets/skills-DIjn93ee.js",
|
|
871
871
|
"dist/control-ui/assets/skills-shared-lQxAuc7D.js",
|
|
872
872
|
"dist/control-ui/assets/string-coerce-BuYUxt7q.js",
|
|
873
|
-
"dist/control-ui/assets/workboard-
|
|
873
|
+
"dist/control-ui/assets/workboard-CHb0if1l.js",
|
|
874
874
|
"dist/control-ui/favicon-32.png",
|
|
875
875
|
"dist/control-ui/favicon.ico",
|
|
876
876
|
"dist/control-ui/favicon.svg",
|
|
@@ -1935,11 +1935,11 @@
|
|
|
1935
1935
|
"dist/includes-C7LBtYMm.js",
|
|
1936
1936
|
"dist/includes-scan-CA6ruuex.js",
|
|
1937
1937
|
"dist/index-4u9MHter.d.ts",
|
|
1938
|
+
"dist/index-AZzJCgph.d.ts",
|
|
1938
1939
|
"dist/index-B0VJdRJQ.d.ts",
|
|
1939
1940
|
"dist/index-BVVgDSdq.d.ts",
|
|
1940
1941
|
"dist/index-B_h1B9_Z.d.ts",
|
|
1941
1942
|
"dist/index-DUn76vuX.d.ts",
|
|
1942
|
-
"dist/index-DhOQs6M_.d.ts",
|
|
1943
1943
|
"dist/index.d.ts",
|
|
1944
1944
|
"dist/index.js",
|
|
1945
1945
|
"dist/infra-runtime-CGD3RE_2.js",
|
|
@@ -2424,8 +2424,8 @@
|
|
|
2424
2424
|
"dist/models-pctWuOlw.js",
|
|
2425
2425
|
"dist/module-export-COvD9dVR.js",
|
|
2426
2426
|
"dist/module-loader-BF97Ap2W.js",
|
|
2427
|
+
"dist/monitor-2_c2Ttjf.js",
|
|
2427
2428
|
"dist/monitor-7tD_FE_5.js",
|
|
2428
|
-
"dist/monitor-HjEwlqJs.js",
|
|
2429
2429
|
"dist/monitor.account-D0F9tnWD.js",
|
|
2430
2430
|
"dist/monitor.state-DY2Uh_tH.js",
|
|
2431
2431
|
"dist/moonshot-thinking-BuCk-RcD.d.ts",
|
|
@@ -2785,7 +2785,7 @@
|
|
|
2785
2785
|
"dist/plugin-sdk/browser-config.js",
|
|
2786
2786
|
"dist/plugin-sdk/btw-command-DSA7-cRy.d.ts",
|
|
2787
2787
|
"dist/plugin-sdk/bundle-mcp-DABlFCpS.d.ts",
|
|
2788
|
-
"dist/plugin-sdk/bundled-channel-config-schema-
|
|
2788
|
+
"dist/plugin-sdk/bundled-channel-config-schema-UtIBjviA.d.ts",
|
|
2789
2789
|
"dist/plugin-sdk/bundled-channel-config-schema.d.ts",
|
|
2790
2790
|
"dist/plugin-sdk/bundled-channel-config-schema.js",
|
|
2791
2791
|
"dist/plugin-sdk/call-CNN79zs_.d.ts",
|
|
@@ -2949,7 +2949,7 @@
|
|
|
2949
2949
|
"dist/plugin-sdk/config-runtime-DvKiQ9x5.d.ts",
|
|
2950
2950
|
"dist/plugin-sdk/config-runtime.d.ts",
|
|
2951
2951
|
"dist/plugin-sdk/config-runtime.js",
|
|
2952
|
-
"dist/plugin-sdk/config-schema-
|
|
2952
|
+
"dist/plugin-sdk/config-schema-DUddICQM.d.ts",
|
|
2953
2953
|
"dist/plugin-sdk/config-schema-DuJUjn6k.d.ts",
|
|
2954
2954
|
"dist/plugin-sdk/config-schema.d.ts",
|
|
2955
2955
|
"dist/plugin-sdk/config-schema.js",
|
|
@@ -3915,7 +3915,7 @@
|
|
|
3915
3915
|
"dist/plugin-sdk/zalouser.d.ts",
|
|
3916
3916
|
"dist/plugin-sdk/zalouser.js",
|
|
3917
3917
|
"dist/plugin-sdk/zod-schema.agent-runtime-DWbjdB_w.d.ts",
|
|
3918
|
-
"dist/plugin-sdk/zod-schema.core-
|
|
3918
|
+
"dist/plugin-sdk/zod-schema.core-B4_b2R5K.d.ts",
|
|
3919
3919
|
"dist/plugin-sdk/zod-schema.proxy-B1XBkex5.d.ts",
|
|
3920
3920
|
"dist/plugin-sdk/zod.d.ts",
|
|
3921
3921
|
"dist/plugin-sdk/zod.js",
|
|
@@ -4601,7 +4601,7 @@
|
|
|
4601
4601
|
"dist/send-aTxtLkJm.js",
|
|
4602
4602
|
"dist/send-deps-B-rmeTVl.js",
|
|
4603
4603
|
"dist/send-deps-BaEC80iY.d.ts",
|
|
4604
|
-
"dist/send-media-
|
|
4604
|
+
"dist/send-media-OG5Gd31l.js",
|
|
4605
4605
|
"dist/send-policy-cLIJehRZ.js",
|
|
4606
4606
|
"dist/send-qwDMMnM6.js",
|
|
4607
4607
|
"dist/send-result-BWRKr16H.js",
|
|
@@ -5395,8 +5395,8 @@
|
|
|
5395
5395
|
"dist/zod-schema.agent-runtime-CggBNRtv.d.ts",
|
|
5396
5396
|
"dist/zod-schema.agent-runtime-DBnyDRDh.js",
|
|
5397
5397
|
"dist/zod-schema.channels-config-CxeJaJgn.js",
|
|
5398
|
+
"dist/zod-schema.core-BGLctDlK.d.ts",
|
|
5398
5399
|
"dist/zod-schema.core-CNYeC3G7.js",
|
|
5399
|
-
"dist/zod-schema.core-Cuz0lz6m.d.ts",
|
|
5400
5400
|
"dist/zod-schema.installs-DdHilcIY.js",
|
|
5401
5401
|
"dist/zod-schema.proxy-C9xClpkh.d.ts",
|
|
5402
5402
|
"dist/zod-schema.sensitive-C6BBiAxv.js"
|
|
@@ -909,6 +909,160 @@ function assertSessionActive(accountId) {
|
|
|
909
909
|
}
|
|
910
910
|
}
|
|
911
911
|
//#endregion
|
|
912
|
+
//#region extensions/weixin/src/cdn/aes-ecb.ts
|
|
913
|
+
/**
|
|
914
|
+
* Shared AES-128-ECB crypto utilities for CDN upload and download.
|
|
915
|
+
*/
|
|
916
|
+
/** Encrypt buffer with AES-128-ECB (PKCS7 padding is default). */
|
|
917
|
+
function encryptAesEcb(plaintext, key) {
|
|
918
|
+
const cipher = createCipheriv("aes-128-ecb", key, null);
|
|
919
|
+
return Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
920
|
+
}
|
|
921
|
+
/** Decrypt buffer with AES-128-ECB (PKCS7 padding). */
|
|
922
|
+
function decryptAesEcb(ciphertext, key) {
|
|
923
|
+
const decipher = createDecipheriv("aes-128-ecb", key, null);
|
|
924
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
925
|
+
}
|
|
926
|
+
/** Compute AES-128-ECB ciphertext size (PKCS7 padding to 16-byte boundary). */
|
|
927
|
+
function aesEcbPaddedSize(plaintextSize) {
|
|
928
|
+
return Math.ceil((plaintextSize + 1) / 16) * 16;
|
|
929
|
+
}
|
|
930
|
+
//#endregion
|
|
931
|
+
//#region extensions/weixin/src/cdn/cdn-url.ts
|
|
932
|
+
/** Build a CDN download URL from encrypt_query_param. */
|
|
933
|
+
function buildCdnDownloadUrl(encryptedQueryParam, cdnBaseUrl) {
|
|
934
|
+
return `${cdnBaseUrl}/download?encrypted_query_param=${encodeURIComponent(encryptedQueryParam)}`;
|
|
935
|
+
}
|
|
936
|
+
/** Build a CDN upload URL from upload_param and filekey. */
|
|
937
|
+
function buildCdnUploadUrl(params) {
|
|
938
|
+
return `${params.cdnBaseUrl}/upload?encrypted_query_param=${encodeURIComponent(params.uploadParam)}&filekey=${encodeURIComponent(params.filekey)}`;
|
|
939
|
+
}
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region extensions/weixin/src/cdn/cdn-upload.ts
|
|
942
|
+
/** Maximum retry attempts for CDN upload. */
|
|
943
|
+
const UPLOAD_MAX_RETRIES = 3;
|
|
944
|
+
/**
|
|
945
|
+
* Upload one buffer to the Weixin CDN with AES-128-ECB encryption.
|
|
946
|
+
* Returns the download encrypted_query_param from the CDN response.
|
|
947
|
+
* Retries up to UPLOAD_MAX_RETRIES times on server errors; client errors (4xx) abort immediately.
|
|
948
|
+
*/
|
|
949
|
+
async function uploadBufferToCdn(params) {
|
|
950
|
+
const { buf, uploadFullUrl, uploadParam, filekey, cdnBaseUrl, label, aeskey } = params;
|
|
951
|
+
const ciphertext = encryptAesEcb(buf, aeskey);
|
|
952
|
+
const trimmedFull = uploadFullUrl?.trim();
|
|
953
|
+
let cdnUrl;
|
|
954
|
+
if (trimmedFull) cdnUrl = trimmedFull;
|
|
955
|
+
else if (uploadParam) cdnUrl = buildCdnUploadUrl({
|
|
956
|
+
cdnBaseUrl,
|
|
957
|
+
uploadParam,
|
|
958
|
+
filekey
|
|
959
|
+
});
|
|
960
|
+
else throw new Error(`${label}: CDN upload URL missing (need upload_full_url or upload_param)`);
|
|
961
|
+
logger.debug(`${label}: CDN POST url=${redactUrl(cdnUrl)} ciphertextSize=${ciphertext.length}`);
|
|
962
|
+
let downloadParam;
|
|
963
|
+
let lastError;
|
|
964
|
+
for (let attempt = 1; attempt <= UPLOAD_MAX_RETRIES; attempt++) try {
|
|
965
|
+
const res = await fetch(cdnUrl, {
|
|
966
|
+
method: "POST",
|
|
967
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
968
|
+
body: new Uint8Array(ciphertext)
|
|
969
|
+
});
|
|
970
|
+
if (res.status >= 400 && res.status < 500) {
|
|
971
|
+
const errMsg = res.headers.get("x-error-message") ?? await res.text();
|
|
972
|
+
logger.error(`${label}: CDN client error attempt=${attempt} status=${res.status} errMsg=${errMsg}`);
|
|
973
|
+
throw new Error(`CDN upload client error ${res.status}: ${errMsg}`);
|
|
974
|
+
}
|
|
975
|
+
if (res.status !== 200) {
|
|
976
|
+
const errMsg = res.headers.get("x-error-message") ?? `status ${res.status}`;
|
|
977
|
+
logger.error(`${label}: CDN server error attempt=${attempt} status=${res.status} errMsg=${errMsg}`);
|
|
978
|
+
throw new Error(`CDN upload server error: ${errMsg}`);
|
|
979
|
+
}
|
|
980
|
+
downloadParam = res.headers.get("x-encrypted-param") ?? void 0;
|
|
981
|
+
if (!downloadParam) {
|
|
982
|
+
logger.error(`${label}: CDN response missing x-encrypted-param header attempt=${attempt}`);
|
|
983
|
+
throw new Error("CDN upload response missing x-encrypted-param header");
|
|
984
|
+
}
|
|
985
|
+
logger.debug(`${label}: CDN upload success attempt=${attempt}`);
|
|
986
|
+
break;
|
|
987
|
+
} catch (err) {
|
|
988
|
+
lastError = err;
|
|
989
|
+
if (err instanceof Error && err.message.includes("client error")) throw err;
|
|
990
|
+
if (attempt < UPLOAD_MAX_RETRIES) logger.error(`${label}: attempt ${attempt} failed, retrying... err=${String(err)}`);
|
|
991
|
+
else logger.error(`${label}: all ${UPLOAD_MAX_RETRIES} attempts failed err=${String(err)}`);
|
|
992
|
+
}
|
|
993
|
+
if (!downloadParam) throw lastError instanceof Error ? lastError : /* @__PURE__ */ new Error(`CDN upload failed after ${UPLOAD_MAX_RETRIES} attempts`);
|
|
994
|
+
return { downloadParam };
|
|
995
|
+
}
|
|
996
|
+
//#endregion
|
|
997
|
+
//#region extensions/weixin/src/media/mime.ts
|
|
998
|
+
const EXTENSION_TO_MIME = {
|
|
999
|
+
".pdf": "application/pdf",
|
|
1000
|
+
".doc": "application/msword",
|
|
1001
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1002
|
+
".xls": "application/vnd.ms-excel",
|
|
1003
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
1004
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
1005
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
1006
|
+
".txt": "text/plain",
|
|
1007
|
+
".csv": "text/csv",
|
|
1008
|
+
".zip": "application/zip",
|
|
1009
|
+
".tar": "application/x-tar",
|
|
1010
|
+
".gz": "application/gzip",
|
|
1011
|
+
".mp3": "audio/mpeg",
|
|
1012
|
+
".ogg": "audio/ogg",
|
|
1013
|
+
".wav": "audio/wav",
|
|
1014
|
+
".mp4": "video/mp4",
|
|
1015
|
+
".mov": "video/quicktime",
|
|
1016
|
+
".webm": "video/webm",
|
|
1017
|
+
".mkv": "video/x-matroska",
|
|
1018
|
+
".avi": "video/x-msvideo",
|
|
1019
|
+
".png": "image/png",
|
|
1020
|
+
".jpg": "image/jpeg",
|
|
1021
|
+
".jpeg": "image/jpeg",
|
|
1022
|
+
".gif": "image/gif",
|
|
1023
|
+
".webp": "image/webp",
|
|
1024
|
+
".bmp": "image/bmp"
|
|
1025
|
+
};
|
|
1026
|
+
const MIME_TO_EXTENSION = {
|
|
1027
|
+
"image/jpeg": ".jpg",
|
|
1028
|
+
"image/jpg": ".jpg",
|
|
1029
|
+
"image/png": ".png",
|
|
1030
|
+
"image/gif": ".gif",
|
|
1031
|
+
"image/webp": ".webp",
|
|
1032
|
+
"image/bmp": ".bmp",
|
|
1033
|
+
"video/mp4": ".mp4",
|
|
1034
|
+
"video/quicktime": ".mov",
|
|
1035
|
+
"video/webm": ".webm",
|
|
1036
|
+
"video/x-matroska": ".mkv",
|
|
1037
|
+
"video/x-msvideo": ".avi",
|
|
1038
|
+
"audio/mpeg": ".mp3",
|
|
1039
|
+
"audio/ogg": ".ogg",
|
|
1040
|
+
"audio/wav": ".wav",
|
|
1041
|
+
"application/pdf": ".pdf",
|
|
1042
|
+
"application/zip": ".zip",
|
|
1043
|
+
"application/x-tar": ".tar",
|
|
1044
|
+
"application/gzip": ".gz",
|
|
1045
|
+
"text/plain": ".txt",
|
|
1046
|
+
"text/csv": ".csv"
|
|
1047
|
+
};
|
|
1048
|
+
/** Get MIME type from filename extension. Returns "application/octet-stream" for unknown extensions. */
|
|
1049
|
+
function getMimeFromFilename(filename) {
|
|
1050
|
+
return EXTENSION_TO_MIME[path.extname(filename).toLowerCase()] ?? "application/octet-stream";
|
|
1051
|
+
}
|
|
1052
|
+
/** Get file extension from MIME type. Returns ".bin" for unknown types. */
|
|
1053
|
+
function getExtensionFromMime(mimeType) {
|
|
1054
|
+
return MIME_TO_EXTENSION[mimeType.split(";")[0].trim().toLowerCase()] ?? ".bin";
|
|
1055
|
+
}
|
|
1056
|
+
/** Get file extension from Content-Type header or URL path. Returns ".bin" for unknown. */
|
|
1057
|
+
function getExtensionFromContentTypeOrUrl(contentType, url) {
|
|
1058
|
+
if (contentType) {
|
|
1059
|
+
const ext = getExtensionFromMime(contentType);
|
|
1060
|
+
if (ext !== ".bin") return ext;
|
|
1061
|
+
}
|
|
1062
|
+
const ext = path.extname(new URL(url).pathname).toLowerCase();
|
|
1063
|
+
return new Set(Object.keys(EXTENSION_TO_MIME)).has(ext) ? ext : ".bin";
|
|
1064
|
+
}
|
|
1065
|
+
//#endregion
|
|
912
1066
|
//#region extensions/weixin/src/util/random.ts
|
|
913
1067
|
/**
|
|
914
1068
|
* Generate a prefixed unique ID using timestamp + crypto random bytes.
|
|
@@ -959,6 +1113,103 @@ const TypingStatus = {
|
|
|
959
1113
|
CANCEL: 2
|
|
960
1114
|
};
|
|
961
1115
|
//#endregion
|
|
1116
|
+
//#region extensions/weixin/src/cdn/upload.ts
|
|
1117
|
+
/**
|
|
1118
|
+
* Download a remote media URL (image, video, file) to a local temp file in destDir.
|
|
1119
|
+
* Returns the local file path; extension is inferred from Content-Type / URL.
|
|
1120
|
+
*/
|
|
1121
|
+
async function downloadRemoteImageToTemp(url, destDir) {
|
|
1122
|
+
logger.debug(`downloadRemoteImageToTemp: fetching url=${url}`);
|
|
1123
|
+
const res = await fetch(url);
|
|
1124
|
+
if (!res.ok) {
|
|
1125
|
+
const msg = `remote media download failed: ${res.status} ${res.statusText} url=${url}`;
|
|
1126
|
+
logger.error(`downloadRemoteImageToTemp: ${msg}`);
|
|
1127
|
+
throw new Error(msg);
|
|
1128
|
+
}
|
|
1129
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
1130
|
+
logger.debug(`downloadRemoteImageToTemp: downloaded ${buf.length} bytes`);
|
|
1131
|
+
await fs$1.mkdir(destDir, { recursive: true });
|
|
1132
|
+
const ext = getExtensionFromContentTypeOrUrl(res.headers.get("content-type"), url);
|
|
1133
|
+
const name = tempFileName("weixin-remote", ext);
|
|
1134
|
+
const filePath = path.join(destDir, name);
|
|
1135
|
+
await fs$1.writeFile(filePath, buf);
|
|
1136
|
+
logger.debug(`downloadRemoteImageToTemp: saved to ${filePath} ext=${ext}`);
|
|
1137
|
+
return filePath;
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Common upload pipeline: read file → hash → gen aeskey → getUploadUrl → uploadBufferToCdn → return info.
|
|
1141
|
+
*/
|
|
1142
|
+
async function uploadMediaToCdn(params) {
|
|
1143
|
+
const { filePath, toUserId, opts, cdnBaseUrl, mediaType, label } = params;
|
|
1144
|
+
const plaintext = await fs$1.readFile(filePath);
|
|
1145
|
+
const rawsize = plaintext.length;
|
|
1146
|
+
const rawfilemd5 = crypto.createHash("md5").update(plaintext).digest("hex");
|
|
1147
|
+
const filesize = aesEcbPaddedSize(rawsize);
|
|
1148
|
+
const filekey = crypto.randomBytes(16).toString("hex");
|
|
1149
|
+
const aeskey = crypto.randomBytes(16);
|
|
1150
|
+
logger.debug(`${label}: file=${filePath} rawsize=${rawsize} filesize=${filesize} md5=${rawfilemd5} filekey=${filekey}`);
|
|
1151
|
+
const uploadUrlResp = await getUploadUrl({
|
|
1152
|
+
...opts,
|
|
1153
|
+
filekey,
|
|
1154
|
+
media_type: mediaType,
|
|
1155
|
+
to_user_id: toUserId,
|
|
1156
|
+
rawsize,
|
|
1157
|
+
rawfilemd5,
|
|
1158
|
+
filesize,
|
|
1159
|
+
no_need_thumb: true,
|
|
1160
|
+
aeskey: aeskey.toString("hex")
|
|
1161
|
+
});
|
|
1162
|
+
const uploadFullUrl = uploadUrlResp.upload_full_url?.trim();
|
|
1163
|
+
const uploadParam = uploadUrlResp.upload_param;
|
|
1164
|
+
if (!uploadFullUrl && !uploadParam) {
|
|
1165
|
+
logger.error(`${label}: getUploadUrl returned no upload URL (need upload_full_url or upload_param), resp=${JSON.stringify(uploadUrlResp)}`);
|
|
1166
|
+
throw new Error(`${label}: getUploadUrl returned no upload URL`);
|
|
1167
|
+
}
|
|
1168
|
+
const { downloadParam: downloadEncryptedQueryParam } = await uploadBufferToCdn({
|
|
1169
|
+
buf: plaintext,
|
|
1170
|
+
uploadFullUrl: uploadFullUrl || void 0,
|
|
1171
|
+
uploadParam: uploadParam ?? void 0,
|
|
1172
|
+
filekey,
|
|
1173
|
+
cdnBaseUrl,
|
|
1174
|
+
aeskey,
|
|
1175
|
+
label: `${label}[orig filekey=${filekey}]`
|
|
1176
|
+
});
|
|
1177
|
+
return {
|
|
1178
|
+
filekey,
|
|
1179
|
+
downloadEncryptedQueryParam,
|
|
1180
|
+
aeskey: aeskey.toString("hex"),
|
|
1181
|
+
fileSize: rawsize,
|
|
1182
|
+
fileSizeCiphertext: filesize
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
/** Upload a local image file to the Weixin CDN with AES-128-ECB encryption. */
|
|
1186
|
+
async function uploadFileToWeixin(params) {
|
|
1187
|
+
return uploadMediaToCdn({
|
|
1188
|
+
...params,
|
|
1189
|
+
mediaType: UploadMediaType.IMAGE,
|
|
1190
|
+
label: "uploadFileToWeixin"
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
/** Upload a local video file to the Weixin CDN. */
|
|
1194
|
+
async function uploadVideoToWeixin(params) {
|
|
1195
|
+
return uploadMediaToCdn({
|
|
1196
|
+
...params,
|
|
1197
|
+
mediaType: UploadMediaType.VIDEO,
|
|
1198
|
+
label: "uploadVideoToWeixin"
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Upload a local file attachment (non-image, non-video) to the Weixin CDN.
|
|
1203
|
+
* Uses media_type=FILE; no thumbnail required.
|
|
1204
|
+
*/
|
|
1205
|
+
async function uploadFileAttachmentToWeixin(params) {
|
|
1206
|
+
return uploadMediaToCdn({
|
|
1207
|
+
...params,
|
|
1208
|
+
mediaType: UploadMediaType.FILE,
|
|
1209
|
+
label: "uploadFileAttachmentToWeixin"
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
//#endregion
|
|
962
1213
|
//#region extensions/weixin/src/messaging/inbound.ts
|
|
963
1214
|
/**
|
|
964
1215
|
* contextToken is issued per-message by the Weixin getupdates API and must
|
|
@@ -1174,75 +1425,6 @@ function emitWeixinMessageSent(params) {
|
|
|
1174
1425
|
fireAndForgetHook(Promise.resolve(hookRunner.runMessageSent(toPluginMessageSentEvent(canonical), toPluginMessageContext(canonical))), "weixin: message_sent plugin hook failed");
|
|
1175
1426
|
}
|
|
1176
1427
|
//#endregion
|
|
1177
|
-
//#region extensions/weixin/src/media/mime.ts
|
|
1178
|
-
const EXTENSION_TO_MIME = {
|
|
1179
|
-
".pdf": "application/pdf",
|
|
1180
|
-
".doc": "application/msword",
|
|
1181
|
-
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1182
|
-
".xls": "application/vnd.ms-excel",
|
|
1183
|
-
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
1184
|
-
".ppt": "application/vnd.ms-powerpoint",
|
|
1185
|
-
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
1186
|
-
".txt": "text/plain",
|
|
1187
|
-
".csv": "text/csv",
|
|
1188
|
-
".zip": "application/zip",
|
|
1189
|
-
".tar": "application/x-tar",
|
|
1190
|
-
".gz": "application/gzip",
|
|
1191
|
-
".mp3": "audio/mpeg",
|
|
1192
|
-
".ogg": "audio/ogg",
|
|
1193
|
-
".wav": "audio/wav",
|
|
1194
|
-
".mp4": "video/mp4",
|
|
1195
|
-
".mov": "video/quicktime",
|
|
1196
|
-
".webm": "video/webm",
|
|
1197
|
-
".mkv": "video/x-matroska",
|
|
1198
|
-
".avi": "video/x-msvideo",
|
|
1199
|
-
".png": "image/png",
|
|
1200
|
-
".jpg": "image/jpeg",
|
|
1201
|
-
".jpeg": "image/jpeg",
|
|
1202
|
-
".gif": "image/gif",
|
|
1203
|
-
".webp": "image/webp",
|
|
1204
|
-
".bmp": "image/bmp"
|
|
1205
|
-
};
|
|
1206
|
-
const MIME_TO_EXTENSION = {
|
|
1207
|
-
"image/jpeg": ".jpg",
|
|
1208
|
-
"image/jpg": ".jpg",
|
|
1209
|
-
"image/png": ".png",
|
|
1210
|
-
"image/gif": ".gif",
|
|
1211
|
-
"image/webp": ".webp",
|
|
1212
|
-
"image/bmp": ".bmp",
|
|
1213
|
-
"video/mp4": ".mp4",
|
|
1214
|
-
"video/quicktime": ".mov",
|
|
1215
|
-
"video/webm": ".webm",
|
|
1216
|
-
"video/x-matroska": ".mkv",
|
|
1217
|
-
"video/x-msvideo": ".avi",
|
|
1218
|
-
"audio/mpeg": ".mp3",
|
|
1219
|
-
"audio/ogg": ".ogg",
|
|
1220
|
-
"audio/wav": ".wav",
|
|
1221
|
-
"application/pdf": ".pdf",
|
|
1222
|
-
"application/zip": ".zip",
|
|
1223
|
-
"application/x-tar": ".tar",
|
|
1224
|
-
"application/gzip": ".gz",
|
|
1225
|
-
"text/plain": ".txt",
|
|
1226
|
-
"text/csv": ".csv"
|
|
1227
|
-
};
|
|
1228
|
-
/** Get MIME type from filename extension. Returns "application/octet-stream" for unknown extensions. */
|
|
1229
|
-
function getMimeFromFilename(filename) {
|
|
1230
|
-
return EXTENSION_TO_MIME[path.extname(filename).toLowerCase()] ?? "application/octet-stream";
|
|
1231
|
-
}
|
|
1232
|
-
/** Get file extension from MIME type. Returns ".bin" for unknown types. */
|
|
1233
|
-
function getExtensionFromMime(mimeType) {
|
|
1234
|
-
return MIME_TO_EXTENSION[mimeType.split(";")[0].trim().toLowerCase()] ?? ".bin";
|
|
1235
|
-
}
|
|
1236
|
-
/** Get file extension from Content-Type header or URL path. Returns ".bin" for unknown. */
|
|
1237
|
-
function getExtensionFromContentTypeOrUrl(contentType, url) {
|
|
1238
|
-
if (contentType) {
|
|
1239
|
-
const ext = getExtensionFromMime(contentType);
|
|
1240
|
-
if (ext !== ".bin") return ext;
|
|
1241
|
-
}
|
|
1242
|
-
const ext = path.extname(new URL(url).pathname).toLowerCase();
|
|
1243
|
-
return new Set(Object.keys(EXTENSION_TO_MIME)).has(ext) ? ext : ".bin";
|
|
1244
|
-
}
|
|
1245
|
-
//#endregion
|
|
1246
1428
|
//#region extensions/weixin/src/messaging/markdown-filter.ts
|
|
1247
1429
|
/**
|
|
1248
1430
|
* Streaming markdown filter — character-level state machine that strips
|
|
@@ -1819,188 +2001,6 @@ async function sendFileMessageWeixin(params) {
|
|
|
1819
2001
|
});
|
|
1820
2002
|
}
|
|
1821
2003
|
//#endregion
|
|
1822
|
-
//#region extensions/weixin/src/cdn/aes-ecb.ts
|
|
1823
|
-
/**
|
|
1824
|
-
* Shared AES-128-ECB crypto utilities for CDN upload and download.
|
|
1825
|
-
*/
|
|
1826
|
-
/** Encrypt buffer with AES-128-ECB (PKCS7 padding is default). */
|
|
1827
|
-
function encryptAesEcb(plaintext, key) {
|
|
1828
|
-
const cipher = createCipheriv("aes-128-ecb", key, null);
|
|
1829
|
-
return Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
1830
|
-
}
|
|
1831
|
-
/** Decrypt buffer with AES-128-ECB (PKCS7 padding). */
|
|
1832
|
-
function decryptAesEcb(ciphertext, key) {
|
|
1833
|
-
const decipher = createDecipheriv("aes-128-ecb", key, null);
|
|
1834
|
-
return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
1835
|
-
}
|
|
1836
|
-
/** Compute AES-128-ECB ciphertext size (PKCS7 padding to 16-byte boundary). */
|
|
1837
|
-
function aesEcbPaddedSize(plaintextSize) {
|
|
1838
|
-
return Math.ceil((plaintextSize + 1) / 16) * 16;
|
|
1839
|
-
}
|
|
1840
|
-
//#endregion
|
|
1841
|
-
//#region extensions/weixin/src/cdn/cdn-url.ts
|
|
1842
|
-
/** Build a CDN download URL from encrypt_query_param. */
|
|
1843
|
-
function buildCdnDownloadUrl(encryptedQueryParam, cdnBaseUrl) {
|
|
1844
|
-
return `${cdnBaseUrl}/download?encrypted_query_param=${encodeURIComponent(encryptedQueryParam)}`;
|
|
1845
|
-
}
|
|
1846
|
-
/** Build a CDN upload URL from upload_param and filekey. */
|
|
1847
|
-
function buildCdnUploadUrl(params) {
|
|
1848
|
-
return `${params.cdnBaseUrl}/upload?encrypted_query_param=${encodeURIComponent(params.uploadParam)}&filekey=${encodeURIComponent(params.filekey)}`;
|
|
1849
|
-
}
|
|
1850
|
-
//#endregion
|
|
1851
|
-
//#region extensions/weixin/src/cdn/cdn-upload.ts
|
|
1852
|
-
/** Maximum retry attempts for CDN upload. */
|
|
1853
|
-
const UPLOAD_MAX_RETRIES = 3;
|
|
1854
|
-
/**
|
|
1855
|
-
* Upload one buffer to the Weixin CDN with AES-128-ECB encryption.
|
|
1856
|
-
* Returns the download encrypted_query_param from the CDN response.
|
|
1857
|
-
* Retries up to UPLOAD_MAX_RETRIES times on server errors; client errors (4xx) abort immediately.
|
|
1858
|
-
*/
|
|
1859
|
-
async function uploadBufferToCdn(params) {
|
|
1860
|
-
const { buf, uploadFullUrl, uploadParam, filekey, cdnBaseUrl, label, aeskey } = params;
|
|
1861
|
-
const ciphertext = encryptAesEcb(buf, aeskey);
|
|
1862
|
-
const trimmedFull = uploadFullUrl?.trim();
|
|
1863
|
-
let cdnUrl;
|
|
1864
|
-
if (trimmedFull) cdnUrl = trimmedFull;
|
|
1865
|
-
else if (uploadParam) cdnUrl = buildCdnUploadUrl({
|
|
1866
|
-
cdnBaseUrl,
|
|
1867
|
-
uploadParam,
|
|
1868
|
-
filekey
|
|
1869
|
-
});
|
|
1870
|
-
else throw new Error(`${label}: CDN upload URL missing (need upload_full_url or upload_param)`);
|
|
1871
|
-
logger.debug(`${label}: CDN POST url=${redactUrl(cdnUrl)} ciphertextSize=${ciphertext.length}`);
|
|
1872
|
-
let downloadParam;
|
|
1873
|
-
let lastError;
|
|
1874
|
-
for (let attempt = 1; attempt <= UPLOAD_MAX_RETRIES; attempt++) try {
|
|
1875
|
-
const res = await fetch(cdnUrl, {
|
|
1876
|
-
method: "POST",
|
|
1877
|
-
headers: { "Content-Type": "application/octet-stream" },
|
|
1878
|
-
body: new Uint8Array(ciphertext)
|
|
1879
|
-
});
|
|
1880
|
-
if (res.status >= 400 && res.status < 500) {
|
|
1881
|
-
const errMsg = res.headers.get("x-error-message") ?? await res.text();
|
|
1882
|
-
logger.error(`${label}: CDN client error attempt=${attempt} status=${res.status} errMsg=${errMsg}`);
|
|
1883
|
-
throw new Error(`CDN upload client error ${res.status}: ${errMsg}`);
|
|
1884
|
-
}
|
|
1885
|
-
if (res.status !== 200) {
|
|
1886
|
-
const errMsg = res.headers.get("x-error-message") ?? `status ${res.status}`;
|
|
1887
|
-
logger.error(`${label}: CDN server error attempt=${attempt} status=${res.status} errMsg=${errMsg}`);
|
|
1888
|
-
throw new Error(`CDN upload server error: ${errMsg}`);
|
|
1889
|
-
}
|
|
1890
|
-
downloadParam = res.headers.get("x-encrypted-param") ?? void 0;
|
|
1891
|
-
if (!downloadParam) {
|
|
1892
|
-
logger.error(`${label}: CDN response missing x-encrypted-param header attempt=${attempt}`);
|
|
1893
|
-
throw new Error("CDN upload response missing x-encrypted-param header");
|
|
1894
|
-
}
|
|
1895
|
-
logger.debug(`${label}: CDN upload success attempt=${attempt}`);
|
|
1896
|
-
break;
|
|
1897
|
-
} catch (err) {
|
|
1898
|
-
lastError = err;
|
|
1899
|
-
if (err instanceof Error && err.message.includes("client error")) throw err;
|
|
1900
|
-
if (attempt < UPLOAD_MAX_RETRIES) logger.error(`${label}: attempt ${attempt} failed, retrying... err=${String(err)}`);
|
|
1901
|
-
else logger.error(`${label}: all ${UPLOAD_MAX_RETRIES} attempts failed err=${String(err)}`);
|
|
1902
|
-
}
|
|
1903
|
-
if (!downloadParam) throw lastError instanceof Error ? lastError : /* @__PURE__ */ new Error(`CDN upload failed after ${UPLOAD_MAX_RETRIES} attempts`);
|
|
1904
|
-
return { downloadParam };
|
|
1905
|
-
}
|
|
1906
|
-
//#endregion
|
|
1907
|
-
//#region extensions/weixin/src/cdn/upload.ts
|
|
1908
|
-
/**
|
|
1909
|
-
* Download a remote media URL (image, video, file) to a local temp file in destDir.
|
|
1910
|
-
* Returns the local file path; extension is inferred from Content-Type / URL.
|
|
1911
|
-
*/
|
|
1912
|
-
async function downloadRemoteImageToTemp(url, destDir) {
|
|
1913
|
-
logger.debug(`downloadRemoteImageToTemp: fetching url=${url}`);
|
|
1914
|
-
const res = await fetch(url);
|
|
1915
|
-
if (!res.ok) {
|
|
1916
|
-
const msg = `remote media download failed: ${res.status} ${res.statusText} url=${url}`;
|
|
1917
|
-
logger.error(`downloadRemoteImageToTemp: ${msg}`);
|
|
1918
|
-
throw new Error(msg);
|
|
1919
|
-
}
|
|
1920
|
-
const buf = Buffer.from(await res.arrayBuffer());
|
|
1921
|
-
logger.debug(`downloadRemoteImageToTemp: downloaded ${buf.length} bytes`);
|
|
1922
|
-
await fs$1.mkdir(destDir, { recursive: true });
|
|
1923
|
-
const ext = getExtensionFromContentTypeOrUrl(res.headers.get("content-type"), url);
|
|
1924
|
-
const name = tempFileName("weixin-remote", ext);
|
|
1925
|
-
const filePath = path.join(destDir, name);
|
|
1926
|
-
await fs$1.writeFile(filePath, buf);
|
|
1927
|
-
logger.debug(`downloadRemoteImageToTemp: saved to ${filePath} ext=${ext}`);
|
|
1928
|
-
return filePath;
|
|
1929
|
-
}
|
|
1930
|
-
/**
|
|
1931
|
-
* Common upload pipeline: read file → hash → gen aeskey → getUploadUrl → uploadBufferToCdn → return info.
|
|
1932
|
-
*/
|
|
1933
|
-
async function uploadMediaToCdn(params) {
|
|
1934
|
-
const { filePath, toUserId, opts, cdnBaseUrl, mediaType, label } = params;
|
|
1935
|
-
const plaintext = await fs$1.readFile(filePath);
|
|
1936
|
-
const rawsize = plaintext.length;
|
|
1937
|
-
const rawfilemd5 = crypto.createHash("md5").update(plaintext).digest("hex");
|
|
1938
|
-
const filesize = aesEcbPaddedSize(rawsize);
|
|
1939
|
-
const filekey = crypto.randomBytes(16).toString("hex");
|
|
1940
|
-
const aeskey = crypto.randomBytes(16);
|
|
1941
|
-
logger.debug(`${label}: file=${filePath} rawsize=${rawsize} filesize=${filesize} md5=${rawfilemd5} filekey=${filekey}`);
|
|
1942
|
-
const uploadUrlResp = await getUploadUrl({
|
|
1943
|
-
...opts,
|
|
1944
|
-
filekey,
|
|
1945
|
-
media_type: mediaType,
|
|
1946
|
-
to_user_id: toUserId,
|
|
1947
|
-
rawsize,
|
|
1948
|
-
rawfilemd5,
|
|
1949
|
-
filesize,
|
|
1950
|
-
no_need_thumb: true,
|
|
1951
|
-
aeskey: aeskey.toString("hex")
|
|
1952
|
-
});
|
|
1953
|
-
const uploadFullUrl = uploadUrlResp.upload_full_url?.trim();
|
|
1954
|
-
const uploadParam = uploadUrlResp.upload_param;
|
|
1955
|
-
if (!uploadFullUrl && !uploadParam) {
|
|
1956
|
-
logger.error(`${label}: getUploadUrl returned no upload URL (need upload_full_url or upload_param), resp=${JSON.stringify(uploadUrlResp)}`);
|
|
1957
|
-
throw new Error(`${label}: getUploadUrl returned no upload URL`);
|
|
1958
|
-
}
|
|
1959
|
-
const { downloadParam: downloadEncryptedQueryParam } = await uploadBufferToCdn({
|
|
1960
|
-
buf: plaintext,
|
|
1961
|
-
uploadFullUrl: uploadFullUrl || void 0,
|
|
1962
|
-
uploadParam: uploadParam ?? void 0,
|
|
1963
|
-
filekey,
|
|
1964
|
-
cdnBaseUrl,
|
|
1965
|
-
aeskey,
|
|
1966
|
-
label: `${label}[orig filekey=${filekey}]`
|
|
1967
|
-
});
|
|
1968
|
-
return {
|
|
1969
|
-
filekey,
|
|
1970
|
-
downloadEncryptedQueryParam,
|
|
1971
|
-
aeskey: aeskey.toString("hex"),
|
|
1972
|
-
fileSize: rawsize,
|
|
1973
|
-
fileSizeCiphertext: filesize
|
|
1974
|
-
};
|
|
1975
|
-
}
|
|
1976
|
-
/** Upload a local image file to the Weixin CDN with AES-128-ECB encryption. */
|
|
1977
|
-
async function uploadFileToWeixin(params) {
|
|
1978
|
-
return uploadMediaToCdn({
|
|
1979
|
-
...params,
|
|
1980
|
-
mediaType: UploadMediaType.IMAGE,
|
|
1981
|
-
label: "uploadFileToWeixin"
|
|
1982
|
-
});
|
|
1983
|
-
}
|
|
1984
|
-
/** Upload a local video file to the Weixin CDN. */
|
|
1985
|
-
async function uploadVideoToWeixin(params) {
|
|
1986
|
-
return uploadMediaToCdn({
|
|
1987
|
-
...params,
|
|
1988
|
-
mediaType: UploadMediaType.VIDEO,
|
|
1989
|
-
label: "uploadVideoToWeixin"
|
|
1990
|
-
});
|
|
1991
|
-
}
|
|
1992
|
-
/**
|
|
1993
|
-
* Upload a local file attachment (non-image, non-video) to the Weixin CDN.
|
|
1994
|
-
* Uses media_type=FILE; no thumbnail required.
|
|
1995
|
-
*/
|
|
1996
|
-
async function uploadFileAttachmentToWeixin(params) {
|
|
1997
|
-
return uploadMediaToCdn({
|
|
1998
|
-
...params,
|
|
1999
|
-
mediaType: UploadMediaType.FILE,
|
|
2000
|
-
label: "uploadFileAttachmentToWeixin"
|
|
2001
|
-
});
|
|
2002
|
-
}
|
|
2003
|
-
//#endregion
|
|
2004
2004
|
//#region extensions/weixin/src/messaging/send-media.ts
|
|
2005
2005
|
/**
|
|
2006
2006
|
* Upload a local file and send it as a weixin message, routing by MIME type:
|
|
@@ -2069,4 +2069,4 @@ async function sendWeixinMediaFile(params) {
|
|
|
2069
2069
|
});
|
|
2070
2070
|
}
|
|
2071
2071
|
//#endregion
|
|
2072
|
-
export { sendTyping as A, registerWeixinAccountId as B, pauseSession as C, getUpdates as D, getConfig as E, clearStaleAccountsForUserId as F, logger as G, saveWeixinAccount as H, deriveRawAccountId as I, resolveStateDir as K, listIndexedWeixinAccountIds as L, redactToken as M, CDN_BASE_URL as N, notifyStart as O, DEFAULT_BASE_URL as P, listWeixinAccountIds as R, getRemainingPauseMs as S, apiPostFetch as T, triggerWeixinChannelReload as U, resolveWeixinAccount as V, readFrameworkAllowFromList as W,
|
|
2072
|
+
export { sendTyping as A, registerWeixinAccountId as B, pauseSession as C, getUpdates as D, getConfig as E, clearStaleAccountsForUserId as F, logger as G, saveWeixinAccount as H, deriveRawAccountId as I, resolveStateDir as K, listIndexedWeixinAccountIds as L, redactToken as M, CDN_BASE_URL as N, notifyStart as O, DEFAULT_BASE_URL as P, listWeixinAccountIds as R, getRemainingPauseMs as S, apiPostFetch as T, triggerWeixinChannelReload as U, resolveWeixinAccount as V, readFrameworkAllowFromList as W, TypingStatus as _, applyWeixinMessageSendingHook as a, decryptAesEcb as b, findAccountIdsByContextToken as c, isMediaItem as d, restoreContextTokens as f, MessageItemType as g, downloadRemoteImageToTemp as h, StreamingMarkdownFilter as i, redactBody as j, notifyStop as k, getContextToken as l, weixinMessageToMsgContext as m, sendMessageItemWeixin as n, emitWeixinMessageSent as o, setContextToken as p, sendMessageWeixin as r, clearContextTokensForAccount as s, sendWeixinMediaFile as t, getContextTokenFromMsgContext as u, getMimeFromFilename as v, apiGetFetch as w, assertSessionActive as x, buildCdnDownloadUrl as y, loadWeixinAccount as z };
|