@krischoichoi/channel-weixin 0.6.0

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 (138) hide show
  1. package/README.md +101 -0
  2. package/lib/adapter.d.ts +90 -0
  3. package/lib/adapter.d.ts.map +1 -0
  4. package/lib/adapter.js +247 -0
  5. package/lib/adapter.js.map +1 -0
  6. package/lib/auth/account-store.d.ts +60 -0
  7. package/lib/auth/account-store.d.ts.map +1 -0
  8. package/lib/auth/account-store.js +84 -0
  9. package/lib/auth/account-store.js.map +1 -0
  10. package/lib/auth/login.d.ts +83 -0
  11. package/lib/auth/login.d.ts.map +1 -0
  12. package/lib/auth/login.js +202 -0
  13. package/lib/auth/login.js.map +1 -0
  14. package/lib/config.d.ts +52 -0
  15. package/lib/config.d.ts.map +1 -0
  16. package/lib/config.js +36 -0
  17. package/lib/config.js.map +1 -0
  18. package/lib/definition.d.ts +59 -0
  19. package/lib/definition.d.ts.map +1 -0
  20. package/lib/definition.js +146 -0
  21. package/lib/definition.js.map +1 -0
  22. package/lib/ilink/base-info.d.ts +22 -0
  23. package/lib/ilink/base-info.d.ts.map +1 -0
  24. package/lib/ilink/base-info.js +11 -0
  25. package/lib/ilink/base-info.js.map +1 -0
  26. package/lib/ilink/client.d.ts +110 -0
  27. package/lib/ilink/client.d.ts.map +1 -0
  28. package/lib/ilink/client.js +308 -0
  29. package/lib/ilink/client.js.map +1 -0
  30. package/lib/ilink/constants.d.ts +59 -0
  31. package/lib/ilink/constants.d.ts.map +1 -0
  32. package/lib/ilink/constants.js +59 -0
  33. package/lib/ilink/constants.js.map +1 -0
  34. package/lib/ilink/errors.d.ts +79 -0
  35. package/lib/ilink/errors.d.ts.map +1 -0
  36. package/lib/ilink/errors.js +121 -0
  37. package/lib/ilink/errors.js.map +1 -0
  38. package/lib/ilink/headers.d.ts +40 -0
  39. package/lib/ilink/headers.d.ts.map +1 -0
  40. package/lib/ilink/headers.js +70 -0
  41. package/lib/ilink/headers.js.map +1 -0
  42. package/lib/ilink/schema.d.ts +154 -0
  43. package/lib/ilink/schema.d.ts.map +1 -0
  44. package/lib/ilink/schema.js +140 -0
  45. package/lib/ilink/schema.js.map +1 -0
  46. package/lib/ilink/types.d.ts +235 -0
  47. package/lib/ilink/types.d.ts.map +1 -0
  48. package/lib/ilink/types.js +21 -0
  49. package/lib/ilink/types.js.map +1 -0
  50. package/lib/index.d.ts +50 -0
  51. package/lib/index.d.ts.map +1 -0
  52. package/lib/index.js +91 -0
  53. package/lib/index.js.map +1 -0
  54. package/lib/manifest.d.ts +54 -0
  55. package/lib/manifest.d.ts.map +1 -0
  56. package/lib/manifest.js +32 -0
  57. package/lib/manifest.js.map +1 -0
  58. package/lib/media/decrypt.d.ts +3 -0
  59. package/lib/media/decrypt.d.ts.map +1 -0
  60. package/lib/media/decrypt.js +16 -0
  61. package/lib/media/decrypt.js.map +1 -0
  62. package/lib/media/download.d.ts +22 -0
  63. package/lib/media/download.d.ts.map +1 -0
  64. package/lib/media/download.js +62 -0
  65. package/lib/media/download.js.map +1 -0
  66. package/lib/media/encrypt.d.ts +3 -0
  67. package/lib/media/encrypt.d.ts.map +1 -0
  68. package/lib/media/encrypt.js +16 -0
  69. package/lib/media/encrypt.js.map +1 -0
  70. package/lib/media/send-media.d.ts +41 -0
  71. package/lib/media/send-media.d.ts.map +1 -0
  72. package/lib/media/send-media.js +52 -0
  73. package/lib/media/send-media.js.map +1 -0
  74. package/lib/media/silk-transcode.d.ts +38 -0
  75. package/lib/media/silk-transcode.d.ts.map +1 -0
  76. package/lib/media/silk-transcode.js +88 -0
  77. package/lib/media/silk-transcode.js.map +1 -0
  78. package/lib/media/upload.d.ts +38 -0
  79. package/lib/media/upload.d.ts.map +1 -0
  80. package/lib/media/upload.js +122 -0
  81. package/lib/media/upload.js.map +1 -0
  82. package/lib/messaging/dedup.d.ts +87 -0
  83. package/lib/messaging/dedup.d.ts.map +1 -0
  84. package/lib/messaging/dedup.js +127 -0
  85. package/lib/messaging/dedup.js.map +1 -0
  86. package/lib/messaging/mapper.d.ts +26 -0
  87. package/lib/messaging/mapper.d.ts.map +1 -0
  88. package/lib/messaging/mapper.js +107 -0
  89. package/lib/messaging/mapper.js.map +1 -0
  90. package/lib/messaging/monitor.d.ts +109 -0
  91. package/lib/messaging/monitor.d.ts.map +1 -0
  92. package/lib/messaging/monitor.js +234 -0
  93. package/lib/messaging/monitor.js.map +1 -0
  94. package/lib/messaging/quote.d.ts +9 -0
  95. package/lib/messaging/quote.d.ts.map +1 -0
  96. package/lib/messaging/quote.js +35 -0
  97. package/lib/messaging/quote.js.map +1 -0
  98. package/lib/messaging/send.d.ts +54 -0
  99. package/lib/messaging/send.d.ts.map +1 -0
  100. package/lib/messaging/send.js +173 -0
  101. package/lib/messaging/send.js.map +1 -0
  102. package/lib/messaging/typing.d.ts +34 -0
  103. package/lib/messaging/typing.d.ts.map +1 -0
  104. package/lib/messaging/typing.js +56 -0
  105. package/lib/messaging/typing.js.map +1 -0
  106. package/lib/storage/context-token.d.ts +26 -0
  107. package/lib/storage/context-token.d.ts.map +1 -0
  108. package/lib/storage/context-token.js +26 -0
  109. package/lib/storage/context-token.js.map +1 -0
  110. package/lib/storage/sync-cursor.d.ts +27 -0
  111. package/lib/storage/sync-cursor.d.ts.map +1 -0
  112. package/lib/storage/sync-cursor.js +25 -0
  113. package/lib/storage/sync-cursor.js.map +1 -0
  114. package/lib/transport.d.ts +38 -0
  115. package/lib/transport.d.ts.map +1 -0
  116. package/lib/transport.js +68 -0
  117. package/lib/transport.js.map +1 -0
  118. package/lib/upstream/compat.d.ts +54 -0
  119. package/lib/upstream/compat.d.ts.map +1 -0
  120. package/lib/upstream/compat.js +54 -0
  121. package/lib/upstream/compat.js.map +1 -0
  122. package/lib/upstream/config-manager.d.ts +35 -0
  123. package/lib/upstream/config-manager.d.ts.map +1 -0
  124. package/lib/upstream/config-manager.js +91 -0
  125. package/lib/upstream/config-manager.js.map +1 -0
  126. package/lib/upstream/index.d.ts +42 -0
  127. package/lib/upstream/index.d.ts.map +1 -0
  128. package/lib/upstream/index.js +13 -0
  129. package/lib/upstream/index.js.map +1 -0
  130. package/lib/upstream/port.d.ts +153 -0
  131. package/lib/upstream/port.d.ts.map +1 -0
  132. package/lib/upstream/port.js +15 -0
  133. package/lib/upstream/port.js.map +1 -0
  134. package/lib/upstream/tencent-upstream.d.ts +116 -0
  135. package/lib/upstream/tencent-upstream.d.ts.map +1 -0
  136. package/lib/upstream/tencent-upstream.js +518 -0
  137. package/lib/upstream/tencent-upstream.js.map +1 -0
  138. package/package.json +48 -0
