@netcat-ai/openclaw-weixin 2.4.7

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.
Files changed (116) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/CHANGELOG.zh_CN.md +156 -0
  3. package/LICENSE +27 -0
  4. package/README.md +355 -0
  5. package/README.zh_CN.md +351 -0
  6. package/dist/index.js +16 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/src/api/api.js +484 -0
  9. package/dist/src/api/api.js.map +1 -0
  10. package/dist/src/api/config-cache.js +64 -0
  11. package/dist/src/api/config-cache.js.map +1 -0
  12. package/dist/src/api/session-guard.js +49 -0
  13. package/dist/src/api/session-guard.js.map +1 -0
  14. package/dist/src/api/types.js +37 -0
  15. package/dist/src/api/types.js.map +1 -0
  16. package/dist/src/auth/accounts.js +328 -0
  17. package/dist/src/auth/accounts.js.map +1 -0
  18. package/dist/src/auth/login-qr.js +331 -0
  19. package/dist/src/auth/login-qr.js.map +1 -0
  20. package/dist/src/auth/pairing.js +104 -0
  21. package/dist/src/auth/pairing.js.map +1 -0
  22. package/dist/src/cdn/aes-ecb.js +19 -0
  23. package/dist/src/cdn/aes-ecb.js.map +1 -0
  24. package/dist/src/cdn/cdn-upload.js +74 -0
  25. package/dist/src/cdn/cdn-upload.js.map +1 -0
  26. package/dist/src/cdn/cdn-url.js +14 -0
  27. package/dist/src/cdn/cdn-url.js.map +1 -0
  28. package/dist/src/cdn/pic-decrypt.js +89 -0
  29. package/dist/src/cdn/pic-decrypt.js.map +1 -0
  30. package/dist/src/cdn/upload.js +115 -0
  31. package/dist/src/cdn/upload.js.map +1 -0
  32. package/dist/src/channel.js +478 -0
  33. package/dist/src/channel.js.map +1 -0
  34. package/dist/src/compat.js +67 -0
  35. package/dist/src/compat.js.map +1 -0
  36. package/dist/src/config/config-schema.js +20 -0
  37. package/dist/src/config/config-schema.js.map +1 -0
  38. package/dist/src/config/reply-progress.js +5 -0
  39. package/dist/src/config/reply-progress.js.map +1 -0
  40. package/dist/src/media/media-download.js +95 -0
  41. package/dist/src/media/media-download.js.map +1 -0
  42. package/dist/src/media/mime.js +73 -0
  43. package/dist/src/media/mime.js.map +1 -0
  44. package/dist/src/media/silk-transcode.js +64 -0
  45. package/dist/src/media/silk-transcode.js.map +1 -0
  46. package/dist/src/messaging/debug-mode.js +63 -0
  47. package/dist/src/messaging/debug-mode.js.map +1 -0
  48. package/dist/src/messaging/error-notice.js +25 -0
  49. package/dist/src/messaging/error-notice.js.map +1 -0
  50. package/dist/src/messaging/inbound.js +201 -0
  51. package/dist/src/messaging/inbound.js.map +1 -0
  52. package/dist/src/messaging/markdown-filter.js +368 -0
  53. package/dist/src/messaging/markdown-filter.js.map +1 -0
  54. package/dist/src/messaging/outbound-hooks.js +58 -0
  55. package/dist/src/messaging/outbound-hooks.js.map +1 -0
  56. package/dist/src/messaging/process-message.js +406 -0
  57. package/dist/src/messaging/process-message.js.map +1 -0
  58. package/dist/src/messaging/reply-progress-sender.js +93 -0
  59. package/dist/src/messaging/reply-progress-sender.js.map +1 -0
  60. package/dist/src/messaging/send-media.js +54 -0
  61. package/dist/src/messaging/send-media.js.map +1 -0
  62. package/dist/src/messaging/send.js +220 -0
  63. package/dist/src/messaging/send.js.map +1 -0
  64. package/dist/src/messaging/slash-commands.js +70 -0
  65. package/dist/src/messaging/slash-commands.js.map +1 -0
  66. package/dist/src/monitor/monitor.js +146 -0
  67. package/dist/src/monitor/monitor.js.map +1 -0
  68. package/dist/src/storage/state-dir.js +9 -0
  69. package/dist/src/storage/state-dir.js.map +1 -0
  70. package/dist/src/storage/sync-buf.js +64 -0
  71. package/dist/src/storage/sync-buf.js.map +1 -0
  72. package/dist/src/util/logger.js +120 -0
  73. package/dist/src/util/logger.js.map +1 -0
  74. package/dist/src/util/random.js +16 -0
  75. package/dist/src/util/random.js.map +1 -0
  76. package/dist/src/util/redact.js +54 -0
  77. package/dist/src/util/redact.js.map +1 -0
  78. package/index.ts +19 -0
  79. package/openclaw.plugin.json +22 -0
  80. package/package.json +75 -0
  81. package/src/api/api.ts +586 -0
  82. package/src/api/config-cache.ts +79 -0
  83. package/src/api/session-guard.ts +58 -0
  84. package/src/api/types.ts +278 -0
  85. package/src/auth/accounts.ts +394 -0
  86. package/src/auth/login-qr.ts +458 -0
  87. package/src/auth/pairing.ts +120 -0
  88. package/src/cdn/aes-ecb.ts +21 -0
  89. package/src/cdn/cdn-upload.ts +93 -0
  90. package/src/cdn/cdn-url.ts +20 -0
  91. package/src/cdn/pic-decrypt.ts +101 -0
  92. package/src/cdn/upload.ts +168 -0
  93. package/src/channel.ts +548 -0
  94. package/src/compat.ts +77 -0
  95. package/src/config/config-schema.ts +23 -0
  96. package/src/config/reply-progress.ts +10 -0
  97. package/src/media/media-download.ts +149 -0
  98. package/src/media/mime.ts +76 -0
  99. package/src/media/silk-transcode.ts +74 -0
  100. package/src/messaging/debug-mode.ts +69 -0
  101. package/src/messaging/error-notice.ts +32 -0
  102. package/src/messaging/inbound.ts +262 -0
  103. package/src/messaging/markdown-filter.ts +361 -0
  104. package/src/messaging/outbound-hooks.ts +88 -0
  105. package/src/messaging/process-message.ts +525 -0
  106. package/src/messaging/reply-progress-sender.ts +122 -0
  107. package/src/messaging/send-media.ts +72 -0
  108. package/src/messaging/send.ts +294 -0
  109. package/src/messaging/slash-commands.ts +110 -0
  110. package/src/monitor/monitor.ts +224 -0
  111. package/src/storage/state-dir.ts +11 -0
  112. package/src/storage/sync-buf.ts +81 -0
  113. package/src/util/logger.ts +145 -0
  114. package/src/util/random.ts +17 -0
  115. package/src/util/redact.ts +54 -0
  116. package/src/vendor.d.ts +25 -0
