@jingyi0605/codingns 0.7.3 → 0.7.4
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.
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export type WechatClawLoginStatus = "not_logged_in" | "waiting_scan" | "scan_confirmed" | "active" | "expired";
|
|
2
|
+
export interface WechatClawStartLoginResult {
|
|
3
|
+
sessionKey: string;
|
|
4
|
+
qrcode: string;
|
|
5
|
+
qrcodeUrl: string | null;
|
|
6
|
+
status: WechatClawLoginStatus;
|
|
7
|
+
}
|
|
8
|
+
export interface WechatClawPollLoginResult {
|
|
9
|
+
status: WechatClawLoginStatus;
|
|
10
|
+
botToken: string | null;
|
|
11
|
+
baseUrl: string | null;
|
|
12
|
+
remoteBotId: string | null;
|
|
13
|
+
boundUserId: string | null;
|
|
14
|
+
redirectHost: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface WechatClawPollMessagesResult {
|
|
17
|
+
nextCursor: string | null;
|
|
18
|
+
longPollingTimeoutMs: number | null;
|
|
19
|
+
messages: WechatClawInboundMessage[];
|
|
20
|
+
}
|
|
21
|
+
export interface WechatClawInboundMessage {
|
|
22
|
+
messageId: string;
|
|
23
|
+
fromUserId: string | null;
|
|
24
|
+
toUserId: string | null;
|
|
25
|
+
text: string | null;
|
|
26
|
+
timestamp: string | null;
|
|
27
|
+
contextToken: string | null;
|
|
28
|
+
rawPayload: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
export interface WechatClawSendTextResult {
|
|
31
|
+
messageRef: string | null;
|
|
32
|
+
}
|
|
33
|
+
export declare function startWechatClawLogin(): Promise<WechatClawStartLoginResult>;
|
|
34
|
+
export declare function pollWechatClawLoginStatus(options: {
|
|
35
|
+
qrcode: string;
|
|
36
|
+
authBaseUrl?: string | null;
|
|
37
|
+
}): Promise<WechatClawPollLoginResult>;
|
|
38
|
+
export declare function pollWechatClawMessages(options: {
|
|
39
|
+
baseUrl?: string | null;
|
|
40
|
+
botToken: string;
|
|
41
|
+
cursor?: string | null;
|
|
42
|
+
timeoutMs?: number;
|
|
43
|
+
}): Promise<WechatClawPollMessagesResult>;
|
|
44
|
+
export declare function sendWechatClawText(options: {
|
|
45
|
+
baseUrl?: string | null;
|
|
46
|
+
botToken: string;
|
|
47
|
+
toUserId: string;
|
|
48
|
+
contextToken: string;
|
|
49
|
+
text: string;
|
|
50
|
+
}): Promise<WechatClawSendTextResult>;
|
|
51
|
+
export declare function normalizeWechatClawBaseUrl(value?: string | null): string;
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { randomInt } from "node:crypto";
|
|
2
|
+
import { AppError } from "../../shared/errors/app-error.js";
|
|
3
|
+
const WECHAT_CLAW_FIXED_BASE_URL = "https://ilinkai.weixin.qq.com";
|
|
4
|
+
const WECHAT_CLAW_BOT_TYPE = "3";
|
|
5
|
+
const WECHAT_CLAW_APP_ID = "bot";
|
|
6
|
+
const WECHAT_CLAW_APP_CLIENT_VERSION = String(0x00020107);
|
|
7
|
+
export async function startWechatClawLogin() {
|
|
8
|
+
const payload = await fetchWechatClawJson(`${WECHAT_CLAW_FIXED_BASE_URL}/ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(WECHAT_CLAW_BOT_TYPE)}`);
|
|
9
|
+
const qrcode = readBodyText(payload, "qrcode");
|
|
10
|
+
if (!qrcode) {
|
|
11
|
+
throw platformRequestFailed("微信 claw 登录二维码响应缺少 qrcode");
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
sessionKey: qrcode,
|
|
15
|
+
qrcode,
|
|
16
|
+
qrcodeUrl: readBodyText(payload, "qrcode_img_content"),
|
|
17
|
+
status: "waiting_scan"
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export async function pollWechatClawLoginStatus(options) {
|
|
21
|
+
const payload = await fetchWechatClawJson(`${normalizeWechatClawBaseUrl(options.authBaseUrl)}/ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(options.qrcode)}`);
|
|
22
|
+
const rawStatus = readBodyText(payload, "status");
|
|
23
|
+
switch (rawStatus) {
|
|
24
|
+
case "wait":
|
|
25
|
+
return createWechatClawPollLoginResult("waiting_scan");
|
|
26
|
+
case "scaned":
|
|
27
|
+
return createWechatClawPollLoginResult("scan_confirmed");
|
|
28
|
+
case "expired":
|
|
29
|
+
return createWechatClawPollLoginResult("expired");
|
|
30
|
+
case "scaned_but_redirect":
|
|
31
|
+
return {
|
|
32
|
+
...createWechatClawPollLoginResult("scan_confirmed"),
|
|
33
|
+
redirectHost: readBodyText(payload, "redirect_host")
|
|
34
|
+
};
|
|
35
|
+
case "confirmed":
|
|
36
|
+
return {
|
|
37
|
+
status: "active",
|
|
38
|
+
botToken: readBodyText(payload, "bot_token"),
|
|
39
|
+
baseUrl: readBodyText(payload, "baseurl") ?? normalizeWechatClawBaseUrl(options.authBaseUrl),
|
|
40
|
+
remoteBotId: readBodyText(payload, "ilink_bot_id"),
|
|
41
|
+
boundUserId: readBodyText(payload, "ilink_user_id"),
|
|
42
|
+
redirectHost: null
|
|
43
|
+
};
|
|
44
|
+
default:
|
|
45
|
+
throw platformRequestFailed(`微信 claw 登录状态无法识别:${rawStatus ?? "unknown"}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export async function pollWechatClawMessages(options) {
|
|
49
|
+
const payload = ensurePlainObject(await fetchJson(`${normalizeWechatClawBaseUrl(options.baseUrl)}/ilink/bot/getupdates`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: buildWechatClawHeaders(options.botToken),
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
base_info: {
|
|
54
|
+
channel_version: "2.0.0"
|
|
55
|
+
},
|
|
56
|
+
get_updates_buf: options.cursor ?? "",
|
|
57
|
+
timeout: Math.max(options.timeoutMs ?? 0, 0),
|
|
58
|
+
max_items: 50
|
|
59
|
+
})
|
|
60
|
+
}), "wechat claw getupdates response");
|
|
61
|
+
const errorCode = readBodyInteger(payload, "errcode");
|
|
62
|
+
if (errorCode === -14) {
|
|
63
|
+
throw platformLoginExpired("个人微信(claw)登录已失效,请重新扫码绑定");
|
|
64
|
+
}
|
|
65
|
+
if (typeof errorCode === "number" && errorCode !== 0) {
|
|
66
|
+
throw platformRequestFailed(`微信 claw 拉取消息失败:${readBodyText(payload, "errmsg") ?? `errcode=${errorCode}`}`);
|
|
67
|
+
}
|
|
68
|
+
const cursor = readBodyText(payload, "get_updates_buf")
|
|
69
|
+
?? readBodyText(payload, "next_cursor")
|
|
70
|
+
?? readBodyText(payload, "sync_buf");
|
|
71
|
+
const items = Array.isArray(payload.msgs)
|
|
72
|
+
? payload.msgs
|
|
73
|
+
: Array.isArray(payload.messages)
|
|
74
|
+
? payload.messages
|
|
75
|
+
: Array.isArray(payload.msg_list)
|
|
76
|
+
? payload.msg_list
|
|
77
|
+
: [];
|
|
78
|
+
return {
|
|
79
|
+
nextCursor: cursor,
|
|
80
|
+
longPollingTimeoutMs: readBodyInteger(payload, "longpolling_timeout_ms"),
|
|
81
|
+
messages: items
|
|
82
|
+
.map((item) => parseWechatClawInboundMessage(item))
|
|
83
|
+
.filter((item) => item !== null)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export async function sendWechatClawText(options) {
|
|
87
|
+
const payload = ensurePlainObject(await fetchJson(`${normalizeWechatClawBaseUrl(options.baseUrl)}/ilink/bot/sendmessage`, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: buildWechatClawHeaders(options.botToken),
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
to_user_id: options.toUserId,
|
|
92
|
+
context_token: options.contextToken,
|
|
93
|
+
item_list: [
|
|
94
|
+
{
|
|
95
|
+
type: "text",
|
|
96
|
+
text_item: {
|
|
97
|
+
text: options.text
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
})
|
|
102
|
+
}), "wechat claw sendmessage response");
|
|
103
|
+
return {
|
|
104
|
+
messageRef: readBodyText(payload, "message_id") ?? readBodyText(payload, "msg_id")
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function normalizeWechatClawBaseUrl(value) {
|
|
108
|
+
const normalized = value?.trim();
|
|
109
|
+
return normalized && normalized.length > 0 ? normalized : WECHAT_CLAW_FIXED_BASE_URL;
|
|
110
|
+
}
|
|
111
|
+
function createWechatClawPollLoginResult(status) {
|
|
112
|
+
return {
|
|
113
|
+
status,
|
|
114
|
+
botToken: null,
|
|
115
|
+
baseUrl: null,
|
|
116
|
+
remoteBotId: null,
|
|
117
|
+
boundUserId: null,
|
|
118
|
+
redirectHost: null
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function buildWechatClawHeaders(botToken) {
|
|
122
|
+
return {
|
|
123
|
+
authorization: `Bearer ${botToken}`,
|
|
124
|
+
authorizationtype: "ilink_bot_token",
|
|
125
|
+
"content-type": "application/json",
|
|
126
|
+
"ilink-app-id": WECHAT_CLAW_APP_ID,
|
|
127
|
+
"ilink-app-clientversion": WECHAT_CLAW_APP_CLIENT_VERSION,
|
|
128
|
+
"x-wechat-uin": Buffer.from(String(randomInt(1, 0xffffffff))).toString("base64")
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function parseWechatClawInboundMessage(value) {
|
|
132
|
+
const payload = ensurePlainObject(value, "wechat claw message");
|
|
133
|
+
const text = extractWechatClawText(payload);
|
|
134
|
+
const fromUserId = readBodyText(payload, "from_user_id");
|
|
135
|
+
if (!text || !fromUserId) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
messageId: readBodyText(payload, "message_id")
|
|
140
|
+
?? readBodyText(payload, "msg_id")
|
|
141
|
+
?? `wechat-claw:${Date.now()}:${Math.random().toString(16).slice(2, 10)}`,
|
|
142
|
+
fromUserId,
|
|
143
|
+
toUserId: readBodyText(payload, "to_user_id"),
|
|
144
|
+
text,
|
|
145
|
+
timestamp: readBodyText(payload, "timestamp"),
|
|
146
|
+
contextToken: readBodyText(payload, "context_token"),
|
|
147
|
+
rawPayload: payload
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function extractWechatClawText(payload) {
|
|
151
|
+
const itemList = payload.item_list;
|
|
152
|
+
if (!Array.isArray(itemList)) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
for (const item of itemList) {
|
|
156
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const entry = item;
|
|
160
|
+
if (readBodyText(entry, "type") !== "text") {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const textItem = ensurePlainObject(entry.text_item ?? {}, "wechat claw text_item");
|
|
164
|
+
const text = readBodyText(textItem, "text");
|
|
165
|
+
if (text) {
|
|
166
|
+
return text;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
async function fetchWechatClawJson(url) {
|
|
172
|
+
return ensurePlainObject(await fetchJson(url), "wechat claw response");
|
|
173
|
+
}
|
|
174
|
+
async function fetchJson(url, init) {
|
|
175
|
+
const response = await fetch(url, init);
|
|
176
|
+
const text = await response.text();
|
|
177
|
+
const payload = text ? safeJsonParse(text) : null;
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
throw new AppError({
|
|
180
|
+
statusCode: 502,
|
|
181
|
+
errorCode: "CHANNEL_PLATFORM_REQUEST_FAILED",
|
|
182
|
+
detail: `请求 ${url} 失败:${response.status} ${response.statusText}`
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return payload;
|
|
186
|
+
}
|
|
187
|
+
function safeJsonParse(text) {
|
|
188
|
+
try {
|
|
189
|
+
return JSON.parse(text);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return {
|
|
193
|
+
raw: text
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function ensurePlainObject(value, field) {
|
|
198
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
199
|
+
throw platformRequestFailed(`${field} 必须是对象`);
|
|
200
|
+
}
|
|
201
|
+
return value;
|
|
202
|
+
}
|
|
203
|
+
function readBodyText(source, key) {
|
|
204
|
+
if (!source || typeof source !== "object" || Array.isArray(source)) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const value = source[key];
|
|
208
|
+
if (typeof value === "string") {
|
|
209
|
+
const normalized = value.trim();
|
|
210
|
+
return normalized.length > 0 ? normalized : null;
|
|
211
|
+
}
|
|
212
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
213
|
+
return String(value);
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
function readBodyInteger(source, key) {
|
|
218
|
+
if (!source || typeof source !== "object" || Array.isArray(source)) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
const value = source[key];
|
|
222
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
223
|
+
return Math.trunc(value);
|
|
224
|
+
}
|
|
225
|
+
if (typeof value === "string") {
|
|
226
|
+
const parsed = Number.parseInt(value.trim(), 10);
|
|
227
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
function platformRequestFailed(detail) {
|
|
232
|
+
return new AppError({
|
|
233
|
+
statusCode: 502,
|
|
234
|
+
errorCode: "CHANNEL_PLATFORM_REQUEST_FAILED",
|
|
235
|
+
detail
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
function platformLoginExpired(detail) {
|
|
239
|
+
return new AppError({
|
|
240
|
+
statusCode: 401,
|
|
241
|
+
errorCode: "CHANNEL_PLATFORM_LOGIN_EXPIRED",
|
|
242
|
+
detail
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=wechat-claw-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wechat-claw-client.js","sourceRoot":"","sources":["../../../../src/modules/channels/wechat-claw-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/scripts/postinstall.mjs
CHANGED
|
@@ -94,29 +94,13 @@ async function verifyCodexRuntime() {
|
|
|
94
94
|
return false;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
env: process.env,
|
|
100
|
-
encoding: "utf8",
|
|
101
|
-
timeout: 30_000
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
if (versionCheck.error) {
|
|
105
|
-
console.error(`[codingns] Codex CLI 启动失败:${versionCheck.error.message}`);
|
|
97
|
+
if (!isExecutableFile(nativeCodexBinaryPath)) {
|
|
98
|
+
console.error(`[codingns] Codex CLI 平台二进制不可执行:${nativeCodexBinaryPath}`);
|
|
106
99
|
return false;
|
|
107
100
|
}
|
|
108
101
|
|
|
109
|
-
if (versionCheck.status !== 0) {
|
|
110
|
-
console.error(
|
|
111
|
-
`[codingns] Codex CLI 校验失败:${formatSpawnFailure(versionCheck)}`
|
|
112
|
-
);
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const versionText = versionCheck.stdout?.trim() || "unknown";
|
|
117
102
|
logInfo(`[codingns] Codex CLI 入口已就绪:${codexBinPath}`);
|
|
118
103
|
logInfo(`[codingns] Codex CLI 平台运行文件已就绪:${nativeCodexBinaryPath}`);
|
|
119
|
-
logInfo(`[codingns] Codex CLI 版本:${versionText}`);
|
|
120
104
|
return true;
|
|
121
105
|
} catch (error) {
|
|
122
106
|
const detail = error instanceof Error ? error.message : String(error);
|
|
@@ -251,17 +235,6 @@ function resolveCodexNativeBinaryPath(codexBinPath) {
|
|
|
251
235
|
return fs.existsSync(platformBinaryPath) ? platformBinaryPath : null;
|
|
252
236
|
}
|
|
253
237
|
|
|
254
|
-
function formatSpawnFailure(result) {
|
|
255
|
-
const parts = [
|
|
256
|
-
result.stderr?.trim(),
|
|
257
|
-
result.stdout?.trim(),
|
|
258
|
-
result.signal ? `signal=${result.signal}` : null,
|
|
259
|
-
typeof result.status === "number" ? `exitCode=${result.status}` : null
|
|
260
|
-
].filter(Boolean);
|
|
261
|
-
|
|
262
|
-
return parts.join("\n") || "unknown error";
|
|
263
|
-
}
|
|
264
|
-
|
|
265
238
|
function resolveCodexPlatformPackageName() {
|
|
266
239
|
switch (`${process.platform}/${process.arch}`) {
|
|
267
240
|
case "linux/x64":
|
|
@@ -281,6 +254,15 @@ function resolveCodexPlatformPackageName() {
|
|
|
281
254
|
}
|
|
282
255
|
}
|
|
283
256
|
|
|
257
|
+
function isExecutableFile(filePath) {
|
|
258
|
+
try {
|
|
259
|
+
fs.accessSync(filePath, process.platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
|
|
260
|
+
return true;
|
|
261
|
+
} catch {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
284
266
|
function resolveCodexTargetTriple() {
|
|
285
267
|
switch (`${process.platform}/${process.arch}`) {
|
|
286
268
|
case "linux/x64":
|