@@ -0,0 +1,518 @@
1
+ /**
2
+ * tencent-upstream.ts — DSH-hosted Weixin iLink source-port.
3
+ *
4
+ * Tencent's published @tencent-weixin/openclaw-weixin plugin couples its
5
+ * runtime to OpenClaw. It is retained as a source reference only: importing
6
+ * its internal dist paths or installing its OpenClaw peer dependency would
7
+ * violate the DSH host boundary. Protocol orchestration and AES therefore stay
8
+ * in this adapter behind the WeixinUpstream port.
9
+ *
10
+ * ZERO-REGRESSION contract:
11
+ * Weixin image → localData → saveImage() → ImageBlock unchanged.
12
+ * downloadImage() returns the SAME decrypted bytes legacy media/download.ts
13
+ * produced. URL resolution keeps the legacy shape because the Tencent plugin
14
+ * uses a different URL form that would alter the working CDN path.
15
+ */
16
+ import { ChannelError, SecureRemoteMediaFetcher, mimeHintFromFilename, } from '@krischoichoi/channel-core';
17
+ import pkg from '../../package.json' with { type: 'json' };
18
+ import { ILinkClient } from '../ilink/client.js';
19
+ import { FetchTransport } from '../transport.js';
20
+ import { AccountCredentialStore } from '../auth/account-store.js';
21
+ import { WeixinQrAuth } from '../auth/login.js';
22
+ import { SyncCursorStore } from '../storage/sync-cursor.js';
23
+ import { ContextTokenStore } from '../storage/context-token.js';
24
+ import { WeixinMonitor } from '../messaging/monitor.js';
25
+ import { OutboundSender } from '../messaging/send.js';
26
+ import { TypingController } from '../messaging/typing.js';
27
+ import { WeixinConfigManager } from './config-manager.js';
28
+ import { transcodeSilkVoice } from '../media/silk-transcode.js';
29
+ import { aes128Decrypt } from '../media/decrypt.js';
30
+ /** Matches the generic channel attachment store's inbound transport cap. */
31
+ const MAX_INBOUND_MEDIA_BYTES = 100 * 1024 * 1024;
32
+ /**
33
+ * The concrete upstream implementation. Owns every protocol/media detail; the
34
+ * adapter depends only on the `WeixinUpstream` port.
35
+ */
36
+ export class TencentWeixinUpstream {
37
+ id = 'weixin';
38
+ config;
39
+ now;
40
+ rand;
41
+ transport;
42
+ mediaFetcher;
43
+ env;
44
+ client;
45
+ credentialStore;
46
+ cursorStore;
47
+ contextTokens;
48
+ qrAuth;
49
+ sender;
50
+ monitor;
51
+ typing;
52
+ configManager;
53
+ typingPeer;
54
+ connected = 'not-started';
55
+ /** Whether a credential is loaded/persisted (the adapter's "authenticated"). */
56
+ authenticated = false;
57
+ /** Active QR ticket id + expiry, so pollAuth can rebuild the challenge. */
58
+ activeQrId;
59
+ activeQrExpiresAt;
60
+ constructor(options) {
61
+ this.config = options.config;
62
+ this.now = options.now ?? Date.now;
63
+ this.rand = options.rand ?? Math.random;
64
+ this.transport = options.transport ?? new FetchTransport({ timeoutMs: options.config.network?.timeoutMs ?? 15000 });
65
+ this.mediaFetcher = options.mediaFetcher ?? new SecureRemoteMediaFetcher({
66
+ fetch: (options.fetchImpl ?? globalThis.fetch),
67
+ });
68
+ }
69
+ /**
70
+ * Wire the host environment (stores + context) and build the internal
71
+ * protocol session. Called by the adapter at start(); idempotent.
72
+ */
73
+ bind(env) {
74
+ if (this.env && this.env.ctx === env.ctx)
75
+ return;
76
+ this.env = env;
77
+ const ilink = this.config.ilink ?? { baseUrl: 'https://ilinkai.weixin.qq.com' };
78
+ const clientOpts = {
79
+ baseUrl: ilink.baseUrl,
80
+ cdnBaseUrl: ilink.cdnBaseUrl,
81
+ timeoutMs: this.config.network?.timeoutMs ?? 15000,
82
+ longPollTimeoutMs: this.config.network?.longPollTimeoutMs ?? 35000,
83
+ botAgent: ilink.botAgent ?? 'DeepSeekHarness/' + pkg.version,
84
+ transport: this.transport,
85
+ now: this.now,
86
+ rand: this.rand,
87
+ };
88
+ this.client = new ILinkClient(clientOpts, this.config.accountId);
89
+ this.credentialStore = new AccountCredentialStore({
90
+ secrets: env.secrets,
91
+ storage: env.storage,
92
+ accountId: this.config.accountId,
93
+ now: this.now,
94
+ });
95
+ this.cursorStore = new SyncCursorStore({ storage: env.storage, accountId: this.config.accountId });
96
+ this.contextTokens = new ContextTokenStore({ storage: env.storage, accountId: this.config.accountId });
97
+ this.sender = new OutboundSender({
98
+ client: this.client,
99
+ contextTokens: this.contextTokens,
100
+ cdnBaseUrl: this.client.cdnUrl,
101
+ apiBaseUrl: this.client.baseUrl,
102
+ });
103
+ this.configManager = new WeixinConfigManager({
104
+ fetchConfig: (peer) => this.client.getConfig({ ilink_user_id: peer }),
105
+ now: this.now,
106
+ rand: this.rand,
107
+ });
108
+ this.typing = new TypingController({
109
+ client: this.client,
110
+ enabled: true,
111
+ typingTicket: () => this.resolveTypingTicket(this.typingPeer),
112
+ });
113
+ }
114
+ hasCredential() {
115
+ return this.authenticated;
116
+ }
117
+ /**
118
+ * Load the persisted credential, applying token/baseUrl to the client.
119
+ * Returns true when a full credential exists. This is the adapter's "have we
120
+ * authenticated before?" signal.
121
+ */
122
+ async loadCredential() {
123
+ const store = this.credentialStore;
124
+ const client = this.client;
125
+ if (!store || !client)
126
+ return false;
127
+ const credential = await store.load();
128
+ if (!credential)
129
+ return false;
130
+ client.setToken(credential.token);
131
+ if (credential.baseUrl)
132
+ client.setBaseUrl(credential.baseUrl);
133
+ this.authenticated = true;
134
+ this.configManager?.clear();
135
+ return true;
136
+ }
137
+ // ── QR auth (WeixinQrAuth — DSH glue over the iLink client) ──
138
+ async beginQrAuth() {
139
+ this.ensureSession();
140
+ const storedCredential = await this.credentialStore?.load();
141
+ this.qrAuth = new WeixinQrAuth({
142
+ client: this.client,
143
+ localTokens: storedCredential?.token ? [storedCredential.token] : [],
144
+ now: this.now,
145
+ });
146
+ const challenge = await this.qrAuth.beginAuth();
147
+ this.activeQrId = challenge.id;
148
+ this.activeQrExpiresAt = challenge.expiresAt;
149
+ return {
150
+ id: challenge.id,
151
+ qrUrl: challenge.qrUrl,
152
+ instruction: challenge.instruction,
153
+ expiresAt: challenge.expiresAt,
154
+ };
155
+ }
156
+ async pollQrAuth(ticketId) {
157
+ this.ensureSession();
158
+ if (!this.qrAuth)
159
+ throw new ChannelError('CHANNEL_AUTH_FAILED', 'weixin QR auth is not started');
160
+ // WeixinQrAuth only inspects challenge.id + expiresAt; instruction is unused
161
+ // for the poll path (the adapter owns the operator-facing prompt).
162
+ const challenge = { id: ticketId, instruction: '', expiresAt: this.activeQrExpiresAt };
163
+ const result = await this.qrAuth.pollAuth(challenge);
164
+ if (result.state === 'authenticated') {
165
+ const cred = this.qrAuth.confirmedCredential;
166
+ if (cred) {
167
+ await this.persistCredential({
168
+ token: cred.token,
169
+ ilinkBotId: cred.ilinkBotId,
170
+ userId: cred.userId,
171
+ baseUrl: cred.baseUrl,
172
+ });
173
+ }
174
+ else {
175
+ // `binded_redirect` confirms a locally-held token is still associated
176
+ // with this bot. Reapply it because a prior stale-token transition
177
+ // intentionally cleared the in-memory client token.
178
+ const stored = await this.credentialStore?.load();
179
+ if (stored) {
180
+ this.client?.setToken(stored.token);
181
+ this.client?.setBaseUrl(stored.baseUrl);
182
+ this.authenticated = true;
183
+ this.configManager?.clear();
184
+ if (!this.monitor)
185
+ await this.startMonitor();
186
+ }
187
+ }
188
+ return { state: 'authenticated', detail: result.detail, credential: cred ?? undefined };
189
+ }
190
+ return { state: result.state, detail: result.detail };
191
+ }
192
+ submitVerifyCode(code) {
193
+ this.ensureSession();
194
+ if (!this.qrAuth)
195
+ throw new ChannelError('CHANNEL_AUTH_FAILED', 'weixin QR auth is not started');
196
+ this.qrAuth.submitVerifyCode(code);
197
+ }
198
+ // ── Monitor ──
199
+ async startMonitor() {
200
+ this.ensureSession();
201
+ if (this.monitor)
202
+ return;
203
+ const ctx = this.env.ctx;
204
+ const monitor = new WeixinMonitor({
205
+ client: this.client,
206
+ cursor: this.cursorStore,
207
+ contextTokens: this.contextTokens,
208
+ ctx,
209
+ meta: { channel: 'weixin', accountId: this.config.accountId },
210
+ reconnect: this.config.reconnect ?? { enabled: true, baseDelayMs: 2000, maxDelayMs: 30000 },
211
+ longPollTimeoutMs: this.config.network?.longPollTimeoutMs ?? 35000,
212
+ dedupWindowMs: 30_000,
213
+ now: this.now,
214
+ onConnectionChange: (st) => {
215
+ this.connected = st;
216
+ this.env?.onConnectionChange?.(st);
217
+ },
218
+ onStaleToken: async () => {
219
+ this.authenticated = false;
220
+ this.connected = 'disconnected';
221
+ this.monitor = undefined;
222
+ this.client?.setToken(undefined);
223
+ this.configManager?.clear();
224
+ await ctx.emit({
225
+ type: 'auth.changed',
226
+ channel: 'weixin',
227
+ accountId: this.config.accountId,
228
+ state: 'expired',
229
+ detail: 'weixin token expired; scan QR to authenticate again',
230
+ });
231
+ },
232
+ beforeEmit: async (event) => {
233
+ // Download + decrypt inbound media before dispatch so image and file
234
+ // parts can enter the common Harness attachment pipeline.
235
+ await this.enrichInboundMedia(event);
236
+ },
237
+ emit: (event) => ctx.emit(event),
238
+ });
239
+ this.monitor = monitor;
240
+ this.connected = 'connected';
241
+ await monitor.start();
242
+ }
243
+ async stopMonitor() {
244
+ const monitor = this.monitor;
245
+ if (monitor) {
246
+ try {
247
+ await monitor.stop();
248
+ }
249
+ catch {
250
+ // best effort
251
+ }
252
+ }
253
+ this.monitor = undefined;
254
+ this.connected = 'disconnected';
255
+ }
256
+ // ── Send ──
257
+ async sendText(params) {
258
+ this.requireReady();
259
+ const res = await this.sender.send(this.targetOf(params), { text: params.text });
260
+ return res;
261
+ }
262
+ async sendImage(params) {
263
+ this.requireReady();
264
+ const image = {
265
+ type: 'image',
266
+ localData: params.data,
267
+ mimeType: params.mimeType,
268
+ };
269
+ return this.sender.send(this.targetOf(params), { parts: [image] });
270
+ }
271
+ async sendFile(params) {
272
+ this.requireReady();
273
+ return this.sender.send(this.targetOf(params), {
274
+ parts: [{ type: 'file', localData: params.data, name: params.fileName, mimeType: params.mimeType }],
275
+ });
276
+ }
277
+ async sendVideo(params) {
278
+ this.requireReady();
279
+ return this.sender.send(this.targetOf(params), {
280
+ parts: [{ type: 'video', localData: params.data, mimeType: params.mimeType }],
281
+ });
282
+ }
283
+ // ── Media download ──
284
+ async downloadImage(ref) {
285
+ const data = await this.downloadAndDecrypt(ref);
286
+ return { data, mimeType: ref.mimeType ?? guessImageMime(data) };
287
+ }
288
+ async downloadFile(ref) {
289
+ const data = await this.downloadAndDecrypt(ref);
290
+ return { data, mimeType: ref.mimeType };
291
+ }
292
+ async downloadAudio(ref, options = {}) {
293
+ const data = Buffer.from(await this.downloadAndDecrypt(ref));
294
+ const decoded = await transcodeSilkVoice(data, options);
295
+ return { data: new Uint8Array(decoded.data), mimeType: decoded.mimeType };
296
+ }
297
+ async downloadVideo(ref) {
298
+ const data = await this.downloadAndDecrypt(ref);
299
+ return { data, mimeType: ref.mimeType ?? 'video/mp4' };
300
+ }
301
+ // ── Typing (operational, not part of the minimal port) ──
302
+ async startTyping(conversationId) {
303
+ if (!this.typing)
304
+ return;
305
+ this.typingPeer = conversationId;
306
+ try {
307
+ await this.typing.start(conversationId);
308
+ }
309
+ catch {
310
+ // best effort
311
+ }
312
+ }
313
+ async stopTyping(conversationId) {
314
+ if (!this.typing)
315
+ return;
316
+ this.typingPeer = conversationId;
317
+ try {
318
+ await this.typing.stop(conversationId);
319
+ }
320
+ catch {
321
+ // best effort
322
+ }
323
+ }
324
+ /** Health introspection (bound credential + connection). */
325
+ async getHealthInfo() {
326
+ if (!this.credentialStore || !this.client) {
327
+ return { authenticated: false, connection: 'not-started' };
328
+ }
329
+ const credential = await this.credentialStore.load().catch(() => undefined);
330
+ return { authenticated: Boolean(credential?.token) && this.authenticated, connection: this.connected };
331
+ }
332
+ /** Introspection for tests: the underlying client. */
333
+ get_iLinkClient() {
334
+ return this.client;
335
+ }
336
+ // ── Internals ──
337
+ ensureSession() {
338
+ if (!this.env)
339
+ throw new ChannelError('CHANNEL_NOT_STARTED', 'weixin upstream is not bound; call bind() first');
340
+ if (!this.client)
341
+ throw new ChannelError('CHANNEL_NOT_STARTED', 'weixin upstream protocol session is not initialised');
342
+ }
343
+ requireReady() {
344
+ this.ensureSession();
345
+ if (!this.sender)
346
+ throw new ChannelError('CHANNEL_NOT_STARTED', 'weixin upstream is not initialised');
347
+ if (!this.authenticated)
348
+ throw new ChannelError('CHANNEL_AUTH_FAILED', 'weixin is not authenticated; scan QR to continue');
349
+ }
350
+ targetOf(params) {
351
+ return {
352
+ channelId: 'weixin',
353
+ accountId: this.config.accountId,
354
+ conversationId: params.to,
355
+ runId: params.runId,
356
+ };
357
+ }
358
+ async persistCredential(cred) {
359
+ if (!this.credentialStore || !this.client)
360
+ return;
361
+ await this.credentialStore.save({
362
+ token: cred.token,
363
+ ilinkBotId: cred.ilinkBotId,
364
+ userId: cred.userId,
365
+ baseUrl: cred.baseUrl || this.client.baseUrl,
366
+ savedAt: new Date(this.now()).toISOString(),
367
+ });
368
+ this.client.setToken(cred.token);
369
+ this.client.setBaseUrl(cred.baseUrl || this.client.baseUrl);
370
+ this.authenticated = true;
371
+ this.configManager?.clear();
372
+ if (!this.sender && this.contextTokens && this.client) {
373
+ this.sender = new OutboundSender({ client: this.client, contextTokens: this.contextTokens });
374
+ }
375
+ // Start the monitor for a fresh QR login once the env is bound and the
376
+ // adapter has started (mirrors the old persistCredentialFromAuth).
377
+ if (this.env && !this.monitor) {
378
+ await this.startMonitor();
379
+ }
380
+ }
381
+ /** Hydrate inbound media before the event reaches the attachment pipeline. */
382
+ async enrichInboundMedia(event) {
383
+ if (!this.client)
384
+ return;
385
+ const raw = event.raw;
386
+ const items = raw?.item_list ?? [];
387
+ const parts = event.message.content;
388
+ const cdnBaseUrl = this.client.cdnUrl;
389
+ const consumedItems = new Set();
390
+ for (const part of parts) {
391
+ if (part.type !== 'image' && part.type !== 'file' && part.type !== 'audio' && part.type !== 'video')
392
+ continue;
393
+ const itemIndex = items.findIndex((candidate, index) => !consumedItems.has(index) && itemMatchesPart(candidate, part.type));
394
+ if (itemIndex < 0)
395
+ continue;
396
+ consumedItems.add(itemIndex);
397
+ const item = items[itemIndex];
398
+ const img = item?.image_item;
399
+ const file = item?.file_item;
400
+ const voice = item?.voice_item;
401
+ const video = item?.video_item;
402
+ const media = (img?.media ?? file?.media ?? voice?.media ?? video?.media);
403
+ if (!media)
404
+ continue;
405
+ try {
406
+ const ref = {
407
+ cdnBaseUrl,
408
+ fullUrl: media.full_url,
409
+ encryptQueryParam: media.encrypt_query_param,
410
+ aesKeyHex: img?.aeskey,
411
+ aesKeyBase64: media.aes_key,
412
+ mimeType: part.mimeType ?? (part.type === 'file'
413
+ ? mimeHintFromFilename(file?.file_name)
414
+ : part.type === 'video'
415
+ ? 'video/mp4'
416
+ : part.type === 'image'
417
+ ? 'image/jpeg'
418
+ : undefined),
419
+ };
420
+ const downloaded = part.type === 'image'
421
+ ? await this.downloadImage(ref)
422
+ : part.type === 'file'
423
+ ? await this.downloadFile(ref)
424
+ : part.type === 'audio'
425
+ ? await this.downloadAudio(ref, { encodeType: voice?.encode_type, sampleRate: voice?.sample_rate })
426
+ : await this.downloadVideo(ref);
427
+ part.localData = downloaded.data;
428
+ part.mimeType = downloaded.mimeType ?? part.mimeType;
429
+ if (part.type === 'file')
430
+ part.size = downloaded.data.byteLength;
431
+ }
432
+ catch (error) {
433
+ // Keep delivery alive, but expose the reason. In practice this catches
434
+ // malformed CDN keys and expired media URLs; hiding it makes a file
435
+ // look like a Harness storage failure even though ingress failed.
436
+ this.env?.ctx.logger.warn('[channel-weixin] inbound media download failed', {
437
+ kind: part.type,
438
+ name: part.type === 'file' ? part.name : undefined,
439
+ error: error instanceof Error ? error.message : String(error),
440
+ });
441
+ part.ingressFailure = 'download-failed';
442
+ }
443
+ }
444
+ }
445
+ /**
446
+ * Resolve the platform media reference, then cross the shared secure remote
447
+ * media boundary before applying Weixin's source-port AES decryption.
448
+ */
449
+ async downloadAndDecrypt(ref) {
450
+ const url = this.resolveDownloadUrl(ref);
451
+ if (!url) {
452
+ throw new Error('weixin media download: no fullUrl or encryptQueryParam to resolve a CDN URL');
453
+ }
454
+ const result = await this.mediaFetcher.fetchBounded(url, {
455
+ maxBytes: MAX_INBOUND_MEDIA_BYTES,
456
+ timeoutMs: this.config.network?.timeoutMs ?? 15_000,
457
+ idleTimeoutMs: this.config.network?.timeoutMs ?? 15_000,
458
+ signal: this.env?.ctx.signal,
459
+ });
460
+ const body = Buffer.from(result.data);
461
+ const key = this.resolveAesKey(ref);
462
+ if (!key)
463
+ return new Uint8Array(body);
464
+ // Official AES-128-ECB decrypt (PKCS#7) — source of truth for crypto.
465
+ return new Uint8Array(aes128Decrypt(body, key));
466
+ }
467
+ resolveDownloadUrl(ref) {
468
+ if (ref.fullUrl)
469
+ return ref.fullUrl;
470
+ if (!ref.cdnBaseUrl || !ref.encryptQueryParam)
471
+ return undefined;
472
+ // Match Tencent's upstream fallback when the server omits full_url.
473
+ const base = ref.cdnBaseUrl.replace(/\/+$/, '');
474
+ return `${base}/download?encrypted_query_param=${encodeURIComponent(ref.encryptQueryParam)}`;
475
+ }
476
+ /** Resolve the AES-128 key honoring hex (item aeskey) then base64 (media aes_key). */
477
+ resolveAesKey(ref) {
478
+ if (ref.aesKeyHex)
479
+ return Buffer.from(ref.aesKeyHex, 'hex');
480
+ if (ref.aesKeyBase64) {
481
+ // Tencent sends images as base64(raw 16 bytes), while file/voice/video
482
+ // may be base64(32 ASCII hex chars). Accept both wire encodings.
483
+ const decoded = Buffer.from(ref.aesKeyBase64, 'base64');
484
+ if (decoded.length === 16)
485
+ return decoded;
486
+ const hex = decoded.toString('ascii');
487
+ if (decoded.length === 32 && /^[0-9a-fA-F]{32}$/.test(hex))
488
+ return Buffer.from(hex, 'hex');
489
+ throw new Error(`weixin media download: aes_key decoded to ${decoded.length} bytes, expected 16 bytes or 32-char hex`);
490
+ }
491
+ return undefined;
492
+ }
493
+ async resolveTypingTicket(peer) {
494
+ return this.configManager?.resolveTypingTicket(peer);
495
+ }
496
+ }
497
+ function itemMatchesPart(item, type) {
498
+ return (type === 'image' && item?.type === 2)
499
+ || (type === 'audio' && item?.type === 3)
500
+ || (type === 'file' && item?.type === 4)
501
+ || (type === 'video' && item?.type === 5);
502
+ }
503
+ /** Cheap JPEG/PNG/WebP/GIF sniff for the default mime when none is supplied. */
504
+ function guessImageMime(data) {
505
+ if (data.length < 12)
506
+ return undefined;
507
+ if (data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4e && data[3] === 0x47)
508
+ return 'image/png';
509
+ if (data[0] === 0xff && data[1] === 0xd8)
510
+ return 'image/jpeg';
511
+ if (data[0] === 0x47 && data[1] === 0x49 && data[2] === 0x46)
512
+ return 'image/gif';
513
+ if (data[0] === 0x52 && data[1] === 0x49 && data[2] === 0x46 && data[3] === 0x46 &&
514
+ data[8] === 0x57 && data[9] === 0x45 && data[10] === 0x42 && data[11] === 0x50)
515
+ return 'image/webp';
516
+ return undefined;
517
+ }
518
+ //# sourceMappingURL=tencent-upstream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tencent-upstream.js","sourceRoot":"","sources":["../../src/upstream/tencent-upstream.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@krischoichoi/channel-weixin",
3
+ "version": "0.6.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/krischoichoi/dsh-channels.git"
7
+ },
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "description": "Weixin channel adapter for DeepSeek Harness (upstream driver skeleton in M0)",
12
+ "type": "module",
13
+ "main": "./lib/index.js",
14
+ "types": "./lib/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./lib/index.d.ts",
18
+ "default": "./lib/index.js"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "files": [
23
+ "lib"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc -p tsconfig.json",
27
+ "typecheck": "tsc -p tsconfig.json --noEmit",
28
+ "test": "vitest run --passWithNoTests",
29
+ "test:live": "vitest run test/live",
30
+ "clean": "rimraf lib"
31
+ },
32
+ "dependencies": {
33
+ "@deepseek-ai/cordis": "^4.0.4",
34
+ "@deepseek-ai/dsh-settings": "0.2.0-rc.2",
35
+ "@deepseek-ai/schemastery": "~3.18.4",
36
+ "@krischoichoi/channel-control": "workspace:*",
37
+ "@krischoichoi/channel-core": "workspace:*",
38
+ "zod": "^4.4.3"
39
+ },
40
+ "devDependencies": {
41
+ "@krischoichoi/channel-testkit": "workspace:*",
42
+ "rimraf": "^6.0.0"
43
+ },
44
+ "optionalDependencies": {
45
+ "silk-wasm": "^3.7.1"
46
+ },
47
+ "license": "MIT"
48
+ }