palz-connector 1.4.7 → 1.4.8
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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/bot.ts +4 -1
- package/src/monitor.ts +69 -57
- package/src/types.ts +2 -0
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/src/bot.ts
CHANGED
|
@@ -558,6 +558,9 @@ async function _dispatchPalzMessageInner(params: HandlePalzMessageParams): Promi
|
|
|
558
558
|
if (groupId) {
|
|
559
559
|
untrustedContext.push(`group_id: ${groupId}`);
|
|
560
560
|
}
|
|
561
|
+
if (msg.group_name) {
|
|
562
|
+
untrustedContext.push(`group_name: ${msg.group_name}`);
|
|
563
|
+
}
|
|
561
564
|
if (msg.group_owner_id) {
|
|
562
565
|
untrustedContext.push(`group_owner_id: ${msg.group_owner_id}`);
|
|
563
566
|
}
|
|
@@ -584,7 +587,7 @@ async function _dispatchPalzMessageInner(params: HandlePalzMessageParams): Promi
|
|
|
584
587
|
SessionKey: route.sessionKey,
|
|
585
588
|
AccountId: route.accountId,
|
|
586
589
|
ChatType: chatType,
|
|
587
|
-
GroupSubject: isGroup ? msg.conversation_id : undefined,
|
|
590
|
+
GroupSubject: isGroup ? (msg.group_name || msg.conversation_id) : undefined,
|
|
588
591
|
SenderId: msg.sender_id,
|
|
589
592
|
SenderName: senderName,
|
|
590
593
|
UntrustedContext: untrustedContext,
|
package/src/monitor.ts
CHANGED
|
@@ -40,6 +40,7 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
40
40
|
let currentWs: WebSocket | null = null;
|
|
41
41
|
let consecutive4002 = 0;
|
|
42
42
|
const MAX_CONSECUTIVE_4002 = 10;
|
|
43
|
+
const MAX_RECONNECT_DELAY_MS = 16_000;
|
|
43
44
|
|
|
44
45
|
const cleanup = () => {
|
|
45
46
|
closed = true;
|
|
@@ -72,15 +73,28 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
72
73
|
}
|
|
73
74
|
abortSignal?.addEventListener("abort", handleAbort, { once: true });
|
|
74
75
|
|
|
75
|
-
function scheduleReconnect() {
|
|
76
|
+
function scheduleReconnect(delay = reconnectDelay, advanceBackoff = true) {
|
|
76
77
|
if (closed) return;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
if (reconnectTimer) {
|
|
79
|
+
clearTimeout(reconnectTimer);
|
|
80
|
+
reconnectTimer = null;
|
|
81
|
+
}
|
|
82
|
+
log(`palz[${accountId}]: scheduling reconnect in ${delay}ms`);
|
|
83
|
+
reconnectTimer = setTimeout(() => {
|
|
84
|
+
reconnectTimer = null;
|
|
85
|
+
connect();
|
|
86
|
+
}, delay);
|
|
87
|
+
if (advanceBackoff) {
|
|
88
|
+
reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY_MS);
|
|
89
|
+
}
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
function connect() {
|
|
83
93
|
if (closed) return;
|
|
94
|
+
if (reconnectTimer) {
|
|
95
|
+
clearTimeout(reconnectTimer);
|
|
96
|
+
reconnectTimer = null;
|
|
97
|
+
}
|
|
84
98
|
|
|
85
99
|
let ws: WebSocket;
|
|
86
100
|
try {
|
|
@@ -94,7 +108,55 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
94
108
|
let connectedAt = 0;
|
|
95
109
|
let pingInterval: ReturnType<typeof setInterval> | null = null;
|
|
96
110
|
let messageCount = 0;
|
|
97
|
-
let
|
|
111
|
+
let ended = false;
|
|
112
|
+
|
|
113
|
+
const handleSocketEnd = (code: number, reasonStr: string) => {
|
|
114
|
+
if (ended) return;
|
|
115
|
+
ended = true;
|
|
116
|
+
if (pingInterval) {
|
|
117
|
+
clearInterval(pingInterval);
|
|
118
|
+
pingInterval = null;
|
|
119
|
+
}
|
|
120
|
+
if (closed) return;
|
|
121
|
+
|
|
122
|
+
const wasConnected = connectedAt > 0;
|
|
123
|
+
const stableMs = wasConnected ? Date.now() - connectedAt : 0;
|
|
124
|
+
|
|
125
|
+
// 4002: 被新连接替代,带退避重试
|
|
126
|
+
if (code === 4002) {
|
|
127
|
+
consecutive4002++;
|
|
128
|
+
if (consecutive4002 >= MAX_CONSECUTIVE_4002) {
|
|
129
|
+
log(
|
|
130
|
+
`palz[${accountId}]: replaced ${consecutive4002} times (code=4002), giving up`,
|
|
131
|
+
);
|
|
132
|
+
cleanup();
|
|
133
|
+
resolve();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const jitter = Math.floor(Math.random() * 2000);
|
|
137
|
+
const delay = 3000 * consecutive4002 + jitter;
|
|
138
|
+
log(
|
|
139
|
+
`palz[${accountId}]: replaced (code=4002, attempt=${consecutive4002}), retry in ${delay}ms`,
|
|
140
|
+
);
|
|
141
|
+
scheduleReconnect(delay, false);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// 4001: bot_id 缺失,不重连
|
|
146
|
+
if (code === 4001) {
|
|
147
|
+
error(`palz[${accountId}]: bot_id missing (code=4001), not reconnecting`);
|
|
148
|
+
cleanup();
|
|
149
|
+
resolve();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 其他断开:指数退避重连
|
|
154
|
+
if (wasConnected && stableMs > 10_000) reconnectDelay = 1000;
|
|
155
|
+
log(
|
|
156
|
+
`palz[${accountId}]: disconnected (code=${code}, reason=${reasonStr}, uptime=${Math.round(stableMs / 1000)}s, msgs=${messageCount}), reconnecting in ${reconnectDelay}ms`,
|
|
157
|
+
);
|
|
158
|
+
scheduleReconnect();
|
|
159
|
+
};
|
|
98
160
|
|
|
99
161
|
ws.on("open", () => {
|
|
100
162
|
connectedAt = Date.now();
|
|
@@ -145,62 +207,12 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
145
207
|
});
|
|
146
208
|
|
|
147
209
|
ws.on("close", (code: number, reason: Buffer) => {
|
|
148
|
-
|
|
149
|
-
if (pingInterval) {
|
|
150
|
-
clearInterval(pingInterval);
|
|
151
|
-
pingInterval = null;
|
|
152
|
-
}
|
|
153
|
-
if (closed) return;
|
|
154
|
-
|
|
155
|
-
const stableMs = Date.now() - connectedAt;
|
|
156
|
-
const reasonStr = reason?.toString() || "";
|
|
157
|
-
|
|
158
|
-
// 4002: 被新连接替代,带退避重试
|
|
159
|
-
if (code === 4002) {
|
|
160
|
-
consecutive4002++;
|
|
161
|
-
if (consecutive4002 >= MAX_CONSECUTIVE_4002) {
|
|
162
|
-
log(
|
|
163
|
-
`palz[${accountId}]: replaced ${consecutive4002} times (code=4002), giving up`,
|
|
164
|
-
);
|
|
165
|
-
cleanup();
|
|
166
|
-
resolve();
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const jitter = Math.floor(Math.random() * 2000);
|
|
170
|
-
const delay = 3000 * consecutive4002 + jitter;
|
|
171
|
-
log(
|
|
172
|
-
`palz[${accountId}]: replaced (code=4002, attempt=${consecutive4002}), retry in ${delay}ms`,
|
|
173
|
-
);
|
|
174
|
-
reconnectTimer = setTimeout(connect, delay);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// 4001: bot_id 缺失,不重连
|
|
179
|
-
if (code === 4001) {
|
|
180
|
-
error(`palz[${accountId}]: bot_id missing (code=4001), not reconnecting`);
|
|
181
|
-
cleanup();
|
|
182
|
-
resolve();
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// 其他断开:指数退避重连
|
|
187
|
-
if (stableMs > 10_000) reconnectDelay = 1000;
|
|
188
|
-
log(
|
|
189
|
-
`palz[${accountId}]: disconnected (code=${code}, reason=${reasonStr}, uptime=${Math.round(stableMs / 1000)}s, msgs=${messageCount}), reconnecting in ${reconnectDelay}ms`,
|
|
190
|
-
);
|
|
191
|
-
scheduleReconnect();
|
|
210
|
+
handleSocketEnd(code, reason?.toString() || "");
|
|
192
211
|
});
|
|
193
212
|
|
|
194
213
|
ws.on("error", (err) => {
|
|
195
214
|
error(`palz[${accountId}]: WebSocket error: ${err.message}`);
|
|
196
|
-
|
|
197
|
-
closeFired = true;
|
|
198
|
-
if (pingInterval) {
|
|
199
|
-
clearInterval(pingInterval);
|
|
200
|
-
pingInterval = null;
|
|
201
|
-
}
|
|
202
|
-
scheduleReconnect();
|
|
203
|
-
}
|
|
215
|
+
handleSocketEnd(1006, err.message);
|
|
204
216
|
});
|
|
205
217
|
}
|
|
206
218
|
|
package/src/types.ts
CHANGED
|
@@ -39,6 +39,8 @@ export interface PalzMessageEvent {
|
|
|
39
39
|
group_id?: string;
|
|
40
40
|
/** 群主用户 ID,群聊时由 IM 下发 */
|
|
41
41
|
group_owner_id?: string;
|
|
42
|
+
/** 群聊名称,群聊时由 IM 下发 */
|
|
43
|
+
group_name?: string;
|
|
42
44
|
/** Lobster ID,标识 agent 身份(IM 通过此字段区分不同 agent) */
|
|
43
45
|
lobster_id?: string;
|
|
44
46
|
/** 群组类型,由 IM 下发 */
|