@wu529778790/open-im 1.10.9-beta.16 → 1.10.9-beta.18

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.
@@ -4,6 +4,7 @@
4
4
  * Receives messages via long-polling ilink/bot/getupdates
5
5
  * and dispatches them to the event handler.
6
6
  */
7
+ import { randomUUID } from 'node:crypto';
7
8
  import { createLogger } from '../logger.js';
8
9
  import { jitteredDelay } from '../shared/reconnect.js';
9
10
  import { CLAWBOT_POLL_INTERVAL_MS } from '../constants.js';
@@ -137,15 +138,40 @@ function updateState(state) {
137
138
  }
138
139
  async function fetchApi(path, signal) {
139
140
  const url = `${apiUrl}${path}`;
140
- const res = await fetch(url, {
141
- headers: {
142
- Authorization: `Bearer ${apiToken}`,
143
- AuthorizationType: 'ilink_bot_token',
144
- 'iLink-App-Id': 'bot',
145
- },
146
- signal,
147
- });
148
- return res.json();
141
+ const headers = {
142
+ 'Content-Type': 'application/json',
143
+ 'AuthorizationType': 'ilink_bot_token',
144
+ 'iLink-App-Id': 'bot',
145
+ 'iLink-App-ClientVersion': '131588',
146
+ 'X-WECHAT-UIN': randomUUID(),
147
+ };
148
+ // Add bot_token to URL for authenticated endpoints
149
+ const sep = path.includes('?') ? '&' : '?';
150
+ const authedUrl = apiToken ? `${url}${sep}bot_token=${encodeURIComponent(apiToken)}` : url;
151
+ const res = await fetch(authedUrl, { headers, signal });
152
+ const text = await res.text();
153
+ try {
154
+ const raw = JSON.parse(text);
155
+ // iLink API uses {"ret": 0} for success, {"ret": -1} for error
156
+ if ('ret' in raw) {
157
+ const ok = raw.ret === 0 || raw.ret === '0';
158
+ const result = raw.result ?? raw.data ?? raw;
159
+ if (!ok) {
160
+ log.warn(`ClawBot API ${path.split('?')[0]} response: ${text.substring(0, 500)}`);
161
+ }
162
+ return { ok, error: ok ? undefined : String(raw.retmsg ?? raw.errmsg ?? raw.msg ?? `ret=${raw.ret}`), result };
163
+ }
164
+ // Fallback: {"ok": true/false} format
165
+ const json = raw;
166
+ if (!json.ok) {
167
+ log.warn(`ClawBot API ${path.split('?')[0]} response: ${text.substring(0, 500)}`);
168
+ }
169
+ return json;
170
+ }
171
+ catch {
172
+ log.warn(`ClawBot API non-JSON response (${res.status}): ${text.substring(0, 300)}`);
173
+ return { ok: false, error: `HTTP ${res.status}: non-JSON response` };
174
+ }
149
175
  }
150
176
  function sleep(ms, signal) {
151
177
  return new Promise((resolve) => {
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * ClawBot Message Sender - Send messages via iLink API
3
3
  */
4
+ import { randomUUID } from 'node:crypto';
4
5
  import { createLogger } from '../logger.js';
5
6
  import { splitLongContent, toReplyPlainText } from '../shared/utils.js';
6
7
  import { MAX_CLAWBOT_MESSAGE_LENGTH } from '../constants.js';
@@ -18,19 +19,22 @@ async function postMessage(chatId, text) {
18
19
  return false;
19
20
  }
20
21
  try {
21
- const res = await fetch(`${apiUrl}/ilink/bot/sendmessage`, {
22
+ const url = `${apiUrl}/ilink/bot/sendmessage?bot_token=${encodeURIComponent(apiToken)}`;
23
+ const res = await fetch(url, {
22
24
  method: 'POST',
23
25
  headers: {
24
26
  'Content-Type': 'application/json',
25
- Authorization: `Bearer ${apiToken}`,
26
- AuthorizationType: 'ilink_bot_token',
27
+ 'AuthorizationType': 'ilink_bot_token',
27
28
  'iLink-App-Id': 'bot',
29
+ 'iLink-App-ClientVersion': '131588',
30
+ 'X-WECHAT-UIN': randomUUID(),
28
31
  },
29
32
  body: JSON.stringify({ chat_id: chatId, text }),
30
33
  });
31
34
  const data = await res.json();
32
- if (!data.ok) {
33
- log.error(`ClawBot sendmessage failed: ${data.error ?? 'unknown'}`);
35
+ const ok = data.ok === true || data.ret === 0 || data.ret === '0';
36
+ if (!ok) {
37
+ log.error(`ClawBot sendmessage failed: ${JSON.stringify(data).substring(0, 300)}`);
34
38
  return false;
35
39
  }
36
40
  return true;
@@ -625,12 +625,20 @@ async function probeClawBot(config) {
625
625
  const apiToken = clean(String(config.apiToken ?? ""));
626
626
  if (!apiToken)
627
627
  throw new Error("ClawBot API token is required.");
628
- const response = await fetch(`${apiUrl}/ilink/bot/getupdates?timeout=1`, {
629
- headers: { Authorization: `Bearer ${apiToken}` },
628
+ const { randomUUID } = await import('node:crypto');
629
+ const response = await fetch(`${apiUrl}/ilink/bot/getupdates?timeout=1&bot_token=${encodeURIComponent(apiToken)}`, {
630
+ headers: {
631
+ 'Content-Type': 'application/json',
632
+ 'AuthorizationType': 'ilink_bot_token',
633
+ 'iLink-App-Id': 'bot',
634
+ 'iLink-App-ClientVersion': '131588',
635
+ 'X-WECHAT-UIN': randomUUID(),
636
+ },
630
637
  signal: AbortSignal.timeout(TEST_TIMEOUT_MS),
631
638
  });
632
639
  const body = await readJsonResponse(response);
633
- if (!response.ok || body.ok !== true) {
640
+ const ok = body.ok === true || body.ret === 0 || body.ret === '0';
641
+ if (!response.ok || !ok) {
634
642
  throw new Error(String(body.error ?? body.description ?? `HTTP ${response.status}`));
635
643
  }
636
644
  return "ClawBot API reachable.";
package/dist/setup.js CHANGED
@@ -607,6 +607,8 @@ export async function runInteractiveSetup() {
607
607
  });
608
608
  if (result.connected && result.botToken) {
609
609
  cbApiToken = result.botToken;
610
+ if (result.baseUrl)
611
+ cbApiUrl = result.baseUrl;
610
612
  console.log("\n✅ 登录成功!");
611
613
  if (result.userId) {
612
614
  console.log(` 用户 ID: ${result.userId}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wu529778790/open-im",
3
- "version": "1.10.9-beta.16",
3
+ "version": "1.10.9-beta.18",
4
4
  "description": "Multi-platform IM bridge for AI CLI tools (Claude, Codex, CodeBuddy)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",