@liangrk/claude-code-wechatbot 0.3.2 → 0.3.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.
- package/cli.mjs +155 -1
- package/dist/setup.js +1033 -983
- package/dist/wechat-channel.js +14950 -7682
- package/package.json +4 -3
package/cli.mjs
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
import { execSync, spawnSync } from "node:child_process";
|
|
13
13
|
import { existsSync, writeFileSync, readFileSync, renameSync } from "node:fs";
|
|
14
|
-
import { resolve, dirname } from "node:path";
|
|
14
|
+
import { resolve, dirname, join } from "node:path";
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
|
+
import os from "node:os";
|
|
16
17
|
|
|
17
18
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
19
|
const DIST_DIR = resolve(__dirname, "dist");
|
|
@@ -46,6 +47,155 @@ function runScript(script, args = []) {
|
|
|
46
47
|
process.exit(result.status ?? 1);
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
function getCredentialsDir() {
|
|
51
|
+
return join(os.homedir(), ".claude", "channels", "wechat");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getCredentialsFile() {
|
|
55
|
+
return join(getCredentialsDir(), "account.json");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function status() {
|
|
59
|
+
const credFile = getCredentialsFile();
|
|
60
|
+
|
|
61
|
+
if (!existsSync(credFile)) {
|
|
62
|
+
console.log("Status: NOT CONFIGURED");
|
|
63
|
+
console.log("");
|
|
64
|
+
console.log("No account credentials found.");
|
|
65
|
+
console.log("Run: npx claude-code-wechat-channel setup");
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let account;
|
|
70
|
+
try {
|
|
71
|
+
account = JSON.parse(readFileSync(credFile, "utf-8"));
|
|
72
|
+
} catch {
|
|
73
|
+
console.log("Status: ERROR");
|
|
74
|
+
console.log("");
|
|
75
|
+
console.log("Failed to parse account.json. It may be corrupted.");
|
|
76
|
+
console.log(`File: ${credFile}`);
|
|
77
|
+
console.log("Fix: Remove the file and run setup again.");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log("Account Information:");
|
|
82
|
+
console.log(` Bot ID: ${account.accountId ?? "N/A"}`);
|
|
83
|
+
console.log(` User ID: ${account.userId ?? "N/A"}`);
|
|
84
|
+
console.log(` Base URL: ${account.baseUrl ?? "N/A"}`);
|
|
85
|
+
console.log(` Token: ${account.token ? account.token.slice(0, 8) + "..." : "MISSING"}`);
|
|
86
|
+
|
|
87
|
+
if (account.savedAt) {
|
|
88
|
+
const ageMs = Date.now() - new Date(account.savedAt).getTime();
|
|
89
|
+
const ageHours = (ageMs / 3600_000).toFixed(1);
|
|
90
|
+
console.log(` Saved at: ${account.savedAt} (${ageHours}h ago)`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!account.token) {
|
|
94
|
+
console.log("");
|
|
95
|
+
console.log("Status: MISSING TOKEN");
|
|
96
|
+
console.log("The account.json is missing the bot_token.");
|
|
97
|
+
console.log("Fix: Run setup again: npx claude-code-wechat-channel setup");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Test API connectivity
|
|
102
|
+
console.log("");
|
|
103
|
+
console.log("Testing API connectivity...");
|
|
104
|
+
|
|
105
|
+
const body = JSON.stringify({
|
|
106
|
+
get_updates_buf: "",
|
|
107
|
+
base_info: { channel_version: "1.0.2" },
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const base = (account.baseUrl || "https://ilinkai.weixin.qq.com").replace(/\/$/, "") + "/";
|
|
111
|
+
const url = base + "ilink/bot/getupdates";
|
|
112
|
+
|
|
113
|
+
const start = Date.now();
|
|
114
|
+
try {
|
|
115
|
+
const res = await fetch(url, {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: {
|
|
118
|
+
"Content-Type": "application/json",
|
|
119
|
+
AuthorizationType: "ilink_bot_token",
|
|
120
|
+
Authorization: `Bearer ${account.token}`,
|
|
121
|
+
},
|
|
122
|
+
body,
|
|
123
|
+
signal: AbortSignal.timeout(15_000),
|
|
124
|
+
});
|
|
125
|
+
const latency = Date.now() - start;
|
|
126
|
+
const text = await res.text();
|
|
127
|
+
|
|
128
|
+
if (!res.ok) {
|
|
129
|
+
console.log(`Status: API ERROR (HTTP ${res.status}, ${latency}ms)`);
|
|
130
|
+
console.log(` Response: ${text.slice(0, 300)}`);
|
|
131
|
+
console.log("");
|
|
132
|
+
console.log("Possible causes:");
|
|
133
|
+
console.log(" - Bot token is invalid or expired");
|
|
134
|
+
console.log(" - Network/firewall blocking the request");
|
|
135
|
+
console.log("Fix: Run setup again: npx claude-code-wechat-channel setup");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let resp;
|
|
140
|
+
try {
|
|
141
|
+
resp = JSON.parse(text);
|
|
142
|
+
} catch {
|
|
143
|
+
console.log(`Status: UNEXPECTED RESPONSE (${latency}ms)`);
|
|
144
|
+
console.log(` Response: ${text.slice(0, 300)}`);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const isErr =
|
|
149
|
+
(resp.ret !== undefined && resp.ret !== 0) ||
|
|
150
|
+
(resp.errcode !== undefined && resp.errcode !== 0);
|
|
151
|
+
|
|
152
|
+
if (isErr) {
|
|
153
|
+
if (resp.ret === -14 || resp.errcode === -14) {
|
|
154
|
+
console.log(`Status: SESSION EXPIRED (${latency}ms)`);
|
|
155
|
+
console.log(" The WeChat session has expired.");
|
|
156
|
+
console.log("");
|
|
157
|
+
console.log("Fix: Run setup to re-login: npx claude-code-wechat-channel setup");
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
console.log(`Status: API ERROR (${latency}ms)`);
|
|
161
|
+
console.log(` ret=${resp.ret} errcode=${resp.errcode} errmsg=${resp.errmsg ?? ""}`);
|
|
162
|
+
console.log("");
|
|
163
|
+
console.log("Possible causes:");
|
|
164
|
+
console.log(" - ClawBot is not activated in WeChat");
|
|
165
|
+
console.log(" - Bot token is invalid");
|
|
166
|
+
console.log("Fix: Run setup again: npx claude-code-wechat-channel setup");
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
console.log(`Status: OK (${latency}ms)`);
|
|
171
|
+
console.log(" API is reachable and session is valid.");
|
|
172
|
+
console.log("");
|
|
173
|
+
console.log("The WeChat channel is ready to use.");
|
|
174
|
+
console.log("If messages aren't being received by Claude Code, check:");
|
|
175
|
+
console.log(" 1. Claude Code is running with MCP connected");
|
|
176
|
+
console.log(" 2. Messages are sent to the ClawBot in WeChat");
|
|
177
|
+
} catch (err) {
|
|
178
|
+
const elapsed = Date.now() - start;
|
|
179
|
+
if (err.name === "TimeoutError" || err.name === "AbortError") {
|
|
180
|
+
console.log(`Status: TIMEOUT (${elapsed}ms)`);
|
|
181
|
+
console.log(" The API request timed out.");
|
|
182
|
+
console.log("");
|
|
183
|
+
console.log("Possible causes:");
|
|
184
|
+
console.log(" - Network connectivity issues");
|
|
185
|
+
console.log(" - Firewall blocking access to ilinkai.weixin.qq.com");
|
|
186
|
+
} else {
|
|
187
|
+
console.log(`Status: NETWORK ERROR (${elapsed}ms)`);
|
|
188
|
+
console.log(` ${err.message}`);
|
|
189
|
+
console.log("");
|
|
190
|
+
console.log("Possible causes:");
|
|
191
|
+
console.log(" - No internet connection");
|
|
192
|
+
console.log(" - DNS resolution failure");
|
|
193
|
+
console.log(" - Firewall blocking the request");
|
|
194
|
+
}
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
49
199
|
function install() {
|
|
50
200
|
const mcpConfig = {
|
|
51
201
|
mcpServers: {
|
|
@@ -97,6 +247,7 @@ function help() {
|
|
|
97
247
|
Commands:
|
|
98
248
|
setup WeChat QR login (scan to authenticate)
|
|
99
249
|
start Start the channel MCP server
|
|
250
|
+
status Check account and API connectivity
|
|
100
251
|
install Write .mcp.json to current directory
|
|
101
252
|
help Show this help message
|
|
102
253
|
`);
|
|
@@ -111,6 +262,9 @@ switch (command) {
|
|
|
111
262
|
case "start":
|
|
112
263
|
runScript("wechat-channel.js");
|
|
113
264
|
break;
|
|
265
|
+
case "status":
|
|
266
|
+
status();
|
|
267
|
+
break;
|
|
114
268
|
case "install":
|
|
115
269
|
install();
|
|
116
270
|
break;
|