@linxiraos/pi-channels 1.1.7 → 1.1.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/CHANGELOG.md +4 -0
- package/dist/types/index.d.ts +4 -4
- package/package.json +4 -4
- package/src/host.ts +4 -1
- package/src/index.ts +22 -4
- package/src/telegram.ts +17 -4
- package/src/types.ts +6 -1
- package/src/wechat.ts +29 -7
package/CHANGELOG.md
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -15,11 +15,11 @@ import { ChannelHost } from "./host.js";
|
|
|
15
15
|
import type { ChannelSession, ChannelsWebConfig } from "./types.js";
|
|
16
16
|
import { type WeChatQrStatus } from "./wechat.js";
|
|
17
17
|
export type { ChannelId, ChatChannel, ChatImage } from "./channel.js";
|
|
18
|
-
export { FeishuChannel, type FeishuChannelOptions, type FeishuInboundHandler } from "./feishu.js";
|
|
18
|
+
export { FeishuChannel, type FeishuChannelOptions, type FeishuInboundHandler, } from "./feishu.js";
|
|
19
19
|
export { ChannelHost } from "./host.js";
|
|
20
|
-
export { TelegramChannel, type TelegramChannelOptions, type TelegramInboundHandler } from "./telegram.js";
|
|
21
|
-
export type { ChannelSession, ChannelSessionEvent, ChannelsWebConfig, IrcMessage } from "./types.js";
|
|
22
|
-
export { WeChatChannel, type WeChatChannelOptions, type WeChatInboundHandler, type WeChatQrStatus } from "./wechat.js";
|
|
20
|
+
export { TelegramChannel, type TelegramChannelOptions, type TelegramInboundHandler, } from "./telegram.js";
|
|
21
|
+
export type { ChannelSession, ChannelSessionEvent, ChannelsWebConfig, IrcMessage, } from "./types.js";
|
|
22
|
+
export { WeChatChannel, type WeChatChannelOptions, type WeChatInboundHandler, type WeChatQrStatus, } from "./wechat.js";
|
|
23
23
|
/** One channel's runtime state, surfaced to the gateway (`/api/channels/status`). */
|
|
24
24
|
export interface ChannelStatus {
|
|
25
25
|
id: ChannelId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linxiraos/pi-channels",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "IM channel adapters for Zeta (WeChat / Feishu / Telegram)",
|
|
6
6
|
"homepage": "https://linxira-os.github.io/zeta/",
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"test": "bun test --parallel"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@linxiraos/pi-utils": "1.1.
|
|
35
|
+
"@linxiraos/pi-utils": "1.1.8",
|
|
36
36
|
"@larksuiteoapi/node-sdk": "^1.71.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@linxiraos/pi-ai": "1.1.
|
|
39
|
+
"@linxiraos/pi-ai": "1.1.8",
|
|
40
40
|
"@types/bun": "^1.3.14"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@linxiraos/pi-ai": "1.1.
|
|
43
|
+
"@linxiraos/pi-ai": "1.1.8"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"bun": ">=1.3.14"
|
package/src/host.ts
CHANGED
|
@@ -87,7 +87,10 @@ export class ChannelHost {
|
|
|
87
87
|
// Optional allowlist: when configured, only listed peers may reach the
|
|
88
88
|
// agent (empty allowlist = everyone, unchanged behavior).
|
|
89
89
|
if (this.#allowedPeers.length > 0 && !this.#allowedPeers.includes(peer)) {
|
|
90
|
-
logger.debug("Channel message from non-allowed peer dropped", {
|
|
90
|
+
logger.debug("Channel message from non-allowed peer dropped", {
|
|
91
|
+
channel: channelId,
|
|
92
|
+
peer,
|
|
93
|
+
});
|
|
91
94
|
return;
|
|
92
95
|
}
|
|
93
96
|
const agentId = this.#session.getAgentId();
|
package/src/index.ts
CHANGED
|
@@ -20,11 +20,29 @@ import type { ChannelSession, ChannelsWebConfig } from "./types";
|
|
|
20
20
|
import { WeChatChannel, type WeChatQrStatus } from "./wechat";
|
|
21
21
|
|
|
22
22
|
export type { ChannelId, ChatChannel, ChatImage } from "./channel";
|
|
23
|
-
export {
|
|
23
|
+
export {
|
|
24
|
+
FeishuChannel,
|
|
25
|
+
type FeishuChannelOptions,
|
|
26
|
+
type FeishuInboundHandler,
|
|
27
|
+
} from "./feishu";
|
|
24
28
|
export { ChannelHost } from "./host";
|
|
25
|
-
export {
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
export {
|
|
30
|
+
TelegramChannel,
|
|
31
|
+
type TelegramChannelOptions,
|
|
32
|
+
type TelegramInboundHandler,
|
|
33
|
+
} from "./telegram";
|
|
34
|
+
export type {
|
|
35
|
+
ChannelSession,
|
|
36
|
+
ChannelSessionEvent,
|
|
37
|
+
ChannelsWebConfig,
|
|
38
|
+
IrcMessage,
|
|
39
|
+
} from "./types";
|
|
40
|
+
export {
|
|
41
|
+
WeChatChannel,
|
|
42
|
+
type WeChatChannelOptions,
|
|
43
|
+
type WeChatInboundHandler,
|
|
44
|
+
type WeChatQrStatus,
|
|
45
|
+
} from "./wechat";
|
|
28
46
|
|
|
29
47
|
/**
|
|
30
48
|
* Module-level QR-login state bridge between the running channel and the web
|
package/src/telegram.ts
CHANGED
|
@@ -66,7 +66,10 @@ export class TelegramChannel implements ChatChannel {
|
|
|
66
66
|
try {
|
|
67
67
|
const url = `${this.#apiUrl("getUpdates")}?timeout=${POLL_TIMEOUT_SECONDS}&offset=${this.#offset + 1}`;
|
|
68
68
|
const res = await this.#fetch(url, {
|
|
69
|
-
signal: AbortSignal.any([
|
|
69
|
+
signal: AbortSignal.any([
|
|
70
|
+
this.#abort?.signal ?? AbortSignal.abort(),
|
|
71
|
+
AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
72
|
+
]),
|
|
70
73
|
});
|
|
71
74
|
if (res.status === 401) {
|
|
72
75
|
logger.error("Telegram bot token rejected (HTTP 401); polling stopped");
|
|
@@ -81,7 +84,11 @@ export class TelegramChannel implements ChatChannel {
|
|
|
81
84
|
ok?: boolean;
|
|
82
85
|
result?: Array<{
|
|
83
86
|
update_id?: number;
|
|
84
|
-
message?: {
|
|
87
|
+
message?: {
|
|
88
|
+
message_id?: number;
|
|
89
|
+
chat?: { id?: number };
|
|
90
|
+
text?: string;
|
|
91
|
+
};
|
|
85
92
|
}>;
|
|
86
93
|
};
|
|
87
94
|
for (const update of data.result ?? []) {
|
|
@@ -92,7 +99,10 @@ export class TelegramChannel implements ChatChannel {
|
|
|
92
99
|
const text = update.message?.text;
|
|
93
100
|
if (chatId === undefined || typeof text !== "string" || text === "") continue;
|
|
94
101
|
if (text.startsWith("/")) continue;
|
|
95
|
-
logger.debug("Telegram message received", {
|
|
102
|
+
logger.debug("Telegram message received", {
|
|
103
|
+
chatId,
|
|
104
|
+
length: text.length,
|
|
105
|
+
});
|
|
96
106
|
this.#onMessage(String(chatId), text, String(update.message?.message_id ?? ""));
|
|
97
107
|
}
|
|
98
108
|
} catch (error) {
|
|
@@ -122,7 +132,10 @@ export class TelegramChannel implements ChatChannel {
|
|
|
122
132
|
form.append("chat_id", to);
|
|
123
133
|
form.append("photo", new Blob([image.data], { type: image.mime }), "plan.png");
|
|
124
134
|
if (caption && caption !== "") form.append("caption", caption);
|
|
125
|
-
const res = await this.#fetch(this.#apiUrl("sendPhoto"), {
|
|
135
|
+
const res = await this.#fetch(this.#apiUrl("sendPhoto"), {
|
|
136
|
+
method: "POST",
|
|
137
|
+
body: form,
|
|
138
|
+
});
|
|
126
139
|
if (!res.ok) {
|
|
127
140
|
throw new Error(`Telegram sendPhoto failed (HTTP ${res.status}): ${await res.text()}`);
|
|
128
141
|
}
|
package/src/types.ts
CHANGED
|
@@ -61,7 +61,12 @@ export interface ChannelsWebConfig {
|
|
|
61
61
|
endpoint?: string;
|
|
62
62
|
peerTokens?: Record<string, string>;
|
|
63
63
|
};
|
|
64
|
-
feishu: {
|
|
64
|
+
feishu: {
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
appId?: string;
|
|
67
|
+
appSecret?: string;
|
|
68
|
+
domain?: "feishu" | "lark";
|
|
69
|
+
};
|
|
65
70
|
telegram: { enabled: boolean; botToken?: string };
|
|
66
71
|
allowedPeers?: string[];
|
|
67
72
|
};
|
package/src/wechat.ts
CHANGED
|
@@ -167,7 +167,10 @@ export class WeChatChannel implements ChatChannel {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
#baseInfo(): Record<string, string> {
|
|
170
|
-
return {
|
|
170
|
+
return {
|
|
171
|
+
channel_version: CHANNEL_VERSION,
|
|
172
|
+
bot_agent: "zeta-WeChat-ClawBot/1.0.0",
|
|
173
|
+
};
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
async #apiGet(path: string): Promise<Record<string, unknown>> {
|
|
@@ -236,7 +239,9 @@ export class WeChatChannel implements ChatChannel {
|
|
|
236
239
|
|
|
237
240
|
while (this.#started && !this.#abort?.signal.aborted) {
|
|
238
241
|
try {
|
|
239
|
-
const result = await this.#apiPost("api/v1/wechat/qrcode/status", {
|
|
242
|
+
const result = await this.#apiPost("api/v1/wechat/qrcode/status", {
|
|
243
|
+
qrcode: token,
|
|
244
|
+
});
|
|
240
245
|
const body = (result.data as Record<string, unknown> | undefined) ?? result;
|
|
241
246
|
const status = typeof body.status === "string" ? body.status : "";
|
|
242
247
|
if (status === "confirmed") {
|
|
@@ -274,13 +279,23 @@ export class WeChatChannel implements ChatChannel {
|
|
|
274
279
|
await config.set("channels.wechat.ilinkUserId", ilinkUserId);
|
|
275
280
|
}
|
|
276
281
|
}
|
|
277
|
-
this.#options.onQrCode?.({
|
|
278
|
-
|
|
282
|
+
this.#options.onQrCode?.({
|
|
283
|
+
qrcode: token,
|
|
284
|
+
qrcodeUrl,
|
|
285
|
+
status: "confirmed",
|
|
286
|
+
});
|
|
287
|
+
logger.info("WeChat channel logged in (v1 API)", {
|
|
288
|
+
baseUrl: this.#baseUrl,
|
|
289
|
+
});
|
|
279
290
|
return;
|
|
280
291
|
}
|
|
281
292
|
if (status === "expired") {
|
|
282
293
|
logger.warn("WeChat QR code expired; fetching a fresh one");
|
|
283
|
-
this.#options.onQrCode?.({
|
|
294
|
+
this.#options.onQrCode?.({
|
|
295
|
+
qrcode: token,
|
|
296
|
+
qrcodeUrl,
|
|
297
|
+
status: "expired",
|
|
298
|
+
});
|
|
284
299
|
return await this.#loginFlowV1();
|
|
285
300
|
}
|
|
286
301
|
this.#options.onQrCode?.({
|
|
@@ -405,7 +420,10 @@ export class WeChatChannel implements ChatChannel {
|
|
|
405
420
|
}
|
|
406
421
|
const textItem = (msg.item_list ?? []).find(item => item.type === 1)?.text_item?.text;
|
|
407
422
|
if (typeof textItem !== "string" || textItem === "") continue;
|
|
408
|
-
logger.debug("WeChat message received", {
|
|
423
|
+
logger.debug("WeChat message received", {
|
|
424
|
+
from,
|
|
425
|
+
length: textItem.length,
|
|
426
|
+
});
|
|
409
427
|
this.#onMessage(from, textItem, String(msg.to_user_id ?? ""));
|
|
410
428
|
}
|
|
411
429
|
} catch (error) {
|
|
@@ -534,7 +552,11 @@ export class WeChatChannel implements ChatChannel {
|
|
|
534
552
|
}
|
|
535
553
|
|
|
536
554
|
// 2. PUT the encrypted payload to the CDN.
|
|
537
|
-
const putRes = await this.#fetch(uploadUrl, {
|
|
555
|
+
const putRes = await this.#fetch(uploadUrl, {
|
|
556
|
+
method: "PUT",
|
|
557
|
+
body: encrypted,
|
|
558
|
+
signal: this.#abort?.signal,
|
|
559
|
+
});
|
|
538
560
|
if (!putRes.ok) {
|
|
539
561
|
throw new Error(`WeChat CDN upload failed (HTTP ${putRes.status})`);
|
|
540
562
|
}
|