@agent-wechat/wechat 0.3.1 → 0.4.0
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/dist/index.js +158 -168
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -1106,6 +1106,21 @@ function resolveWeChatAccount(cfg, accountId) {
|
|
|
1106
1106
|
};
|
|
1107
1107
|
}
|
|
1108
1108
|
|
|
1109
|
+
// src/runtime.ts
|
|
1110
|
+
var runtime = null;
|
|
1111
|
+
function setWeChatRuntime(next) {
|
|
1112
|
+
runtime = next;
|
|
1113
|
+
}
|
|
1114
|
+
function getWeChatRuntime() {
|
|
1115
|
+
if (!runtime) {
|
|
1116
|
+
throw new Error("WeChat runtime not initialized");
|
|
1117
|
+
}
|
|
1118
|
+
return runtime;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// src/monitor.ts
|
|
1122
|
+
import { execSync } from "node:child_process";
|
|
1123
|
+
|
|
1109
1124
|
// ../shared/dist/client.js
|
|
1110
1125
|
function normalizeUrl(base) {
|
|
1111
1126
|
const url = base.startsWith("http") ? base : `http://${base}`;
|
|
@@ -5486,20 +5501,6 @@ var agentConfigSchema = external_exports.object({
|
|
|
5486
5501
|
|
|
5487
5502
|
// src/monitor.ts
|
|
5488
5503
|
import { createReplyPrefixOptions } from "openclaw/plugin-sdk";
|
|
5489
|
-
|
|
5490
|
-
// src/runtime.ts
|
|
5491
|
-
var runtime = null;
|
|
5492
|
-
function setWeChatRuntime(next) {
|
|
5493
|
-
runtime = next;
|
|
5494
|
-
}
|
|
5495
|
-
function getWeChatRuntime() {
|
|
5496
|
-
if (!runtime) {
|
|
5497
|
-
throw new Error("WeChat runtime not initialized");
|
|
5498
|
-
}
|
|
5499
|
-
return runtime;
|
|
5500
|
-
}
|
|
5501
|
-
|
|
5502
|
-
// src/monitor.ts
|
|
5503
5504
|
var MEDIA_TYPES = /* @__PURE__ */ new Set([3, 34]);
|
|
5504
5505
|
var HISTORY_CONTEXT_MARKER = "[Chat messages since your last reply - for context]";
|
|
5505
5506
|
var CURRENT_MESSAGE_MARKER = "[Current message - respond to this]";
|
|
@@ -5552,8 +5553,16 @@ function enqueueWeChatSystemEvent(text, contextKey) {
|
|
|
5552
5553
|
} catch {
|
|
5553
5554
|
}
|
|
5554
5555
|
}
|
|
5556
|
+
function enqueueAndWakeSystemEvent(text, contextKey, log) {
|
|
5557
|
+
enqueueWeChatSystemEvent(text, contextKey);
|
|
5558
|
+
try {
|
|
5559
|
+
execSync("openclaw system event --mode now", { timeout: 5e3, stdio: "ignore" });
|
|
5560
|
+
} catch {
|
|
5561
|
+
log?.info?.("Failed to trigger heartbeat wake \u2014 agent will see event on next prompt");
|
|
5562
|
+
}
|
|
5563
|
+
}
|
|
5555
5564
|
async function startWeChatMonitor(opts) {
|
|
5556
|
-
const { account, abortSignal,
|
|
5565
|
+
const { account, abortSignal, setStatus, log } = opts;
|
|
5557
5566
|
const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
|
|
5558
5567
|
const lastSeenId = /* @__PURE__ */ new Map();
|
|
5559
5568
|
let lastAuthCheck = 0;
|
|
@@ -5581,12 +5590,13 @@ async function startWeChatMonitor(opts) {
|
|
|
5581
5590
|
authStatus: auth.status
|
|
5582
5591
|
});
|
|
5583
5592
|
if (prevStatus === "logged_in" && !isLinked) {
|
|
5584
|
-
const msg = auth.status === "app_not_running" ? "[WeChat] Application stopped. It will restart automatically \u2014
|
|
5585
|
-
|
|
5593
|
+
const msg = auth.status === "app_not_running" ? "[WeChat] Application stopped. It will restart automatically \u2014 credentials may be cached, so you can try reconnecting using the wechat_login tool." : "[WeChat] Session ended. You can try reconnecting using the wechat_login tool \u2014 if credentials are cached, login may complete automatically.";
|
|
5594
|
+
enqueueAndWakeSystemEvent(msg, "wechat:auth_lost", log);
|
|
5586
5595
|
} else if (prevStatus === void 0 && !isLinked) {
|
|
5587
|
-
|
|
5588
|
-
"[WeChat] Not logged in. Use the wechat_login tool to authenticate.",
|
|
5589
|
-
"wechat:auth_required"
|
|
5596
|
+
enqueueAndWakeSystemEvent(
|
|
5597
|
+
"[WeChat] Not logged in. Use the wechat_login tool to authenticate \u2014 if credentials are cached from a previous session, login may complete automatically.",
|
|
5598
|
+
"wechat:auth_required",
|
|
5599
|
+
log
|
|
5590
5600
|
);
|
|
5591
5601
|
}
|
|
5592
5602
|
prevStatus = auth.status;
|
|
@@ -5604,9 +5614,10 @@ async function startWeChatMonitor(opts) {
|
|
|
5604
5614
|
lastError: String(err)
|
|
5605
5615
|
});
|
|
5606
5616
|
if (prevStatus === "logged_in") {
|
|
5607
|
-
|
|
5617
|
+
enqueueAndWakeSystemEvent(
|
|
5608
5618
|
"[WeChat] Cannot reach agent-wechat server. The container may have stopped.",
|
|
5609
|
-
"wechat:server_unreachable"
|
|
5619
|
+
"wechat:server_unreachable",
|
|
5620
|
+
log
|
|
5610
5621
|
);
|
|
5611
5622
|
}
|
|
5612
5623
|
prevStatus = void 0;
|
|
@@ -6303,24 +6314,26 @@ function readOrGenerateToken() {
|
|
|
6303
6314
|
return token;
|
|
6304
6315
|
}
|
|
6305
6316
|
var wechatOnboardingAdapter = {
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
if (!account
|
|
6317
|
+
channel: "wechat",
|
|
6318
|
+
getStatus: async ({ cfg }) => {
|
|
6319
|
+
const account = resolveWeChatAccount(cfg);
|
|
6320
|
+
if (!account?.serverUrl) {
|
|
6310
6321
|
return {
|
|
6322
|
+
channel: "wechat",
|
|
6311
6323
|
configured: false,
|
|
6312
|
-
|
|
6324
|
+
statusLines: ["Not configured. Run: openclaw channels setup wechat"]
|
|
6313
6325
|
};
|
|
6314
6326
|
}
|
|
6315
6327
|
const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
|
|
6316
|
-
const
|
|
6328
|
+
const statusLines = [];
|
|
6317
6329
|
try {
|
|
6318
6330
|
await client.status();
|
|
6319
|
-
|
|
6331
|
+
statusLines.push(`Connected to ${account.serverUrl}`);
|
|
6320
6332
|
} catch {
|
|
6321
6333
|
return {
|
|
6334
|
+
channel: "wechat",
|
|
6322
6335
|
configured: true,
|
|
6323
|
-
|
|
6336
|
+
statusLines: [
|
|
6324
6337
|
`Server URL: ${account.serverUrl}`,
|
|
6325
6338
|
"Cannot reach server \u2014 is the agent-wechat container running?"
|
|
6326
6339
|
]
|
|
@@ -6329,45 +6342,44 @@ var wechatOnboardingAdapter = {
|
|
|
6329
6342
|
try {
|
|
6330
6343
|
const auth = await client.authStatus();
|
|
6331
6344
|
if (auth.status === "logged_in") {
|
|
6332
|
-
|
|
6345
|
+
statusLines.push(
|
|
6333
6346
|
`Logged in${auth.loggedInUser ? ` as ${auth.loggedInUser}` : ""}`
|
|
6334
6347
|
);
|
|
6335
6348
|
} else {
|
|
6336
|
-
|
|
6349
|
+
statusLines.push("Not logged in. Run: openclaw channels login --channel wechat");
|
|
6337
6350
|
}
|
|
6338
6351
|
} catch {
|
|
6339
|
-
|
|
6352
|
+
statusLines.push("Could not check auth status");
|
|
6340
6353
|
}
|
|
6341
|
-
|
|
6354
|
+
statusLines.push(`DM policy: ${account.dmPolicy}`);
|
|
6342
6355
|
if (account.allowFrom.length > 0) {
|
|
6343
|
-
|
|
6356
|
+
statusLines.push(`Allowed senders: ${account.allowFrom.join(", ")}`);
|
|
6344
6357
|
}
|
|
6345
|
-
|
|
6346
|
-
return { configured: true,
|
|
6358
|
+
statusLines.push(`Group policy: ${account.groupPolicy}`);
|
|
6359
|
+
return { channel: "wechat", configured: true, statusLines };
|
|
6347
6360
|
},
|
|
6348
|
-
configure: async ({
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
const existingUrl = cfg?.channels?.wechat?.serverUrl ?? "http://localhost:6174";
|
|
6361
|
+
configure: async ({ prompter, cfg }) => {
|
|
6362
|
+
const wechatCfg = {
|
|
6363
|
+
...cfg?.channels?.wechat ?? {}
|
|
6364
|
+
};
|
|
6365
|
+
const existingUrl = wechatCfg.serverUrl ?? "http://localhost:6174";
|
|
6354
6366
|
const serverUrl = await prompter.text({
|
|
6355
6367
|
message: "Agent-wechat server URL",
|
|
6356
|
-
|
|
6368
|
+
initialValue: existingUrl
|
|
6357
6369
|
});
|
|
6358
|
-
|
|
6359
|
-
const existingToken =
|
|
6370
|
+
wechatCfg.serverUrl = serverUrl;
|
|
6371
|
+
const existingToken = wechatCfg.token ?? "";
|
|
6360
6372
|
const localDefault = existingToken || readOrGenerateToken();
|
|
6361
6373
|
const token = await prompter.text({
|
|
6362
6374
|
message: "Auth token (leave empty to use local token)",
|
|
6363
|
-
|
|
6375
|
+
initialValue: localDefault
|
|
6364
6376
|
});
|
|
6365
|
-
|
|
6377
|
+
wechatCfg.token = token || localDefault;
|
|
6366
6378
|
const client = new WeChatClient({ baseUrl: serverUrl, token: token || void 0 });
|
|
6367
6379
|
try {
|
|
6368
6380
|
await client.status();
|
|
6369
6381
|
} catch {
|
|
6370
|
-
|
|
6382
|
+
wechatCfg.enabled = false;
|
|
6371
6383
|
throw new Error(
|
|
6372
6384
|
`Cannot reach ${serverUrl}. Ensure the agent-wechat container is running.`
|
|
6373
6385
|
);
|
|
@@ -6377,10 +6389,10 @@ var wechatOnboardingAdapter = {
|
|
|
6377
6389
|
if (auth.status !== "logged_in") {
|
|
6378
6390
|
const wantsLink = await prompter.confirm({
|
|
6379
6391
|
message: "WeChat not logged in. Link now?",
|
|
6380
|
-
|
|
6392
|
+
initialValue: true
|
|
6381
6393
|
});
|
|
6382
6394
|
if (wantsLink) {
|
|
6383
|
-
await prompter.note
|
|
6395
|
+
await prompter.note(
|
|
6384
6396
|
"Starting login \u2014 watch for QR code or phone confirmation.",
|
|
6385
6397
|
"WeChat Login"
|
|
6386
6398
|
);
|
|
@@ -6389,52 +6401,37 @@ var wechatOnboardingAdapter = {
|
|
|
6389
6401
|
onEvent: (event) => {
|
|
6390
6402
|
switch (event.type) {
|
|
6391
6403
|
case "status":
|
|
6392
|
-
prompter.
|
|
6404
|
+
prompter.note?.(event.message, "Status");
|
|
6393
6405
|
break;
|
|
6394
6406
|
case "qr":
|
|
6395
|
-
prompter.
|
|
6396
|
-
if (event.qrData) {
|
|
6397
|
-
try {
|
|
6398
|
-
const qrTerminalMod = require_main();
|
|
6399
|
-
const qrInput = event.qrBinaryData ? Buffer.from(event.qrBinaryData).toString("utf-8") : event.qrData;
|
|
6400
|
-
qrTerminalMod.generate(qrInput, { small: true }, (qr) => {
|
|
6401
|
-
prompter.log?.(qr);
|
|
6402
|
-
});
|
|
6403
|
-
} catch {
|
|
6404
|
-
if (event.qrDataUrl) {
|
|
6405
|
-
prompter.log?.("(QR data URL available \u2014 open in browser to scan)");
|
|
6406
|
-
}
|
|
6407
|
-
}
|
|
6408
|
-
}
|
|
6409
|
-
prompter.log?.("\nWaiting for scan...\n");
|
|
6407
|
+
prompter.note?.("Scan QR code with WeChat", "Login");
|
|
6410
6408
|
break;
|
|
6411
6409
|
case "phone_confirm":
|
|
6412
|
-
prompter.
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
`
|
|
6410
|
+
prompter.note?.(
|
|
6411
|
+
event.message || "Please confirm login on your phone",
|
|
6412
|
+
"Confirm"
|
|
6416
6413
|
);
|
|
6417
6414
|
break;
|
|
6418
6415
|
case "login_success":
|
|
6419
|
-
prompter.
|
|
6416
|
+
prompter.note?.("Login successful!", "Done");
|
|
6420
6417
|
break;
|
|
6421
6418
|
case "login_timeout":
|
|
6422
|
-
prompter.
|
|
6419
|
+
prompter.note?.("Login timed out. Please try again.", "Timeout");
|
|
6423
6420
|
break;
|
|
6424
6421
|
case "error":
|
|
6425
|
-
prompter.
|
|
6426
|
-
Error: ${event.message}`);
|
|
6422
|
+
prompter.note?.(`Error: ${event.message}`, "Error");
|
|
6427
6423
|
break;
|
|
6428
6424
|
}
|
|
6429
6425
|
}
|
|
6430
6426
|
});
|
|
6431
6427
|
} catch (err) {
|
|
6432
|
-
prompter.
|
|
6433
|
-
`Login failed: ${err instanceof Error ? err.message : String(err)}
|
|
6428
|
+
prompter.note?.(
|
|
6429
|
+
`Login failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
6430
|
+
"Error"
|
|
6434
6431
|
);
|
|
6435
6432
|
}
|
|
6436
6433
|
} else {
|
|
6437
|
-
await prompter.note
|
|
6434
|
+
await prompter.note(
|
|
6438
6435
|
"Run `openclaw channels login --channel wechat` later to link.",
|
|
6439
6436
|
"WeChat"
|
|
6440
6437
|
);
|
|
@@ -6444,54 +6441,45 @@ Error: ${event.message}`);
|
|
|
6444
6441
|
}
|
|
6445
6442
|
const dmPolicy = await prompter.select({
|
|
6446
6443
|
message: "DM (direct message) policy",
|
|
6447
|
-
|
|
6444
|
+
options: [
|
|
6448
6445
|
{ label: "Disabled \u2014 ignore all DMs", value: "disabled" },
|
|
6449
|
-
{
|
|
6450
|
-
label: "Allowlist \u2014 only respond to specific senders",
|
|
6451
|
-
value: "allowlist"
|
|
6452
|
-
},
|
|
6446
|
+
{ label: "Allowlist \u2014 only respond to specific senders", value: "allowlist" },
|
|
6453
6447
|
{ label: "Open \u2014 respond to all DMs", value: "open" }
|
|
6454
6448
|
]
|
|
6455
6449
|
});
|
|
6456
|
-
|
|
6450
|
+
wechatCfg.dmPolicy = dmPolicy;
|
|
6457
6451
|
if (dmPolicy === "allowlist") {
|
|
6458
|
-
const
|
|
6459
|
-
message: "Allowed WeChat IDs (wxid_xxx)
|
|
6460
|
-
hint: "Enter wxid values, press Enter after each. Empty line to finish."
|
|
6452
|
+
const raw = await prompter.text({
|
|
6453
|
+
message: "Allowed WeChat IDs (comma-separated wxid_xxx values)"
|
|
6461
6454
|
});
|
|
6462
|
-
|
|
6455
|
+
wechatCfg.allowFrom = raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
6463
6456
|
}
|
|
6464
6457
|
const groupPolicy = await prompter.select({
|
|
6465
6458
|
message: "Group chat policy",
|
|
6466
|
-
|
|
6467
|
-
{
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
},
|
|
6471
|
-
{
|
|
6472
|
-
label: "Allowlist \u2014 only respond in specific groups",
|
|
6473
|
-
value: "allowlist"
|
|
6474
|
-
},
|
|
6475
|
-
{
|
|
6476
|
-
label: "Open \u2014 respond in all groups (when mentioned)",
|
|
6477
|
-
value: "open"
|
|
6478
|
-
}
|
|
6459
|
+
options: [
|
|
6460
|
+
{ label: "Disabled \u2014 ignore all group messages", value: "disabled" },
|
|
6461
|
+
{ label: "Allowlist \u2014 only respond in specific groups", value: "allowlist" },
|
|
6462
|
+
{ label: "Open \u2014 respond in all groups (when mentioned)", value: "open" }
|
|
6479
6463
|
]
|
|
6480
6464
|
});
|
|
6481
|
-
|
|
6465
|
+
wechatCfg.groupPolicy = groupPolicy;
|
|
6482
6466
|
if (groupPolicy === "allowlist") {
|
|
6483
|
-
const
|
|
6484
|
-
message: "Allowed group IDs (xxx@chatroom)
|
|
6485
|
-
hint: "Enter chatroom IDs, press Enter after each. Empty line to finish."
|
|
6467
|
+
const raw = await prompter.text({
|
|
6468
|
+
message: "Allowed group IDs (comma-separated xxx@chatroom values)"
|
|
6486
6469
|
});
|
|
6487
|
-
|
|
6470
|
+
wechatCfg.groupAllowFrom = raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
6488
6471
|
}
|
|
6489
|
-
|
|
6472
|
+
wechatCfg.enabled = true;
|
|
6473
|
+
const newCfg = {
|
|
6474
|
+
...cfg,
|
|
6475
|
+
channels: { ...cfg.channels, wechat: wechatCfg }
|
|
6476
|
+
};
|
|
6477
|
+
return { cfg: newCfg };
|
|
6490
6478
|
}
|
|
6491
6479
|
};
|
|
6492
6480
|
|
|
6493
6481
|
// src/status.ts
|
|
6494
|
-
|
|
6482
|
+
function collectWeChatStatusIssues(accounts) {
|
|
6495
6483
|
const issues = [];
|
|
6496
6484
|
for (const snapshot of accounts) {
|
|
6497
6485
|
if (!snapshot.connected) {
|
|
@@ -6548,7 +6536,8 @@ function createWeChatLoginTool(account) {
|
|
|
6548
6536
|
},
|
|
6549
6537
|
required: ["action"]
|
|
6550
6538
|
},
|
|
6551
|
-
execute: async (_toolCallId,
|
|
6539
|
+
execute: async (_toolCallId, params) => {
|
|
6540
|
+
const args = params;
|
|
6552
6541
|
const action = args.action;
|
|
6553
6542
|
const force = args.force;
|
|
6554
6543
|
const timeoutMs = args.timeoutMs;
|
|
@@ -6671,6 +6660,7 @@ var meta = {
|
|
|
6671
6660
|
label: "WeChat",
|
|
6672
6661
|
selectionLabel: "WeChat (\u5FAE\u4FE1)",
|
|
6673
6662
|
blurb: "WeChat messaging via agent-wechat container.",
|
|
6663
|
+
docsPath: "wechat",
|
|
6674
6664
|
aliases: ["weixin"],
|
|
6675
6665
|
order: 80
|
|
6676
6666
|
};
|
|
@@ -6787,14 +6777,16 @@ var wechatPlugin = {
|
|
|
6787
6777
|
cfg
|
|
6788
6778
|
);
|
|
6789
6779
|
if (!account?.serverUrl) {
|
|
6790
|
-
|
|
6780
|
+
throw new Error("No serverUrl configured");
|
|
6791
6781
|
}
|
|
6792
6782
|
const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
|
|
6793
6783
|
const result = await client.sendMessage({ chatId: to, text });
|
|
6784
|
+
if (!result.success) {
|
|
6785
|
+
throw new Error(result.error ?? "Send failed");
|
|
6786
|
+
}
|
|
6794
6787
|
return {
|
|
6795
6788
|
channel: "wechat",
|
|
6796
|
-
|
|
6797
|
-
error: result.error ?? void 0
|
|
6789
|
+
messageId: `wechat:${to}:${Date.now()}`
|
|
6798
6790
|
};
|
|
6799
6791
|
},
|
|
6800
6792
|
sendMedia: async ({ cfg, to, text, mediaUrl }) => {
|
|
@@ -6802,68 +6794,64 @@ var wechatPlugin = {
|
|
|
6802
6794
|
cfg
|
|
6803
6795
|
);
|
|
6804
6796
|
if (!account?.serverUrl) {
|
|
6805
|
-
|
|
6797
|
+
throw new Error("No serverUrl configured");
|
|
6806
6798
|
}
|
|
6807
6799
|
const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
|
|
6808
6800
|
if (mediaUrl) {
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
webp: "image/webp"
|
|
6833
|
-
};
|
|
6834
|
-
mimeType = extMime[ext] ?? "application/octet-stream";
|
|
6835
|
-
}
|
|
6836
|
-
const isImage = mimeType.startsWith("image/");
|
|
6837
|
-
const result2 = isImage ? await client.sendMessage({
|
|
6838
|
-
chatId: to,
|
|
6839
|
-
text: text || void 0,
|
|
6840
|
-
image: { data: base64, mimeType }
|
|
6841
|
-
}) : await client.sendMessage({
|
|
6842
|
-
chatId: to,
|
|
6843
|
-
text: text || void 0,
|
|
6844
|
-
file: { data: base64, filename }
|
|
6845
|
-
});
|
|
6846
|
-
return {
|
|
6847
|
-
channel: "wechat",
|
|
6848
|
-
ok: result2.success,
|
|
6849
|
-
error: result2.error ?? void 0
|
|
6850
|
-
};
|
|
6851
|
-
} catch (err) {
|
|
6852
|
-
return {
|
|
6853
|
-
channel: "wechat",
|
|
6854
|
-
ok: false,
|
|
6855
|
-
error: `Failed to send media: ${err}`
|
|
6801
|
+
const fsmod = await import("fs/promises");
|
|
6802
|
+
const pathmod = await import("path");
|
|
6803
|
+
let base64;
|
|
6804
|
+
let mimeType;
|
|
6805
|
+
let filename;
|
|
6806
|
+
if (mediaUrl.startsWith("http://") || mediaUrl.startsWith("https://")) {
|
|
6807
|
+
const res = await fetch(mediaUrl);
|
|
6808
|
+
const buffer = await res.arrayBuffer();
|
|
6809
|
+
base64 = Buffer.from(buffer).toString("base64");
|
|
6810
|
+
mimeType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
6811
|
+
const urlPath = new URL(mediaUrl).pathname;
|
|
6812
|
+
filename = pathmod.basename(urlPath) || "file";
|
|
6813
|
+
} else {
|
|
6814
|
+
const buf = await fsmod.readFile(mediaUrl);
|
|
6815
|
+
base64 = buf.toString("base64");
|
|
6816
|
+
filename = pathmod.basename(mediaUrl);
|
|
6817
|
+
const ext = pathmod.extname(mediaUrl).toLowerCase().replace(".", "");
|
|
6818
|
+
const extMime = {
|
|
6819
|
+
png: "image/png",
|
|
6820
|
+
jpg: "image/jpeg",
|
|
6821
|
+
jpeg: "image/jpeg",
|
|
6822
|
+
gif: "image/gif",
|
|
6823
|
+
webp: "image/webp"
|
|
6856
6824
|
};
|
|
6825
|
+
mimeType = extMime[ext] ?? "application/octet-stream";
|
|
6826
|
+
}
|
|
6827
|
+
const isImage = mimeType.startsWith("image/");
|
|
6828
|
+
const result2 = isImage ? await client.sendMessage({
|
|
6829
|
+
chatId: to,
|
|
6830
|
+
text: text || void 0,
|
|
6831
|
+
image: { data: base64, mimeType }
|
|
6832
|
+
}) : await client.sendMessage({
|
|
6833
|
+
chatId: to,
|
|
6834
|
+
text: text || void 0,
|
|
6835
|
+
file: { data: base64, filename }
|
|
6836
|
+
});
|
|
6837
|
+
if (!result2.success) {
|
|
6838
|
+
throw new Error(result2.error ?? "Send media failed");
|
|
6857
6839
|
}
|
|
6840
|
+
return {
|
|
6841
|
+
channel: "wechat",
|
|
6842
|
+
messageId: `wechat:${to}:${Date.now()}`
|
|
6843
|
+
};
|
|
6858
6844
|
}
|
|
6859
6845
|
const result = await client.sendMessage({
|
|
6860
6846
|
chatId: to,
|
|
6861
6847
|
text: text || void 0
|
|
6862
6848
|
});
|
|
6849
|
+
if (!result.success) {
|
|
6850
|
+
throw new Error(result.error ?? "Send failed");
|
|
6851
|
+
}
|
|
6863
6852
|
return {
|
|
6864
6853
|
channel: "wechat",
|
|
6865
|
-
|
|
6866
|
-
error: result.error ?? void 0
|
|
6854
|
+
messageId: `wechat:${to}:${Date.now()}`
|
|
6867
6855
|
};
|
|
6868
6856
|
}
|
|
6869
6857
|
},
|
|
@@ -6882,7 +6870,8 @@ var wechatPlugin = {
|
|
|
6882
6870
|
cfg: ctx.cfg
|
|
6883
6871
|
});
|
|
6884
6872
|
},
|
|
6885
|
-
loginWithQrStart: async ({
|
|
6873
|
+
loginWithQrStart: async ({ accountId, force, timeoutMs }) => {
|
|
6874
|
+
const cfg = getWeChatRuntime().config.loadConfig();
|
|
6886
6875
|
const account = resolveWeChatAccount(
|
|
6887
6876
|
cfg,
|
|
6888
6877
|
accountId ?? void 0
|
|
@@ -6892,7 +6881,7 @@ var wechatPlugin = {
|
|
|
6892
6881
|
}
|
|
6893
6882
|
const client = new WeChatClient({ baseUrl: account.serverUrl, token: account.token });
|
|
6894
6883
|
try {
|
|
6895
|
-
const result = await loginStart(client, accountId, { timeoutMs, force });
|
|
6884
|
+
const result = await loginStart(client, accountId ?? DEFAULT_ACCOUNT_ID2, { timeoutMs, force });
|
|
6896
6885
|
return result;
|
|
6897
6886
|
} catch (err) {
|
|
6898
6887
|
return {
|
|
@@ -6900,7 +6889,8 @@ var wechatPlugin = {
|
|
|
6900
6889
|
};
|
|
6901
6890
|
}
|
|
6902
6891
|
},
|
|
6903
|
-
logoutAccount: async ({
|
|
6892
|
+
logoutAccount: async ({ accountId }) => {
|
|
6893
|
+
const cfg = getWeChatRuntime().config.loadConfig();
|
|
6904
6894
|
const account = resolveWeChatAccount(
|
|
6905
6895
|
cfg,
|
|
6906
6896
|
accountId ?? void 0
|
|
@@ -6915,7 +6905,7 @@ var wechatPlugin = {
|
|
|
6915
6905
|
}
|
|
6916
6906
|
},
|
|
6917
6907
|
loginWithQrWait: async ({ accountId, timeoutMs }) => {
|
|
6918
|
-
const result = await loginWait(accountId, { timeoutMs });
|
|
6908
|
+
const result = await loginWait(accountId ?? DEFAULT_ACCOUNT_ID2, { timeoutMs });
|
|
6919
6909
|
return result;
|
|
6920
6910
|
}
|
|
6921
6911
|
},
|
|
@@ -6999,11 +6989,11 @@ Error: ${event.message}`);
|
|
|
6999
6989
|
collectStatusIssues: collectWeChatStatusIssues
|
|
7000
6990
|
},
|
|
7001
6991
|
// ---- Agent tools adapter ----
|
|
7002
|
-
agentTools: ({ cfg }) => {
|
|
6992
|
+
agentTools: (({ cfg }) => {
|
|
7003
6993
|
const account = resolveWeChatAccount(cfg);
|
|
7004
6994
|
if (!account?.serverUrl) return [];
|
|
7005
6995
|
return [createWeChatLoginTool(account)];
|
|
7006
|
-
},
|
|
6996
|
+
}),
|
|
7007
6997
|
// ---- Directory adapter ----
|
|
7008
6998
|
directory: {
|
|
7009
6999
|
self: async ({ cfg }) => {
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-wechat/wechat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"openclaw.plugin.json"
|
|
8
8
|
],
|
|
9
9
|
"devDependencies": {
|
|
10
|
+
"@types/node": "^22",
|
|
10
11
|
"esbuild": "^0.25.0",
|
|
12
|
+
"openclaw": "^2026.2.22",
|
|
13
|
+
"typescript": "^5.4.5",
|
|
11
14
|
"@agent-wechat/shared": "0.1.0"
|
|
12
15
|
},
|
|
13
16
|
"openclaw": {
|
|
@@ -37,6 +40,7 @@
|
|
|
37
40
|
"directory": "packages/openclaw-extension"
|
|
38
41
|
},
|
|
39
42
|
"scripts": {
|
|
40
|
-
"build": "esbuild index.ts --bundle --format=esm --platform=node --outfile=dist/index.js --external:openclaw"
|
|
43
|
+
"build": "esbuild index.ts --bundle --format=esm --platform=node --outfile=dist/index.js --external:openclaw",
|
|
44
|
+
"typecheck": "tsc --noEmit"
|
|
41
45
|
}
|
|
42
46
|
}
|