imtoagent 0.3.4 → 0.3.6
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/README.md +97 -97
- package/bin/imtoagent-real +197 -153
- package/bin/imtoagent.cjs +13 -5
- package/index.ts +106 -106
- package/modules/agent/claude-adapter.ts +6 -6
- package/modules/agent/claude.ts +6 -6
- package/modules/agent/codex-adapter.ts +13 -13
- package/modules/agent/codex-exec-server.ts +11 -11
- package/modules/agent/codex.ts +29 -29
- package/modules/agent/opencode-adapter.ts +17 -17
- package/modules/agent/opencode.ts +10 -10
- package/modules/capabilities.ts +33 -33
- package/modules/cli/setup.ts +164 -164
- package/modules/core/config.ts +5 -5
- package/modules/core/error.ts +8 -8
- package/modules/core/runtime.ts +10 -10
- package/modules/core/session.ts +4 -4
- package/modules/core/stats.ts +14 -14
- package/modules/core/types.ts +7 -7
- package/modules/im/feishu.ts +56 -56
- package/modules/im/telegram.ts +23 -23
- package/modules/im/wechat.ts +54 -54
- package/modules/im/wecom.ts +50 -50
- package/modules/media/feishu-inbound-adapter.ts +4 -4
- package/modules/media/resolver.ts +11 -11
- package/modules/media/telegram-inbound-adapter.ts +8 -8
- package/modules/prompt-builder.ts +12 -12
- package/modules/proxy/anthropic-proxy.ts +31 -31
- package/modules/proxy/codex-proxy.ts +18 -18
- package/modules/utils/backend-check.ts +12 -12
- package/modules/utils/paths.ts +8 -8
- package/package.json +1 -1
- package/scripts/postinstall.cjs +10 -10
- package/scripts/postinstall.ts +13 -13
- package/templates/soul.template/identity.md +5 -5
- package/templates/soul.template/profile.md +7 -7
- package/templates/soul.template/rules.md +5 -5
- package/templates/soul.template/skills.md +2 -2
- package/templates/soul.template/workspace.md +3 -3
package/modules/im/wechat.ts
CHANGED
|
@@ -154,12 +154,12 @@ async function ilinkPost(endpoint: string, body: any, token?: string): Promise<a
|
|
|
154
154
|
try {
|
|
155
155
|
resolve(JSON.parse(data));
|
|
156
156
|
} catch {
|
|
157
|
-
reject(new Error(
|
|
157
|
+
reject(new Error(`Failed to parse response: ${data.slice(0, 200)}`));
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
161
|
req.on('error', reject);
|
|
162
|
-
req.on('timeout', () => { req.destroy(); reject(new Error('
|
|
162
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('request timeout')); });
|
|
163
163
|
req.write(bodyStr);
|
|
164
164
|
req.end();
|
|
165
165
|
});
|
|
@@ -188,7 +188,7 @@ async function ilinkGet(endpoint: string, token?: string): Promise<any> {
|
|
|
188
188
|
try {
|
|
189
189
|
resolve(JSON.parse(data));
|
|
190
190
|
} catch {
|
|
191
|
-
reject(new Error(
|
|
191
|
+
reject(new Error(`Failed to parse response: ${data.slice(0, 200)}`));
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
194
|
}).on('error', reject).on('timeout', reject);
|
|
@@ -287,7 +287,7 @@ async function getBotQrcode(localTokenList: string[], token?: string): Promise<{
|
|
|
287
287
|
local_token_list: localTokenList,
|
|
288
288
|
}, token);
|
|
289
289
|
if (result.ret !== 0 || !result.qrcode) {
|
|
290
|
-
throw new Error(
|
|
290
|
+
throw new Error(`Failed to get QR code: ${JSON.stringify(result).slice(0, 200)}`);
|
|
291
291
|
}
|
|
292
292
|
return { qrcode: result.qrcode, qrcode_img_content: result.qrcode_img_content };
|
|
293
293
|
}
|
|
@@ -326,8 +326,8 @@ async function renderQR(qrContent: string): Promise<void> {
|
|
|
326
326
|
* 返回 ilink_bot_id, bot_token, ilink_user_id
|
|
327
327
|
*/
|
|
328
328
|
export async function bindWechatQR(): Promise<{ botId: string; botToken: string; ilinkUserId: string }> {
|
|
329
|
-
console.log('\n📱
|
|
330
|
-
console.log('
|
|
329
|
+
console.log('\n📱 WeChat QR Code Binding');
|
|
330
|
+
console.log('Fetching QR code...');
|
|
331
331
|
|
|
332
332
|
let refreshCount = 0;
|
|
333
333
|
let currentToken: string | undefined;
|
|
@@ -335,9 +335,9 @@ export async function bindWechatQR(): Promise<{ botId: string; botToken: string;
|
|
|
335
335
|
while (refreshCount < MAX_QR_REFRESH) {
|
|
336
336
|
const { qrcode, qrcode_img_content } = await getBotQrcode([], currentToken);
|
|
337
337
|
|
|
338
|
-
console.log('
|
|
338
|
+
console.log('Please scan the following QR code with WeChat:');
|
|
339
339
|
await renderQR(qrcode_img_content || qrcode);
|
|
340
|
-
console.log('
|
|
340
|
+
console.log('Waiting for scan...');
|
|
341
341
|
|
|
342
342
|
const start = Date.now();
|
|
343
343
|
while (Date.now() - start < QR_POLL_TIMEOUT_MS) {
|
|
@@ -345,7 +345,7 @@ export async function bindWechatQR(): Promise<{ botId: string; botToken: string;
|
|
|
345
345
|
|
|
346
346
|
switch (statusResult.status) {
|
|
347
347
|
case 'confirmed':
|
|
348
|
-
console.log('\n✅
|
|
348
|
+
console.log('\n✅ QR scan successful!');
|
|
349
349
|
const creds: StoredCreds = {
|
|
350
350
|
botId: statusResult.ilink_bot_id!,
|
|
351
351
|
botToken: statusResult.bot_token!,
|
|
@@ -372,15 +372,15 @@ export async function bindWechatQR(): Promise<{ botId: string; botToken: string;
|
|
|
372
372
|
break;
|
|
373
373
|
|
|
374
374
|
case 'need_verifycode':
|
|
375
|
-
console.log('\n⚠️
|
|
376
|
-
console.log('
|
|
377
|
-
throw new Error('
|
|
375
|
+
console.log('\n⚠️ Pairing code required (number shown on phone WeChat)');
|
|
376
|
+
console.log('This feature does not support automatic handling yet, please verify on phone and retry');
|
|
377
|
+
throw new Error('Pairing code verification required');
|
|
378
378
|
|
|
379
379
|
case 'verify_code_blocked':
|
|
380
|
-
throw new Error('
|
|
380
|
+
throw new Error('Pairing code entered incorrectly too many times, please re-scan');
|
|
381
381
|
|
|
382
382
|
case 'expired':
|
|
383
|
-
console.log('\n⏱
|
|
383
|
+
console.log('\n⏱ QR code expired, refreshing...');
|
|
384
384
|
refreshCount++;
|
|
385
385
|
break;
|
|
386
386
|
|
|
@@ -393,10 +393,10 @@ export async function bindWechatQR(): Promise<{ botId: string; botToken: string;
|
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
refreshCount++;
|
|
396
|
-
console.log('\n⏱
|
|
396
|
+
console.log('\n⏱ QR scan timed out, refreshing QR code...');
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
-
console.log('\n❌
|
|
399
|
+
console.log('\n❌ QR code refresh limit exceeded, please retry');
|
|
400
400
|
process.exit(1);
|
|
401
401
|
}
|
|
402
402
|
|
|
@@ -459,7 +459,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
459
459
|
getCapabilities(): IMCapabilities {
|
|
460
460
|
return {
|
|
461
461
|
text: true,
|
|
462
|
-
codeBlock: false, //
|
|
462
|
+
codeBlock: false, // WeChat doesn't support code blocks
|
|
463
463
|
cardMessage: false,
|
|
464
464
|
fileSend: true,
|
|
465
465
|
imageSend: true,
|
|
@@ -473,7 +473,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
473
473
|
|
|
474
474
|
start(handler: MessageHandler): void {
|
|
475
475
|
if (this.running) {
|
|
476
|
-
console.warn('[WeChat]
|
|
476
|
+
console.warn('[WeChat] Already running');
|
|
477
477
|
return;
|
|
478
478
|
}
|
|
479
479
|
this.handler = handler;
|
|
@@ -486,7 +486,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
486
486
|
if (this.pollTimer) { clearTimeout(this.pollTimer); this.pollTimer = null; }
|
|
487
487
|
this._notifyStop().catch(() => {});
|
|
488
488
|
this.handler = null;
|
|
489
|
-
console.log('[WeChat]
|
|
489
|
+
console.log('[WeChat] Disconnected');
|
|
490
490
|
}
|
|
491
491
|
|
|
492
492
|
// ── 连接 & 认证 ──
|
|
@@ -503,12 +503,12 @@ export class WeChatIMModule implements IMModule {
|
|
|
503
503
|
this.botId = stored.botId;
|
|
504
504
|
this.botToken = stored.botToken;
|
|
505
505
|
this.ilinkUserId = stored.ilinkUserId;
|
|
506
|
-
console.log('[WeChat]
|
|
506
|
+
console.log('[WeChat] Loaded local credentials');
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
if (!this.botId || !this.botToken) {
|
|
511
|
-
console.log('[WeChat]
|
|
511
|
+
console.log('[WeChat] No credentials found, starting QR binding...');
|
|
512
512
|
const bound = await bindWechatQR();
|
|
513
513
|
this.botId = bound.botId;
|
|
514
514
|
this.botToken = bound.botToken;
|
|
@@ -518,9 +518,9 @@ export class WeChatIMModule implements IMModule {
|
|
|
518
518
|
// 2. 加载 context_token
|
|
519
519
|
this.contextTokens = new Map(Object.entries(loadContextTokens()));
|
|
520
520
|
|
|
521
|
-
console.log(`[WeChat]
|
|
521
|
+
console.log(`[WeChat] Authenticated (bot: ${this.botId.slice(0, 8)}...)`);
|
|
522
522
|
|
|
523
|
-
// 3.
|
|
523
|
+
// 3. Notify online
|
|
524
524
|
await this._notifyStart();
|
|
525
525
|
|
|
526
526
|
// 4. 启动 long-poll
|
|
@@ -534,9 +534,9 @@ export class WeChatIMModule implements IMModule {
|
|
|
534
534
|
await ilinkPost('ilink/bot/msg/notifystart', {
|
|
535
535
|
base_info: { channel_version: CHANNEL_VERSION, bot_agent: 'IMtoAgent' },
|
|
536
536
|
}, this.botToken);
|
|
537
|
-
console.log('[WeChat]
|
|
537
|
+
console.log('[WeChat] Notified online');
|
|
538
538
|
} catch (e: any) {
|
|
539
|
-
console.warn(`[WeChat]
|
|
539
|
+
console.warn(`[WeChat] Failed to notify online: ${e.message}`);
|
|
540
540
|
}
|
|
541
541
|
}
|
|
542
542
|
|
|
@@ -557,13 +557,13 @@ export class WeChatIMModule implements IMModule {
|
|
|
557
557
|
// 检查 session 是否暂停(过期冷却)
|
|
558
558
|
if (Date.now() < this.sessionPausedUntil) {
|
|
559
559
|
const remaining = Math.ceil((this.sessionPausedUntil - Date.now()) / 1000);
|
|
560
|
-
console.log(`[WeChat] Session
|
|
560
|
+
console.log(`[WeChat] Session cooling down, ${remaining}s remaining`);
|
|
561
561
|
this.pollTimer = setTimeout(() => this._pollLoop(), Math.min(remaining * 1000, 60000));
|
|
562
562
|
return;
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
this._pollOnce().catch(e => {
|
|
566
|
-
console.error(`[WeChat]
|
|
566
|
+
console.error(`[WeChat] Poll error: ${e.message}`);
|
|
567
567
|
if (this.running) {
|
|
568
568
|
this.pollTimer = setTimeout(() => this._pollLoop(), LONGPOLL_RETRY_DELAY_MS);
|
|
569
569
|
}
|
|
@@ -579,15 +579,15 @@ export class WeChatIMModule implements IMModule {
|
|
|
579
579
|
}, this.botToken);
|
|
580
580
|
|
|
581
581
|
if (result.ret === -14) {
|
|
582
|
-
// Session
|
|
583
|
-
console.error('[WeChat] ⚠️ Session
|
|
582
|
+
// Session expired, pause for 1 hour
|
|
583
|
+
console.error('[WeChat] ⚠️ Session expired, pausing for 1 hour');
|
|
584
584
|
this.sessionPausedUntil = Date.now() + SESSION_PAUSE_MS;
|
|
585
585
|
this.pollTimer = setTimeout(() => this._pollLoop(), SESSION_PAUSE_MS);
|
|
586
586
|
return;
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
if (result.ret !== 0) {
|
|
590
|
-
throw new Error(`getupdates
|
|
590
|
+
throw new Error(`getupdates error: ret=${result.ret} ${result.errmsg || ''}`);
|
|
591
591
|
}
|
|
592
592
|
|
|
593
593
|
// 保存续传 buf
|
|
@@ -601,7 +601,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
601
601
|
try {
|
|
602
602
|
await this._handleMessage(msg);
|
|
603
603
|
} catch (e: any) {
|
|
604
|
-
console.error(`[WeChat]
|
|
604
|
+
console.error(`[WeChat] Message processing error: ${e.message}`);
|
|
605
605
|
}
|
|
606
606
|
}
|
|
607
607
|
}
|
|
@@ -638,7 +638,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
638
638
|
break;
|
|
639
639
|
|
|
640
640
|
case MessageItemType.IMAGE:
|
|
641
|
-
text += text ? ' [
|
|
641
|
+
text += text ? ' [Image]' : '[Image]';
|
|
642
642
|
if (item.image_item?.media) {
|
|
643
643
|
const localPath = await this._downloadMedia(item.image_item.media, item.image_item.aeskey, 'image.png');
|
|
644
644
|
if (localPath) {
|
|
@@ -648,7 +648,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
648
648
|
break;
|
|
649
649
|
|
|
650
650
|
case MessageItemType.VOICE:
|
|
651
|
-
text += text ? ' [
|
|
651
|
+
text += text ? ' [Voice]' : '[Voice]';
|
|
652
652
|
if (item.voice_item?.media) {
|
|
653
653
|
const localPath = await this._downloadMedia(item.voice_item.media, item.voice_item.aeskey, 'voice.silk');
|
|
654
654
|
if (localPath) {
|
|
@@ -658,7 +658,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
658
658
|
break;
|
|
659
659
|
|
|
660
660
|
case MessageItemType.FILE:
|
|
661
|
-
text += text ? ' [
|
|
661
|
+
text += text ? ' [File]' : '[File]';
|
|
662
662
|
if (item.file_item?.media) {
|
|
663
663
|
const localPath = await this._downloadMedia(item.file_item.media, item.file_item.aeskey, 'file');
|
|
664
664
|
if (localPath) {
|
|
@@ -668,7 +668,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
668
668
|
break;
|
|
669
669
|
|
|
670
670
|
case MessageItemType.VIDEO:
|
|
671
|
-
text += text ? ' [
|
|
671
|
+
text += text ? ' [Video]' : '[Video]';
|
|
672
672
|
if (item.video_item?.media) {
|
|
673
673
|
const localPath = await this._downloadMedia(item.video_item.media, item.video_item.aeskey, 'video.mp4');
|
|
674
674
|
if (localPath) {
|
|
@@ -680,7 +680,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
680
680
|
}
|
|
681
681
|
|
|
682
682
|
const preview = text.length > 80 ? text.slice(0, 80) + '...' : text;
|
|
683
|
-
console.log(`[WeChat]
|
|
683
|
+
console.log(`[WeChat] DM ${userId.slice(0, 12)}...: ${preview}`);
|
|
684
684
|
|
|
685
685
|
// 保存 frame 用于被动回复
|
|
686
686
|
this.pendingFrames.set(chatId, msg);
|
|
@@ -699,7 +699,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
699
699
|
|
|
700
700
|
async reply(chatId: string, text: string, maxLen?: number): Promise<void> {
|
|
701
701
|
const max = maxLen || TEXT_MAX;
|
|
702
|
-
const safe = text.length > max ? text.slice(0, max) + '\n
|
|
702
|
+
const safe = text.length > max ? text.slice(0, max) + '\n…truncated' : text;
|
|
703
703
|
await this._sendMessage(chatId, [
|
|
704
704
|
{ type: MessageItemType.TEXT, text_item: { text: safe } },
|
|
705
705
|
]);
|
|
@@ -724,7 +724,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
724
724
|
// 发送 thinking 阶段结束信号
|
|
725
725
|
await this._sendStreamSignal(state.streamTicket, 'thinking', true);
|
|
726
726
|
} catch (e: any) {
|
|
727
|
-
console.error(`[WeChat]
|
|
727
|
+
console.error(`[WeChat] Stream init failed, falling back to normal reply: ${e.message}`);
|
|
728
728
|
await this.reply(chatId, content);
|
|
729
729
|
return;
|
|
730
730
|
}
|
|
@@ -785,7 +785,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
785
785
|
try {
|
|
786
786
|
await this._sendImageFromSource(chatId, b.url, b.title || 'image.png');
|
|
787
787
|
} catch (e: any) {
|
|
788
|
-
console.error(`[WeChat]
|
|
788
|
+
console.error(`[WeChat] Image send failed: ${e.message}`);
|
|
789
789
|
}
|
|
790
790
|
}
|
|
791
791
|
break;
|
|
@@ -794,7 +794,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
794
794
|
try {
|
|
795
795
|
await this._sendFileFromSource(chatId, b.url, b.title || b.filename || 'file');
|
|
796
796
|
} catch (e: any) {
|
|
797
|
-
console.error(`[WeChat]
|
|
797
|
+
console.error(`[WeChat] File send failed: ${e.message}`);
|
|
798
798
|
}
|
|
799
799
|
}
|
|
800
800
|
break;
|
|
@@ -807,7 +807,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
807
807
|
try {
|
|
808
808
|
await this._sendImageFromSource(chatId, imageKey, this._basename(imageKey));
|
|
809
809
|
} catch (e: any) {
|
|
810
|
-
console.error(`[WeChat]
|
|
810
|
+
console.error(`[WeChat] Image send failed: ${e.message}`);
|
|
811
811
|
}
|
|
812
812
|
}
|
|
813
813
|
|
|
@@ -815,7 +815,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
815
815
|
try {
|
|
816
816
|
await this._sendFileFromSource(chatId, fileKey, fileName);
|
|
817
817
|
} catch (e: any) {
|
|
818
|
-
console.error(`[WeChat]
|
|
818
|
+
console.error(`[WeChat] File send failed: ${e.message}`);
|
|
819
819
|
}
|
|
820
820
|
}
|
|
821
821
|
|
|
@@ -839,18 +839,18 @@ export class WeChatIMModule implements IMModule {
|
|
|
839
839
|
try {
|
|
840
840
|
await ilinkPost('ilink/bot/sendmessage', body, this.botToken);
|
|
841
841
|
} catch (e: any) {
|
|
842
|
-
console.error(`[WeChat]
|
|
842
|
+
console.error(`[WeChat] Send failed: ${e.message}`);
|
|
843
843
|
}
|
|
844
844
|
}
|
|
845
845
|
|
|
846
|
-
// ──
|
|
846
|
+
// ── Streaming ──
|
|
847
847
|
|
|
848
848
|
private async _initStream(): Promise<string> {
|
|
849
849
|
const result = await ilinkPost('ilink/bot/init_stream', {
|
|
850
850
|
base_info: { channel_version: CHANNEL_VERSION, bot_agent: 'IMtoAgent' },
|
|
851
851
|
}, this.botToken);
|
|
852
852
|
if (result.ret !== 0 || !result.stream_ticket) {
|
|
853
|
-
throw new Error(`initStream
|
|
853
|
+
throw new Error(`initStream failed: ${JSON.stringify(result).slice(0, 200)}`);
|
|
854
854
|
}
|
|
855
855
|
return result.stream_ticket;
|
|
856
856
|
}
|
|
@@ -886,7 +886,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
886
886
|
} else if (media.encrypt_query_param) {
|
|
887
887
|
downloadUrl = `${CDN_BASE}?${media.encrypt_query_param}`;
|
|
888
888
|
} else {
|
|
889
|
-
console.error('[WeChat]
|
|
889
|
+
console.error('[WeChat] Media download: no URL available');
|
|
890
890
|
return null;
|
|
891
891
|
}
|
|
892
892
|
|
|
@@ -916,10 +916,10 @@ export class WeChatIMModule implements IMModule {
|
|
|
916
916
|
fs.mkdirSync(MEDIA_DIR, { recursive: true });
|
|
917
917
|
const filePath = path.join(MEDIA_DIR, `${Date.now()}_${fallbackName}`);
|
|
918
918
|
fs.writeFileSync(filePath, decrypted);
|
|
919
|
-
console.log(`[WeChat]
|
|
919
|
+
console.log(`[WeChat] Media downloaded: ${filePath}`);
|
|
920
920
|
return filePath;
|
|
921
921
|
} catch (e: any) {
|
|
922
|
-
console.error(`[WeChat]
|
|
922
|
+
console.error(`[WeChat] Media download failed: ${e.message}`);
|
|
923
923
|
return null;
|
|
924
924
|
}
|
|
925
925
|
}
|
|
@@ -945,12 +945,12 @@ export class WeChatIMModule implements IMModule {
|
|
|
945
945
|
}, this.botToken);
|
|
946
946
|
|
|
947
947
|
if (uploadResult.ret !== 0) {
|
|
948
|
-
throw new Error(`getUploadUrl
|
|
948
|
+
throw new Error(`getUploadUrl failed: ${JSON.stringify(uploadResult).slice(0, 200)}`);
|
|
949
949
|
}
|
|
950
950
|
|
|
951
951
|
const uploadUrl = uploadResult.upload_full_url || uploadResult.upload_url;
|
|
952
952
|
if (!uploadUrl) {
|
|
953
|
-
throw new Error('
|
|
953
|
+
throw new Error('Failed to get upload URL');
|
|
954
954
|
}
|
|
955
955
|
|
|
956
956
|
// 3. 上传加密文件到 CDN
|
|
@@ -960,7 +960,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
960
960
|
const encryptQuery = uploadResult.encrypt_query_param || uploadResult.encrypt_query;
|
|
961
961
|
return { encryptQuery, aesKey, fileKey };
|
|
962
962
|
} catch (e: any) {
|
|
963
|
-
console.error(`[WeChat]
|
|
963
|
+
console.error(`[WeChat] Media upload failed: ${e.message}`);
|
|
964
964
|
return null;
|
|
965
965
|
}
|
|
966
966
|
}
|
|
@@ -984,12 +984,12 @@ export class WeChatIMModule implements IMModule {
|
|
|
984
984
|
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
985
985
|
resolve();
|
|
986
986
|
} else {
|
|
987
|
-
reject(new Error(`CDN
|
|
987
|
+
reject(new Error(`CDN upload failed: HTTP ${res.statusCode} ${data.slice(0, 100)}`));
|
|
988
988
|
}
|
|
989
989
|
});
|
|
990
990
|
});
|
|
991
991
|
req.on('error', reject);
|
|
992
|
-
req.on('timeout', () => { req.destroy(); reject(new Error('CDN
|
|
992
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('CDN upload timed out')); });
|
|
993
993
|
req.write(buffer);
|
|
994
994
|
req.end();
|
|
995
995
|
});
|
|
@@ -1058,7 +1058,7 @@ export class WeChatIMModule implements IMModule {
|
|
|
1058
1058
|
return fs.readFileSync(source);
|
|
1059
1059
|
}
|
|
1060
1060
|
|
|
1061
|
-
console.error(`[WeChat]
|
|
1061
|
+
console.error(`[WeChat] File not found: ${source}`);
|
|
1062
1062
|
return null;
|
|
1063
1063
|
}
|
|
1064
1064
|
|