@wu529778790/open-im 1.9.1 → 1.9.3-beta.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.
- package/dist/dingtalk/message-sender.js +1 -1
- package/dist/index.js +7 -0
- package/dist/qq/message-sender.js +1 -1
- package/dist/shared/chat-user-map.js +1 -1
- package/dist/telegram/message-sender.js +1 -1
- package/dist/wework/message-sender.js +1 -1
- package/dist/workbuddy/centrifuge-client.js +18 -6
- package/dist/workbuddy/oauth.js +12 -6
- package/package.json +2 -4
package/dist/index.js
CHANGED
|
@@ -289,6 +289,13 @@ export async function main() {
|
|
|
289
289
|
log.error("Unhandled Promise rejection:", reason);
|
|
290
290
|
});
|
|
291
291
|
process.on("uncaughtException", (err) => {
|
|
292
|
+
const msg = err?.message ?? String(err);
|
|
293
|
+
// WebSocket "not open" errors are transient — the connection will auto-reconnect.
|
|
294
|
+
// Exiting would take down all platforms, so just log and continue.
|
|
295
|
+
if (msg.includes("WebSocket is not open") || msg.includes("readyState")) {
|
|
296
|
+
log.warn("Transient WebSocket error (ignored, will reconnect):", err);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
292
299
|
log.error("Uncaught exception (process will exit):", err);
|
|
293
300
|
closeLogger();
|
|
294
301
|
process.exit(1);
|
|
@@ -17,7 +17,7 @@ setInterval(() => {
|
|
|
17
17
|
pendingReplies.delete(id);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
}, PENDING_MAX_AGE_MS);
|
|
20
|
+
}, PENDING_MAX_AGE_MS).unref();
|
|
21
21
|
function parseChatTarget(chatId) {
|
|
22
22
|
if (chatId.startsWith("group:")) {
|
|
23
23
|
return { kind: "group", id: chatId.slice("group:".length) };
|
|
@@ -14,7 +14,7 @@ setInterval(() => {
|
|
|
14
14
|
chatToPlatform.delete(key);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
}, 60 * 60 * 1000); // Check every hour
|
|
17
|
+
}, 60 * 60 * 1000).unref(); // Check every hour
|
|
18
18
|
export function setChatUser(chatId, userId, platform) {
|
|
19
19
|
chatToUser.set(chatId, userId);
|
|
20
20
|
if (platform)
|
|
@@ -112,7 +112,7 @@ setInterval(() => {
|
|
|
112
112
|
log.info(`Cleaned up expired stream state: ${id}`);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
}, STREAM_CLEANUP_INTERVAL_MS);
|
|
115
|
+
}, STREAM_CLEANUP_INTERVAL_MS).unref();
|
|
116
116
|
function sleep(ms) {
|
|
117
117
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
118
118
|
}
|
|
@@ -259,17 +259,29 @@ export class WorkBuddyCentrifugeClient {
|
|
|
259
259
|
payload,
|
|
260
260
|
};
|
|
261
261
|
try {
|
|
262
|
+
// Guard against the race where WebSocket transitions to CONNECTING between
|
|
263
|
+
// the state check above and the actual publish call.
|
|
262
264
|
this.client.publish(this.config.channel, envelope).catch((err) => {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
266
|
+
if (msg.includes('WebSocket is not open') || msg.includes('readyState')) {
|
|
267
|
+
log.warn(`${this.logPrefix} WebSocket not ready for send (will reconnect): ${msg}`);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
log.error(`${this.logPrefix} Message send failed:`, err);
|
|
271
|
+
this.callbacks.onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
272
|
+
}
|
|
265
273
|
});
|
|
266
|
-
const json = JSON.stringify(envelope);
|
|
267
|
-
const preview = json.length > 500 ? json.substring(0, 500) + `...(truncated)` : json;
|
|
268
274
|
log.debug(`${this.logPrefix} Sent message: method=${method}, msg_id=${envelope.msg_id}`);
|
|
269
275
|
}
|
|
270
276
|
catch (error) {
|
|
271
|
-
|
|
272
|
-
|
|
277
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
278
|
+
if (msg.includes('WebSocket is not open') || msg.includes('readyState')) {
|
|
279
|
+
log.warn(`${this.logPrefix} WebSocket not ready for send (will reconnect): ${msg}`);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
log.error(`${this.logPrefix} Message send failed:`, error);
|
|
283
|
+
this.callbacks.onError?.(error instanceof Error ? error : new Error(`Message send failed: ${msg}`));
|
|
284
|
+
}
|
|
273
285
|
}
|
|
274
286
|
}
|
|
275
287
|
/**
|
package/dist/workbuddy/oauth.js
CHANGED
|
@@ -91,10 +91,12 @@ export class WorkBuddyOAuth {
|
|
|
91
91
|
}
|
|
92
92
|
catch (e) {
|
|
93
93
|
// code 11217 = still waiting, continue polling
|
|
94
|
-
|
|
94
|
+
const msg = e instanceof Error ? e.message : '';
|
|
95
|
+
const code = e?.code;
|
|
96
|
+
if (msg.includes('11217'))
|
|
95
97
|
continue;
|
|
96
98
|
// network errors: retry
|
|
97
|
-
if (
|
|
99
|
+
if (code === 'UND_ERR_CONNECT_TIMEOUT' || code === 'ECONNREFUSED')
|
|
98
100
|
continue;
|
|
99
101
|
throw e;
|
|
100
102
|
}
|
|
@@ -133,7 +135,8 @@ export class WorkBuddyOAuth {
|
|
|
133
135
|
return data.data;
|
|
134
136
|
}
|
|
135
137
|
catch (e) {
|
|
136
|
-
|
|
138
|
+
const msg = e instanceof Error ? e.message : '';
|
|
139
|
+
if (msg.includes('12151'))
|
|
137
140
|
continue;
|
|
138
141
|
throw e;
|
|
139
142
|
}
|
|
@@ -194,7 +197,8 @@ export class WorkBuddyOAuth {
|
|
|
194
197
|
const body = await res.text().catch(() => '');
|
|
195
198
|
return { success: false, message: `获取链接失败: ${res.status} ${body}` };
|
|
196
199
|
}
|
|
197
|
-
|
|
200
|
+
const body = (await res.json());
|
|
201
|
+
return body.data ?? { success: false, message: 'Empty response' };
|
|
198
202
|
}
|
|
199
203
|
/**
|
|
200
204
|
* Check WeChat KF binding status
|
|
@@ -209,7 +213,8 @@ export class WorkBuddyOAuth {
|
|
|
209
213
|
if (!res.ok) {
|
|
210
214
|
return { success: false, bound: false, message: `查询状态失败: ${res.status}` };
|
|
211
215
|
}
|
|
212
|
-
|
|
216
|
+
const body = (await res.json());
|
|
217
|
+
return body.data ?? { success: false, bound: false, message: 'Empty response' };
|
|
213
218
|
}
|
|
214
219
|
/**
|
|
215
220
|
* Poll binding status until bound
|
|
@@ -266,7 +271,8 @@ export class WorkBuddyOAuth {
|
|
|
266
271
|
const body = await res.text().catch(() => '');
|
|
267
272
|
throw new Error(`registerChannel failed: ${res.status} ${body}`);
|
|
268
273
|
}
|
|
269
|
-
|
|
274
|
+
const body = (await res.json());
|
|
275
|
+
return body.data ?? {};
|
|
270
276
|
}
|
|
271
277
|
/**
|
|
272
278
|
* Send response to WeChat KF
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wu529778790/open-im",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.3-beta.0",
|
|
4
4
|
"description": "Multi-platform IM bridge for AI CLI tools (Claude, Codex, CodeBuddy)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
"dingtalk",
|
|
30
30
|
"telegram",
|
|
31
31
|
"feishu",
|
|
32
|
-
"
|
|
33
|
-
"weixin",
|
|
32
|
+
"workbuddy",
|
|
34
33
|
"claude",
|
|
35
34
|
"claude-code",
|
|
36
35
|
"bot",
|
|
@@ -48,7 +47,6 @@
|
|
|
48
47
|
"dependencies": {
|
|
49
48
|
"@anthropic-ai/claude-agent-sdk": "^0.2.86",
|
|
50
49
|
"@larksuiteoapi/node-sdk": "^1.59.0",
|
|
51
|
-
"@wu529778790/open-im": "^1.8.1-beta.8",
|
|
52
50
|
"centrifuge": "^5.3.0",
|
|
53
51
|
"dingtalk-stream": "^2.1.4",
|
|
54
52
|
"prompts": "^2.4.2",
|