@@ -0,0 +1,89 @@
1
+ import { decryptAesEcb } from "./aes-ecb.js";
2
+ import { buildCdnDownloadUrl, ENABLE_CDN_URL_FALLBACK } from "./cdn-url.js";
3
+ import { logger } from "../util/logger.js";
4
+ /**
5
+ * Download raw bytes from the CDN (no decryption).
6
+ */
7
+ async function fetchCdnBytes(url, label) {
8
+ let res;
9
+ try {
10
+ res = await fetch(url);
11
+ }
12
+ catch (err) {
13
+ const cause = err.cause ?? err.code ?? "(no cause)";
14
+ logger.error(`${label}: fetch network error url=${url} err=${String(err)} cause=${String(cause)}`);
15
+ throw err;
16
+ }
17
+ logger.debug(`${label}: response status=${res.status} ok=${res.ok}`);
18
+ if (!res.ok) {
19
+ const body = await res.text().catch(() => "(unreadable)");
20
+ const msg = `${label}: CDN download ${res.status} ${res.statusText} body=${body}`;
21
+ logger.error(msg);
22
+ throw new Error(msg);
23
+ }
24
+ return Buffer.from(await res.arrayBuffer());
25
+ }
26
+ /**
27
+ * Parse CDNMedia.aes_key into a raw 16-byte AES key.
28
+ *
29
+ * Two encodings are seen in the wild:
30
+ * - base64(raw 16 bytes) → images (aes_key from media field)
31
+ * - base64(hex string of 16 bytes) → file / voice / video
32
+ *
33
+ * In the second case, base64-decoding yields 32 ASCII hex chars which must
34
+ * then be parsed as hex to recover the actual 16-byte key.
35
+ */
36
+ function parseAesKey(aesKeyBase64, label) {
37
+ const decoded = Buffer.from(aesKeyBase64, "base64");
38
+ if (decoded.length === 16) {
39
+ return decoded;
40
+ }
41
+ if (decoded.length === 32 && /^[0-9a-fA-F]{32}$/.test(decoded.toString("ascii"))) {
42
+ // hex-encoded key: base64 → hex string → raw bytes
43
+ return Buffer.from(decoded.toString("ascii"), "hex");
44
+ }
45
+ const msg = `${label}: aes_key must decode to 16 raw bytes or 32-char hex string, got ${decoded.length} bytes (base64="${aesKeyBase64}")`;
46
+ logger.error(msg);
47
+ throw new Error(msg);
48
+ }
49
+ /**
50
+ * Download and AES-128-ECB decrypt a CDN media file. Returns plaintext Buffer.
51
+ * aesKeyBase64: CDNMedia.aes_key JSON field (see parseAesKey for supported formats).
52
+ */
53
+ export async function downloadAndDecryptBuffer(encryptedQueryParam, aesKeyBase64, cdnBaseUrl, label, fullUrl) {
54
+ const key = parseAesKey(aesKeyBase64, label);
55
+ let url;
56
+ if (fullUrl) {
57
+ url = fullUrl;
58
+ }
59
+ else if (ENABLE_CDN_URL_FALLBACK) {
60
+ url = buildCdnDownloadUrl(encryptedQueryParam, cdnBaseUrl);
61
+ }
62
+ else {
63
+ throw new Error(`${label}: fullUrl is required (CDN URL fallback is disabled)`);
64
+ }
65
+ logger.debug(`${label}: fetching url=${url}`);
66
+ const encrypted = await fetchCdnBytes(url, label);
67
+ logger.debug(`${label}: downloaded ${encrypted.byteLength} bytes, decrypting`);
68
+ const decrypted = decryptAesEcb(encrypted, key);
69
+ logger.debug(`${label}: decrypted ${decrypted.length} bytes`);
70
+ return decrypted;
71
+ }
72
+ /**
73
+ * Download plain (unencrypted) bytes from the CDN. Returns the raw Buffer.
74
+ */
75
+ export async function downloadPlainCdnBuffer(encryptedQueryParam, cdnBaseUrl, label, fullUrl) {
76
+ let url;
77
+ if (fullUrl) {
78
+ url = fullUrl;
79
+ }
80
+ else if (ENABLE_CDN_URL_FALLBACK) {
81
+ url = buildCdnDownloadUrl(encryptedQueryParam, cdnBaseUrl);
82
+ }
83
+ else {
84
+ throw new Error(`${label}: fullUrl is required (CDN URL fallback is disabled)`);
85
+ }
86
+ logger.debug(`${label}: fetching url=${url}`);
87
+ return fetchCdnBytes(url, label);
88
+ }
89
+ //# sourceMappingURL=pic-decrypt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pic-decrypt.js","sourceRoot":"","sources":["../../../src/cdn/pic-decrypt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { getUploadUrl } from "../api/api.js";
5
+ import { aesEcbPaddedSize } from "./aes-ecb.js";
6
+ import { uploadBufferToCdn } from "./cdn-upload.js";
7
+ import { logger } from "../util/logger.js";
8
+ import { redactUrl } from "../util/redact.js";
9
+ import { getExtensionFromContentTypeOrUrl } from "../media/mime.js";
10
+ import { tempFileName } from "../util/random.js";
11
+ import { UploadMediaType } from "../api/types.js";
12
+ /**
13
+ * Download a remote media URL (image, video, file) to a local temp file in destDir.
14
+ * Returns the local file path; extension is inferred from Content-Type / URL.
15
+ */
16
+ export async function downloadRemoteImageToTemp(url, destDir) {
17
+ logger.debug(`downloadRemoteImageToTemp: fetching url=${redactUrl(url)}`);
18
+ let res;
19
+ try {
20
+ res = await fetch(url);
21
+ }
22
+ catch (err) {
23
+ const cause = err.cause ?? err.code ?? "";
24
+ logger.error(`downloadRemoteImageToTemp: fetch network error url=${redactUrl(url)} error=${String(err)}${cause ? ` cause=${cause}` : ""}`);
25
+ throw err;
26
+ }
27
+ if (!res.ok) {
28
+ const msg = `remote media download failed: ${res.status} ${res.statusText} url=${redactUrl(url)}`;
29
+ logger.error(`downloadRemoteImageToTemp: ${msg}`);
30
+ throw new Error(msg);
31
+ }
32
+ const buf = Buffer.from(await res.arrayBuffer());
33
+ logger.debug(`downloadRemoteImageToTemp: downloaded ${buf.length} bytes`);
34
+ await fs.mkdir(destDir, { recursive: true });
35
+ const ext = getExtensionFromContentTypeOrUrl(res.headers.get("content-type"), url);
36
+ const name = tempFileName("weixin-remote", ext);
37
+ const filePath = path.join(destDir, name);
38
+ await fs.writeFile(filePath, buf);
39
+ logger.debug(`downloadRemoteImageToTemp: saved to ${filePath} ext=${ext}`);
40
+ return filePath;
41
+ }
42
+ /**
43
+ * Common upload pipeline: read file → hash → gen aeskey → getUploadUrl → uploadBufferToCdn → return info.
44
+ */
45
+ async function uploadMediaToCdn(params) {
46
+ const { filePath, toUserId, opts, cdnBaseUrl, mediaType, label } = params;
47
+ const plaintext = await fs.readFile(filePath);
48
+ const rawsize = plaintext.length;
49
+ const rawfilemd5 = crypto.createHash("md5").update(plaintext).digest("hex");
50
+ const filesize = aesEcbPaddedSize(rawsize);
51
+ const filekey = crypto.randomBytes(16).toString("hex");
52
+ const aeskey = crypto.randomBytes(16);
53
+ logger.debug(`${label}: file=${filePath} rawsize=${rawsize} filesize=${filesize} md5=${rawfilemd5} filekey=${filekey}`);
54
+ const uploadUrlResp = await getUploadUrl({
55
+ ...opts,
56
+ filekey,
57
+ media_type: mediaType,
58
+ to_user_id: toUserId,
59
+ rawsize,
60
+ rawfilemd5,
61
+ filesize,
62
+ no_need_thumb: true,
63
+ aeskey: aeskey.toString("hex"),
64
+ });
65
+ const uploadFullUrl = uploadUrlResp.upload_full_url?.trim();
66
+ const uploadParam = uploadUrlResp.upload_param;
67
+ if (!uploadFullUrl && !uploadParam) {
68
+ logger.error(`${label}: getUploadUrl returned no upload URL (need upload_full_url or upload_param), resp=${JSON.stringify(uploadUrlResp)}`);
69
+ throw new Error(`${label}: getUploadUrl returned no upload URL`);
70
+ }
71
+ const { downloadParam: downloadEncryptedQueryParam } = await uploadBufferToCdn({
72
+ buf: plaintext,
73
+ uploadFullUrl: uploadFullUrl || undefined,
74
+ uploadParam: uploadParam ?? undefined,
75
+ filekey,
76
+ cdnBaseUrl,
77
+ aeskey,
78
+ label: `${label}[orig filekey=${filekey}]`,
79
+ });
80
+ return {
81
+ filekey,
82
+ downloadEncryptedQueryParam,
83
+ aeskey: aeskey.toString("hex"),
84
+ fileSize: rawsize,
85
+ fileSizeCiphertext: filesize,
86
+ };
87
+ }
88
+ /** Upload a local image file to the Weixin CDN with AES-128-ECB encryption. */
89
+ export async function uploadFileToWeixin(params) {
90
+ return uploadMediaToCdn({
91
+ ...params,
92
+ mediaType: UploadMediaType.IMAGE,
93
+ label: "uploadFileToWeixin",
94
+ });
95
+ }
96
+ /** Upload a local video file to the Weixin CDN. */
97
+ export async function uploadVideoToWeixin(params) {
98
+ return uploadMediaToCdn({
99
+ ...params,
100
+ mediaType: UploadMediaType.VIDEO,
101
+ label: "uploadVideoToWeixin",
102
+ });
103
+ }
104
+ /**
105
+ * Upload a local file attachment (non-image, non-video) to the Weixin CDN.
106
+ * Uses media_type=FILE; no thumbnail required.
107
+ */
108
+ export async function uploadFileAttachmentToWeixin(params) {
109
+ return uploadMediaToCdn({
110
+ ...params,
111
+ mediaType: UploadMediaType.FILE,
112
+ label: "uploadFileAttachmentToWeixin",
113
+ });
114
+ }
115
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/cdn/upload.ts"],"names":[],"mappings":"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"}