wezard 2.4.1 → 2.5.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/CLAUDE.md +1 -1
- package/README.md +113 -57
- package/cli/wezard.sh +2 -0
- package/config.example.jsonc +7 -4
- package/dist/cli/wx.js +78 -0
- package/dist/cli/wx.js.map +1 -0
- package/dist/daemon/aibot-media.js +62 -0
- package/dist/daemon/aibot-media.js.map +1 -0
- package/dist/daemon/approval.js +11 -7
- package/dist/daemon/approval.js.map +1 -1
- package/dist/daemon/ask.js +3 -2
- package/dist/daemon/ask.js.map +1 -1
- package/dist/daemon/cc-session.js +27 -4
- package/dist/daemon/cc-session.js.map +1 -1
- package/dist/daemon/chat-log.js +2 -2
- package/dist/daemon/chat-log.js.map +1 -1
- package/dist/daemon/chat-name.js +6 -2
- package/dist/daemon/chat-name.js.map +1 -1
- package/dist/daemon/config-api.js +5 -6
- package/dist/daemon/config-api.js.map +1 -1
- package/dist/daemon/direction.js +53 -0
- package/dist/daemon/direction.js.map +1 -0
- package/dist/daemon/ilink.js +162 -0
- package/dist/daemon/ilink.js.map +1 -0
- package/dist/daemon/inbound.js +57 -14
- package/dist/daemon/inbound.js.map +1 -1
- package/dist/daemon/index.js +297 -65
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/jobs.js +4 -3
- package/dist/daemon/jobs.js.map +1 -1
- package/dist/daemon/last-response.js +6 -3
- package/dist/daemon/last-response.js.map +1 -1
- package/dist/daemon/media.js +108 -0
- package/dist/daemon/media.js.map +1 -0
- package/dist/daemon/mirror-bridge.js +109 -92
- package/dist/daemon/mirror-bridge.js.map +1 -1
- package/dist/daemon/model-select.js +159 -54
- package/dist/daemon/model-select.js.map +1 -1
- package/dist/daemon/notices.js +35 -15
- package/dist/daemon/notices.js.map +1 -1
- package/dist/daemon/outbound.js +2 -1
- package/dist/daemon/outbound.js.map +1 -1
- package/dist/daemon/peers.js +29 -23
- package/dist/daemon/peers.js.map +1 -1
- package/dist/daemon/pending-items.js +1 -1
- package/dist/daemon/pending-items.js.map +1 -1
- package/dist/daemon/reach.js +6 -0
- package/dist/daemon/reach.js.map +1 -0
- package/dist/daemon/receipts.js +145 -3
- package/dist/daemon/receipts.js.map +1 -1
- package/dist/daemon/route.js +11 -4
- package/dist/daemon/route.js.map +1 -1
- package/dist/daemon/spawn-tmux.js +157 -60
- package/dist/daemon/spawn-tmux.js.map +1 -1
- package/dist/daemon/steward-guard.js +48 -7
- package/dist/daemon/steward-guard.js.map +1 -1
- package/dist/daemon/weixin-cmd.js +268 -0
- package/dist/daemon/weixin-cmd.js.map +1 -0
- package/dist/daemon/weixin-port.js +226 -0
- package/dist/daemon/weixin-port.js.map +1 -0
- package/dist/daemon/weixin.js +772 -0
- package/dist/daemon/weixin.js.map +1 -0
- package/dist/daemon/wizard.js +47 -19
- package/dist/daemon/wizard.js.map +1 -1
- package/dist/mcp/server.js +43 -23
- package/dist/mcp/server.js.map +1 -1
- package/dist/shared/chat-http.js +59 -28
- package/dist/shared/chat-http.js.map +1 -1
- package/dist/shared/chat-render.js +9 -1
- package/dist/shared/chat-render.js.map +1 -1
- package/dist/shared/chat-view.js +16 -2
- package/dist/shared/chat-view.js.map +1 -1
- package/dist/shared/cli-backends.js +3 -0
- package/dist/shared/cli-backends.js.map +1 -1
- package/dist/shared/config.js +35 -10
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/json-map-store.js +1 -0
- package/dist/shared/json-map-store.js.map +1 -1
- package/dist/shared/reminder.js +1 -0
- package/dist/shared/reminder.js.map +1 -1
- package/dist/shared/role-render.js +4 -3
- package/dist/shared/role-render.js.map +1 -1
- package/dist/shared/role-view.js +97 -62
- package/dist/shared/role-view.js.map +1 -1
- package/dist/shared/seen-log.js +26 -0
- package/dist/shared/seen-log.js.map +1 -0
- package/dist/shared/session-label.js +84 -31
- package/dist/shared/session-label.js.map +1 -1
- package/dist/shared/turn-state.js +1 -1
- package/dist/shared/turn-state.js.map +1 -1
- package/dist/shared/world.js.map +1 -1
- package/dist/shared/wx-text.js +101 -0
- package/dist/shared/wx-text.js.map +1 -0
- package/dist/svr/index.js +5 -2
- package/dist/svr/index.js.map +1 -1
- package/package.json +6 -2
- package/web/chat.css +26 -5
- package/web/chat.js +128 -63
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// `/wx` 命令、`/wx/*` 路由、绑定落定后的那几件事、微信侧的 SendMedia。
|
|
2
|
+
//
|
|
3
|
+
// 门槛: 二维码就是授权凭据 —— 谁扫了谁就能驱动本机。所以只有审批人 (wxAdmins) 能发起; 判据只有
|
|
4
|
+
// 发话人, 不看在哪个聊天 (对 wezard 单聊群聊都是 chat), 码与进度回发起的那个聊天。本机终端 (`wezard wx bind`) 发起的
|
|
5
|
+
// 要先给审批人推一张确认卡, 点了才出码 —— 口令每个 wizard 都读得到, 光凭口令等于任何 wizard 都能
|
|
6
|
+
// 给本机多开一个微信入口。
|
|
7
|
+
import { mkdirSync, statSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { basename, join } from "node:path";
|
|
10
|
+
import QRCode from "qrcode";
|
|
11
|
+
import { appendUnique, patchJsonc } from "../shared/config-writer.js";
|
|
12
|
+
import { baseOfKey } from "../shared/session-label.js";
|
|
13
|
+
import { shortNameOf } from "../shared/wx-text.js";
|
|
14
|
+
import { applyChatNames, chatNameOf, listChatNames, normChatName, uniqueChatName } from "./chat-name.js";
|
|
15
|
+
import { json, readBody } from "./http.js";
|
|
16
|
+
import { planMedia, kindOf } from "./media.js";
|
|
17
|
+
import { settleName, wizardStore } from "./wizard.js";
|
|
18
|
+
import { WX_MEDIA_MAX } from "./weixin.js";
|
|
19
|
+
export const parseWxCommand = (text) => {
|
|
20
|
+
const m = /^\/wx(?:\s+(\S+))?(?:\s+([\s\S]*))?$/i.exec((text ?? "").trim());
|
|
21
|
+
if (!m)
|
|
22
|
+
return undefined;
|
|
23
|
+
const verb = (m[1] ?? "").toLowerCase();
|
|
24
|
+
const arg = (m[2] ?? "").trim();
|
|
25
|
+
return verb === "" || verb === "list" ? { verb: "list" }
|
|
26
|
+
: verb === "bind" ? { verb: "bind", name: arg }
|
|
27
|
+
: verb === "code" ? { verb: "code", code: arg }
|
|
28
|
+
: verb === "unbind" ? { verb: "unbind", arg }
|
|
29
|
+
: { verb: "help" };
|
|
30
|
+
};
|
|
31
|
+
/** 能发起绑定的人: 审批人名单; 名单空 → defaultChat (是个人的话) 并上 allowFrom 里的人。
|
|
32
|
+
* allowFrom 里的人本就能驱动本机 (所发起的轮次的审批卡也是他点), 绑一个微信号给他不是放出新权限;
|
|
33
|
+
* 只认 defaultChat 会把「defaultChat 指着别人、自己在 allowFrom」的部署里的唯一使用者挡在外面。 */
|
|
34
|
+
export const wxAdmins = (cfg) => cfg.approval.approvers.length ? cfg.approval.approvers
|
|
35
|
+
: [...new Set([...(cfg.defaultChat?.startsWith("user:") ? [cfg.defaultChat] : []), ...cfg.wrc.allowFrom.filter((p) => p.startsWith("user:"))])];
|
|
36
|
+
export const isWxAdmin = (cfg, userPrincipal) => wxAdmins(cfg).includes(userPrincipal);
|
|
37
|
+
const ago = (t) => {
|
|
38
|
+
if (!t)
|
|
39
|
+
return "—";
|
|
40
|
+
const s = Math.round((Date.now() - t) / 1000);
|
|
41
|
+
return s < 90 ? `${s}s 前` : s < 5400 ? `${Math.round(s / 60)} 分钟前` : s < 172800 ? `${Math.round(s / 3600)} 小时前` : `${Math.round(s / 86400)} 天前`;
|
|
42
|
+
};
|
|
43
|
+
export const renderAccounts = (cfg, xs) => xs.length === 0
|
|
44
|
+
? "[wezard] 还没有绑定微信。发 `/wx bind [群名]` 扫码绑定 (仅审批人)。"
|
|
45
|
+
: [
|
|
46
|
+
`*微信 ClawBot* (${xs.length}/${cfg.weixin.maxAccounts}${cfg.weixin.enabled ? "" : " · ⚠️ 通道未开启"})`,
|
|
47
|
+
...xs.map((a, i) => {
|
|
48
|
+
const name = chatNameOf(cfg, `chat:${a.chatId}`) || a.chatId;
|
|
49
|
+
const ctx = a.ctx ? `额度 ${Math.max(0, cfg.weixin.sendCap - a.ctx.used)}/${cfg.weixin.sendCap}` : "无 token";
|
|
50
|
+
return `${i + 1}. \`${name}\` ${a.state === "live" ? "🟢" : "🔴 掉线"} · 上次说话 ${ago(a.lastInAt)} · ${ctx}${a.outbox.length ? ` · 📬 压着 ${a.outbox.length}` : ""} · 发 ${a.sent ?? 0} / 败 ${a.failed ?? 0}`;
|
|
51
|
+
}),
|
|
52
|
+
"",
|
|
53
|
+
"`/wx bind [群名]` 绑新号 · `/wx unbind <序号|群名>` 解绑",
|
|
54
|
+
].join("\n");
|
|
55
|
+
const HELP = [
|
|
56
|
+
"*/wx* 微信 ClawBot (仅审批人; 二维码与进度回发起的这个聊天)",
|
|
57
|
+
"`/wx` 列出已绑定的微信",
|
|
58
|
+
"`/wx bind [群名]` 出二维码, 用要绑定的那个微信扫 (约 2 分钟有效)",
|
|
59
|
+
"`/wx code <配对码>` 微信上显示配对码时回填",
|
|
60
|
+
"`/wx unbind <序号|群名>` 解绑 (群聊与 wizard 保留)",
|
|
61
|
+
].join("\n");
|
|
62
|
+
const viewLine = (v) => v.status === "qr" ? `📱 ${v.message}`
|
|
63
|
+
: v.status === "scaned" ? "👀 已扫码, 请在微信里点「确认」"
|
|
64
|
+
: v.status === "need_code" ? `🔢 ${v.message}: 发 \`/wx code <配对码>\``
|
|
65
|
+
: v.status === "done" ? `✅ 微信已绑定为群聊 \`${v.name}\` —— 去微信里先给「微信 ClawBot」发一句话 (机器人在你开口前不能说话); 之后像企微群一样用, \`.名字\` 点名 wizard`
|
|
66
|
+
: v.status === "already" ? `ℹ️ ${v.message}`
|
|
67
|
+
: `❌ 绑定失败: ${v.message}`;
|
|
68
|
+
/** 起群名 (只填空)、进 allowFrom、生默认 wizard —— 与企微群聊首条消息走的是同一套。 */
|
|
69
|
+
export const makeOnBound = ({ cfg, sourcePath, log, hasSession, newSession }) => async (acct, wantName) => {
|
|
70
|
+
const base = `chat:${acct.chatId}`;
|
|
71
|
+
const have = chatNameOf(cfg, base);
|
|
72
|
+
const name = have || (() => {
|
|
73
|
+
const want = normChatName(wantName).replace(/[^\p{L}\p{N}_-]+/gu, "-").replace(/^-+|-+$/g, "").slice(0, 32) || shortNameOf(acct.userId);
|
|
74
|
+
const taken = new Set(listChatNames(cfg).map((c) => c.name.toLowerCase()));
|
|
75
|
+
const picked = uniqueChatName(want, taken);
|
|
76
|
+
applyChatNames(cfg, sourcePath, { [base]: picked });
|
|
77
|
+
return picked;
|
|
78
|
+
})();
|
|
79
|
+
if (!cfg.wrc.allowFrom.includes(base)) {
|
|
80
|
+
cfg.wrc.allowFrom.push(base);
|
|
81
|
+
try {
|
|
82
|
+
appendUnique(sourcePath, ["wrc", "allowFrom"], base);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
log.error({ err: e.message }, "weixin allowFrom write failed");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!hasSession(base)) {
|
|
89
|
+
const wiz = settleName(wizardStore(), name, base);
|
|
90
|
+
const r = await newSession(base, wiz || name);
|
|
91
|
+
if (!r.ok)
|
|
92
|
+
log.warn({ base, reason: r.reason }, "weixin default wizard spawn failed (首条消息时会再开)");
|
|
93
|
+
}
|
|
94
|
+
return name;
|
|
95
|
+
};
|
|
96
|
+
/** 解绑时撤销授权 (群名与 wizard 留着 —— 历史还在 rolepage 上)。 */
|
|
97
|
+
export const revokeAllow = (cfg, sourcePath, chatId) => {
|
|
98
|
+
const base = `chat:${chatId}`;
|
|
99
|
+
if (!cfg.wrc.allowFrom.includes(base))
|
|
100
|
+
return;
|
|
101
|
+
cfg.wrc.allowFrom = cfg.wrc.allowFrom.filter((x) => x !== base);
|
|
102
|
+
patchJsonc(sourcePath, [{ path: ["wrc", "allowFrom"], value: cfg.wrc.allowFrom }]);
|
|
103
|
+
};
|
|
104
|
+
// ── 二维码 ───────────────────────────────────────────────────────────
|
|
105
|
+
export const qrPng = async (content) => {
|
|
106
|
+
const dir = join(tmpdir(), "wezard-wx");
|
|
107
|
+
mkdirSync(dir, { recursive: true });
|
|
108
|
+
const path = join(dir, `qr-${Date.now().toString(36)}.png`);
|
|
109
|
+
writeFileSync(path, await QRCode.toBuffer(content, { type: "png", width: 420, margin: 2 }));
|
|
110
|
+
return path;
|
|
111
|
+
};
|
|
112
|
+
/** 解绑参数: 序号 / 群名 / chat:wx_… / wx_… → chatId。 */
|
|
113
|
+
const pickAccount = (cfg, xs, arg) => {
|
|
114
|
+
const n = Number(arg);
|
|
115
|
+
if (Number.isInteger(n) && n >= 1)
|
|
116
|
+
return xs[n - 1];
|
|
117
|
+
const a = arg.replace(/^chat:/, "").toLowerCase();
|
|
118
|
+
return xs.find((x) => x.chatId.toLowerCase() === a || chatNameOf(cfg, `chat:${x.chatId}`).toLowerCase() === a);
|
|
119
|
+
};
|
|
120
|
+
/** 企微侧一次绑定的进度推送: 新码发图, 关键状态各一句。 */
|
|
121
|
+
export const wecomBindSink = (d, to) => {
|
|
122
|
+
let lastQr = "";
|
|
123
|
+
let last = "";
|
|
124
|
+
return (v) => {
|
|
125
|
+
if (v.status === "qr" && v.qrUrl && v.qrUrl !== lastQr) {
|
|
126
|
+
lastQr = v.qrUrl;
|
|
127
|
+
void (async () => {
|
|
128
|
+
try {
|
|
129
|
+
const r = await d.sendWecomMedia(to, { path: await qrPng(v.qrUrl), kind: "image", name: "weixin-bind.png" });
|
|
130
|
+
if (!r.ok)
|
|
131
|
+
d.log.warn({ reason: r.reason }, "weixin qr image failed");
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
d.log.warn({ err: e.message }, "weixin qr render failed");
|
|
135
|
+
}
|
|
136
|
+
d.sendWecom(to, `📱 ${v.refresh ? `二维码已换新 (${v.refresh}/3)。` : ""}用**要绑定的那个人的微信**扫上图 (约 2 分钟有效)。手机上只有这一台时: 长按图片存到相册, 微信「扫一扫」右上角选相册。\n\n扫不了也可以在微信里打开: ${v.qrUrl}`);
|
|
137
|
+
})();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const line = v.status === "qr" ? "" : viewLine(v);
|
|
141
|
+
if (line && line !== last) {
|
|
142
|
+
last = line;
|
|
143
|
+
d.sendWecom(to, line);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
export const makeWxCommands = (d) => async (ctx, cmd) => {
|
|
148
|
+
const { cfg, wx } = d;
|
|
149
|
+
if (!isWxAdmin(cfg, ctx.sender)) {
|
|
150
|
+
d.log.info({ sender: ctx.sender, chat: ctx.chat, admins: wxAdmins(cfg) }, "/wx rejected: not an admin");
|
|
151
|
+
return ctx.reply(`[wezard] \`/wx\` 只有审批人能用 (approval.approvers; 空则 defaultChat 与 allowFrom 里的人), 你是 \`${ctx.sender}\``);
|
|
152
|
+
}
|
|
153
|
+
if (cmd.verb === "help")
|
|
154
|
+
return ctx.reply(HELP);
|
|
155
|
+
if (cmd.verb === "list")
|
|
156
|
+
return ctx.reply(renderAccounts(cfg, wx.list()));
|
|
157
|
+
if (cmd.verb === "bind") {
|
|
158
|
+
if (!cfg.weixin.enabled)
|
|
159
|
+
return ctx.reply("[wezard] 微信通道未开启: 先 `config_set weixin.enabled=true` (放权项, 会推卡确认), reload 后再 `/wx bind`");
|
|
160
|
+
const r = wx.startBind(ctx.sender, cmd.name, wecomBindSink(d, ctx.chat), ctx.chat);
|
|
161
|
+
return r.ok ? undefined : ctx.reply(`[wezard] ${r.reason}`);
|
|
162
|
+
}
|
|
163
|
+
if (cmd.verb === "code") {
|
|
164
|
+
const r = wx.submitCode(ctx.sender, cmd.code);
|
|
165
|
+
return ctx.reply(r.ok ? "🔢 配对码已提交, 校验中…" : `[wezard] ${r.reason}`);
|
|
166
|
+
}
|
|
167
|
+
const a = pickAccount(cfg, wx.list(), cmd.arg);
|
|
168
|
+
if (!a)
|
|
169
|
+
return ctx.reply(`[wezard] 认不出要解绑哪个: \`${cmd.arg || "(空)"}\`\n\n${renderAccounts(cfg, wx.list())}`);
|
|
170
|
+
const r = wx.unbind(a.chatId);
|
|
171
|
+
if (r.ok)
|
|
172
|
+
revokeAllow(cfg, d.sourcePath, a.chatId);
|
|
173
|
+
return ctx.reply(r.ok ? `🗑️ 已解绑 \`${chatNameOf(cfg, `chat:${a.chatId}`) || a.chatId}\` (群聊、wizard 与记录保留; 微信客户端里那个对话可能还在, 但已无人应答)` : `[wezard] ${r.reason}`);
|
|
174
|
+
};
|
|
175
|
+
// inbound 的 gate 只认这一个钩子, 不改 installInboundRouter 的签名。
|
|
176
|
+
let handler;
|
|
177
|
+
export const bindWxCommands = (fn) => { handler = fn; };
|
|
178
|
+
export const wxCommandHandler = () => handler;
|
|
179
|
+
/** 全部要出示 daemon 口令 (index.ts 套 guarded); rolepage 读的是推送的 facts, 不走这里。 */
|
|
180
|
+
export const wxRoutes = (d) => ({
|
|
181
|
+
"GET /wx/list": (_req, res) => json(res, 200, {
|
|
182
|
+
ok: true,
|
|
183
|
+
enabled: d.cfg.weixin.enabled,
|
|
184
|
+
max: d.cfg.weixin.maxAccounts,
|
|
185
|
+
accounts: d.wx.list().map((a) => ({
|
|
186
|
+
chatId: a.chatId, name: chatNameOf(d.cfg, `chat:${a.chatId}`), state: a.state, boundBy: a.boundBy, boundAt: a.boundAt,
|
|
187
|
+
lastInAt: a.lastInAt ?? 0, lastOutAt: a.lastOutAt ?? 0, held: a.outbox.length,
|
|
188
|
+
budget: a.ctx ? Math.max(0, d.cfg.weixin.sendCap - a.ctx.used) : 0, sent: a.sent ?? 0, failed: a.failed ?? 0,
|
|
189
|
+
pausedUntil: a.pausedUntil ?? 0,
|
|
190
|
+
})),
|
|
191
|
+
}),
|
|
192
|
+
"POST /wx/bind": async (req, res) => {
|
|
193
|
+
const b = (await readBody(req));
|
|
194
|
+
const name = (b.name ?? "").trim();
|
|
195
|
+
if (!d.cfg.weixin.enabled) {
|
|
196
|
+
json(res, 400, { ok: false, reason: "微信通道未开启 (weixin.enabled=false)" });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const yes = await d.confirmBind(name).catch((e) => { json(res, 503, { ok: false, reason: `确认卡发不出去: ${e.message}` }); return undefined; });
|
|
200
|
+
if (yes === undefined)
|
|
201
|
+
return;
|
|
202
|
+
if (!yes) {
|
|
203
|
+
json(res, 403, { ok: false, reason: "审批人没有同意 (拒绝或超时)" });
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const r = d.wx.startBind("cli", name, () => undefined, "cli");
|
|
207
|
+
json(res, r.ok ? 200 : 400, r);
|
|
208
|
+
},
|
|
209
|
+
"GET /wx/bind/status": (_req, res, url) => {
|
|
210
|
+
const v = d.wx.bindOf(url.searchParams.get("id") || "cli");
|
|
211
|
+
json(res, v ? 200 : 404, v ? { ok: true, view: v } : { ok: false, reason: "no such bind" });
|
|
212
|
+
},
|
|
213
|
+
"POST /wx/bind/code": async (req, res) => {
|
|
214
|
+
const b = (await readBody(req));
|
|
215
|
+
const r = d.wx.submitCode("cli", (b.code ?? "").trim());
|
|
216
|
+
json(res, r.ok ? 200 : 400, r);
|
|
217
|
+
},
|
|
218
|
+
"POST /wx/unbind": async (req, res) => {
|
|
219
|
+
const b = (await readBody(req));
|
|
220
|
+
const a = pickAccount(d.cfg, d.wx.list(), (b.chat ?? "").trim());
|
|
221
|
+
if (!a) {
|
|
222
|
+
json(res, 404, { ok: false, reason: "no such account" });
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const r = d.wx.unbind(a.chatId);
|
|
226
|
+
if (r.ok)
|
|
227
|
+
revokeAllow(d.cfg, d.sourcePath, a.chatId);
|
|
228
|
+
json(res, r.ok ? 200 : 400, r);
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
// ── 微信侧 SendMedia ─────────────────────────────────────────────────
|
|
232
|
+
const WX_KIND = { image: "image", video: "video", file: "file", voice: "file" };
|
|
233
|
+
/** 微信不发语音条 (官方插件也不发, 社区: 发出后客户端不显示) → 当文件; 上限 WX_MEDIA_MAX。 */
|
|
234
|
+
export const planWxMedia = (spec) => {
|
|
235
|
+
if (!spec.path.startsWith("/"))
|
|
236
|
+
return { ok: false, reason: `path 要写绝对路径: ${spec.path}` };
|
|
237
|
+
const st = (() => { try {
|
|
238
|
+
return statSync(spec.path);
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return undefined;
|
|
242
|
+
} })();
|
|
243
|
+
if (!st?.isFile())
|
|
244
|
+
return { ok: false, reason: `文件不存在或不是普通文件: ${spec.path}` };
|
|
245
|
+
const name = spec.name?.trim() || basename(spec.path);
|
|
246
|
+
const bytes = Number(st.size);
|
|
247
|
+
if (bytes > WX_MEDIA_MAX)
|
|
248
|
+
return { ok: false, reason: `微信侧单文件上限 ${WX_MEDIA_MAX / 1024 / 1024}MB, 「${name}」有 ${(bytes / 1024 / 1024).toFixed(1)}MB` };
|
|
249
|
+
const kind = spec.kind ?? kindOf(name);
|
|
250
|
+
return { ok: true, kind: kind === "voice" ? "file" : kind, name, bytes };
|
|
251
|
+
};
|
|
252
|
+
export const weixinSendMedia = (wx) => async (target, spec) => {
|
|
253
|
+
const chatId = baseOfKey(target).replace(/^chat:/, "");
|
|
254
|
+
const plan = planWxMedia(spec);
|
|
255
|
+
if (!plan.ok)
|
|
256
|
+
return plan;
|
|
257
|
+
const r = await wx.sendMedia(chatId, { path: spec.path, kind: WX_KIND[plan.kind], name: plan.name });
|
|
258
|
+
return r.ok ? plan : r;
|
|
259
|
+
};
|
|
260
|
+
/** 按收件聊天分流: 绑定过的微信群聊走微信, 其余企微。 */
|
|
261
|
+
export const routeSendMedia = (wx, wxSend, aibot) => {
|
|
262
|
+
const isWx = (t) => wx.owns(baseOfKey(t).replace(/^chat:/, ""));
|
|
263
|
+
return {
|
|
264
|
+
send: (t, s) => (isWx(t) ? wxSend(t, s) : aibot(t, s)),
|
|
265
|
+
plan: (t, s) => (isWx(t) ? planWxMedia(s) : planMedia(s)),
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
//# sourceMappingURL=weixin-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weixin-cmd.js","sourceRoot":"","sources":["../../daemon/weixin-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { renderCard, renderAck, choicesOf, parseMenuReply, clickOf, mintCode, wxMarkdown, WX_REQ as REQ } from "../shared/wx-text.js";
|
|
2
|
+
import { getPending } from "./pending.js";
|
|
3
|
+
const CARD_TTL_MS = 24 * 3600_000;
|
|
4
|
+
/** `wx:<chatId>:<n>` → chatId; 不是微信帧返回 undefined。 */
|
|
5
|
+
const chatOfFrame = (frame) => {
|
|
6
|
+
const id = frame?.headers?.req_id;
|
|
7
|
+
return typeof id === "string" && id.startsWith(REQ) ? id.slice(REQ.length).split(":")[0] : undefined;
|
|
8
|
+
};
|
|
9
|
+
const ack = (reqId) => ({ headers: { req_id: reqId }, errcode: 0, errmsg: "ok" });
|
|
10
|
+
export const installWeixinPort = (client, wx, log) => {
|
|
11
|
+
const cards = new Map();
|
|
12
|
+
const live = (chatId) => {
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
const xs = (cards.get(chatId) ?? []).filter((c) => now - c.at < CARD_TTL_MS && (!c.tracked || !!getPending(c.taskId)));
|
|
15
|
+
cards.set(chatId, xs);
|
|
16
|
+
return xs;
|
|
17
|
+
};
|
|
18
|
+
let seq = 0;
|
|
19
|
+
const reqId = (chatId) => `${REQ}${chatId}:${Date.now().toString(36)}${(seq++).toString(36)}`;
|
|
20
|
+
const isWx = (chatId) => !!chatId && wx.owns(chatId);
|
|
21
|
+
// ── 出站 ──
|
|
22
|
+
const text = (chatId, md) => {
|
|
23
|
+
const out = wxMarkdown(md);
|
|
24
|
+
if (out)
|
|
25
|
+
wx.send(chatId, out);
|
|
26
|
+
};
|
|
27
|
+
const card = (chatId, c) => {
|
|
28
|
+
const choices = choicesOf(c);
|
|
29
|
+
const taskId = c.task_id ?? "";
|
|
30
|
+
// 同一 task_id 重发 (reload 续接、改卡重推) 顶替旧条目, 沿用旧短码 —— 人手里那张菜单仍然作数。
|
|
31
|
+
const open = live(chatId);
|
|
32
|
+
const prev = taskId ? open.find((x) => x.taskId === taskId) : undefined;
|
|
33
|
+
const code = prev?.code ?? mintCode(new Set(open.map((x) => x.code)));
|
|
34
|
+
if (choices.kind !== "none") {
|
|
35
|
+
cards.set(chatId, [...open.filter((x) => x !== prev), { code, taskId, choices, cardType: c.card_type, at: Date.now(), tracked: !!taskId && !!getPending(taskId) }]);
|
|
36
|
+
}
|
|
37
|
+
wx.send(chatId, renderCard(c, code), { card: true });
|
|
38
|
+
};
|
|
39
|
+
const body = (chatId, b) => {
|
|
40
|
+
const t = b.msgtype;
|
|
41
|
+
if (t === "markdown")
|
|
42
|
+
return text(chatId, String(b.markdown?.content ?? ""));
|
|
43
|
+
if (t === "template_card")
|
|
44
|
+
return card(chatId, b.template_card);
|
|
45
|
+
if (t === "stream") {
|
|
46
|
+
const st = b.stream;
|
|
47
|
+
return st.finish ? (wx.typing(chatId, false), text(chatId, st.content ?? "")) : wx.typing(chatId, true);
|
|
48
|
+
}
|
|
49
|
+
log.warn({ chatId, msgtype: t }, "weixin port: unsupported outbound msgtype — dropped");
|
|
50
|
+
};
|
|
51
|
+
const orig = {
|
|
52
|
+
sendMessage: client.sendMessage.bind(client),
|
|
53
|
+
reply: client.reply.bind(client),
|
|
54
|
+
replyStream: client.replyStream.bind(client),
|
|
55
|
+
replyStreamNonBlocking: client.replyStreamNonBlocking.bind(client),
|
|
56
|
+
replyStreamWithCard: client.replyStreamWithCard.bind(client),
|
|
57
|
+
replyTemplateCard: client.replyTemplateCard.bind(client),
|
|
58
|
+
updateTemplateCard: client.updateTemplateCard.bind(client),
|
|
59
|
+
replyWelcome: client.replyWelcome.bind(client),
|
|
60
|
+
replyMedia: client.replyMedia.bind(client),
|
|
61
|
+
sendMediaMessage: client.sendMediaMessage.bind(client),
|
|
62
|
+
hasPendingReplyAck: client.hasPendingReplyAck.bind(client),
|
|
63
|
+
downloadFile: client.downloadFile.bind(client),
|
|
64
|
+
};
|
|
65
|
+
client.sendMessage = async (chatid, b) => (isWx(chatid) ? (body(chatid, b), ack(reqId(chatid))) : orig.sendMessage(chatid, b));
|
|
66
|
+
client.reply = async (frame, b, cmd) => {
|
|
67
|
+
const c = chatOfFrame(frame);
|
|
68
|
+
return isWx(c) ? (body(c, b), ack(frame.headers.req_id)) : orig.reply(frame, b, cmd);
|
|
69
|
+
};
|
|
70
|
+
const stream = (c, content, finish) => {
|
|
71
|
+
if (finish) {
|
|
72
|
+
wx.typing(c, false);
|
|
73
|
+
text(c, content);
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
wx.typing(c, true);
|
|
77
|
+
};
|
|
78
|
+
client.replyStream = async (frame, id, content, finish, msgItem, feedback) => {
|
|
79
|
+
const c = chatOfFrame(frame);
|
|
80
|
+
return isWx(c) ? (stream(c, content, finish), ack(frame.headers.req_id)) : orig.replyStream(frame, id, content, finish, msgItem, feedback);
|
|
81
|
+
};
|
|
82
|
+
client.replyStreamNonBlocking = async (frame, id, content, finish, msgItem, feedback) => {
|
|
83
|
+
const c = chatOfFrame(frame);
|
|
84
|
+
return isWx(c) ? (stream(c, content, finish), ack(frame.headers.req_id)) : orig.replyStreamNonBlocking(frame, id, content, finish, msgItem, feedback);
|
|
85
|
+
};
|
|
86
|
+
client.replyStreamWithCard = async (frame, id, content, finish, options) => {
|
|
87
|
+
const c = chatOfFrame(frame);
|
|
88
|
+
if (!isWx(c))
|
|
89
|
+
return orig.replyStreamWithCard(frame, id, content, finish, options);
|
|
90
|
+
stream(c, content, finish);
|
|
91
|
+
if (options?.templateCard)
|
|
92
|
+
card(c, options.templateCard);
|
|
93
|
+
return ack(frame.headers.req_id);
|
|
94
|
+
};
|
|
95
|
+
client.replyTemplateCard = async (frame, c0, feedback) => {
|
|
96
|
+
const c = chatOfFrame(frame);
|
|
97
|
+
return isWx(c) ? (card(c, c0), ack(frame.headers.req_id)) : orig.replyTemplateCard(frame, c0, feedback);
|
|
98
|
+
};
|
|
99
|
+
// 点击 (数字回复) 之后的改卡 → 一行回执, 并把这张卡从待答表里摘掉。
|
|
100
|
+
client.updateTemplateCard = async (frame, c0, userids) => {
|
|
101
|
+
const c = chatOfFrame(frame);
|
|
102
|
+
if (!isWx(c))
|
|
103
|
+
return orig.updateTemplateCard(frame, c0, userids);
|
|
104
|
+
// 查原表而不是 live(): 点击一 resolve, 这张卡就已不在待决表里了, 回执还要用它的短码。
|
|
105
|
+
const open = cards.get(c) ?? [];
|
|
106
|
+
const hit = open.find((x) => x.taskId && x.taskId === c0.task_id);
|
|
107
|
+
if (hit)
|
|
108
|
+
cards.set(c, open.filter((x) => x !== hit));
|
|
109
|
+
wx.send(c, renderAck(c0, hit?.code ?? "卡片"), { card: true });
|
|
110
|
+
return ack(frame.headers.req_id);
|
|
111
|
+
};
|
|
112
|
+
client.replyWelcome = async (frame, b) => (isWx(chatOfFrame(frame)) ? ack(frame.headers.req_id) : orig.replyWelcome(frame, b));
|
|
113
|
+
// 媒体走 SendMedia (index.ts 按聊天分流), 不经这两个口; 走到这里说明有人绕过了它。
|
|
114
|
+
client.replyMedia = async (frame, kind, mediaId, video) => {
|
|
115
|
+
const c = chatOfFrame(frame);
|
|
116
|
+
if (!isWx(c))
|
|
117
|
+
return orig.replyMedia(frame, kind, mediaId, video);
|
|
118
|
+
log.warn({ chatId: c, kind }, "weixin port: replyMedia bypassed SendMedia — dropped");
|
|
119
|
+
return ack(frame.headers.req_id);
|
|
120
|
+
};
|
|
121
|
+
client.sendMediaMessage = async (chatid, kind, mediaId, video) => {
|
|
122
|
+
if (!isWx(chatid))
|
|
123
|
+
return orig.sendMediaMessage(chatid, kind, mediaId, video);
|
|
124
|
+
log.warn({ chatId: chatid, kind }, "weixin port: sendMediaMessage bypassed SendMedia — dropped");
|
|
125
|
+
return ack(reqId(chatid));
|
|
126
|
+
};
|
|
127
|
+
client.hasPendingReplyAck = (frame) => (isWx(chatOfFrame(frame)) ? false : orig.hasPendingReplyAck(frame));
|
|
128
|
+
client.downloadFile = async (url, aesKey) => (url.startsWith("wxcdn:") ? wx.download(url) : orig.downloadFile(url, aesKey));
|
|
129
|
+
// ── 入站 ──
|
|
130
|
+
const frameOf = (m, extra) => ({
|
|
131
|
+
cmd: "aibot_msg_callback",
|
|
132
|
+
headers: { req_id: reqId(m.chatId) },
|
|
133
|
+
body: {
|
|
134
|
+
msgid: m.msgId,
|
|
135
|
+
aibotid: "weixin",
|
|
136
|
+
chatid: m.chatId,
|
|
137
|
+
chattype: "group",
|
|
138
|
+
from: { userid: m.chatId },
|
|
139
|
+
create_time: Math.floor(m.at / 1000),
|
|
140
|
+
...(m.quote ? { quote: { msgtype: "text", text: { content: m.quote } } } : {}),
|
|
141
|
+
...extra,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
const emit = (name, f) => {
|
|
145
|
+
try {
|
|
146
|
+
const e = client.emit.bind(client);
|
|
147
|
+
e("message", f);
|
|
148
|
+
e(name, f);
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
log.error({ name, err: e.message }, "weixin port: inbound listener threw");
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
// 人回的是菜单数字 → 合成点击; 返回 true = 已消费, 不再当普通消息派给 wizard。
|
|
155
|
+
// 拿不准是在答哪张卡 (短码对不上、多张待答又没带短码) 就不吞: 照常交给 wizard ——
|
|
156
|
+
// 「k7q 1」「top 3」也可能就是一句话。
|
|
157
|
+
const answerCard = (m) => {
|
|
158
|
+
if (m.images.length || m.files.length)
|
|
159
|
+
return false;
|
|
160
|
+
const r = parseMenuReply(m.text);
|
|
161
|
+
const open = live(m.chatId);
|
|
162
|
+
if (!r || open.length === 0)
|
|
163
|
+
return false;
|
|
164
|
+
const target = r.code ? open.find((x) => x.code === r.code) : open.length === 1 ? open[0] : undefined;
|
|
165
|
+
if (!target) {
|
|
166
|
+
if (!r.code)
|
|
167
|
+
wx.send(m.chatId, `有 ${open.length} 张待答卡 (${open.map((x) => x.code).join(" / ")}), 要作答请带短码, 如 "${open[0].code} 1" —— 刚才那句已照常转给 wizard`);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
const click = clickOf(target.choices, r.picks);
|
|
171
|
+
if (!click) {
|
|
172
|
+
wx.send(m.chatId, `${target.code}: 选项不对, 请回菜单里的编号${target.choices.kind === "vote" && target.choices.multi ? " (可多个, 空格隔开)" : ""}`);
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
// 投票卡提交后企微不改卡 —— 这里先摘; 按钮卡等 updateTemplateCard 回执时摘。
|
|
176
|
+
if (target.choices.kind === "vote")
|
|
177
|
+
cards.set(m.chatId, open.filter((x) => x !== target));
|
|
178
|
+
const tce = { card_type: target.cardType, event_key: click.eventKey, task_id: target.taskId, ...(click.selected ? { selected_items: click.selected } : {}) };
|
|
179
|
+
const f = {
|
|
180
|
+
cmd: "aibot_event_callback",
|
|
181
|
+
headers: { req_id: reqId(m.chatId) },
|
|
182
|
+
body: {
|
|
183
|
+
msgid: m.msgId, aibotid: "weixin", chatid: m.chatId, chattype: "group", from: { userid: m.chatId },
|
|
184
|
+
create_time: Math.floor(m.at / 1000), msgtype: "event",
|
|
185
|
+
event: { eventtype: "template_card_event", ...tce, template_card_event: tce },
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
log.info({ chatId: m.chatId, code: target.code, eventKey: click.eventKey }, "weixin menu reply → card event");
|
|
189
|
+
try {
|
|
190
|
+
const e = client.emit.bind(client);
|
|
191
|
+
e("event", f);
|
|
192
|
+
e("event.template_card_event", f);
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
log.error({ err: e.message }, "weixin port: card listener threw");
|
|
196
|
+
}
|
|
197
|
+
return true;
|
|
198
|
+
};
|
|
199
|
+
wx.onInbound((m) => {
|
|
200
|
+
if (answerCard(m))
|
|
201
|
+
return;
|
|
202
|
+
const [file] = m.files;
|
|
203
|
+
if (file) {
|
|
204
|
+
emit(`message.${file.kind}`, frameOf(m, { msgtype: file.kind, [file.kind]: { url: file.ref } }));
|
|
205
|
+
// 文件之外同一条里还有字 / 图: 照常再走一遍 (微信一条消息通常只有一项, 这是兜底)。
|
|
206
|
+
if (!m.text && !m.images.length)
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (m.images.length && !m.text && m.images.length === 1) {
|
|
210
|
+
emit("message.image", frameOf(m, { msgtype: "image", image: { url: m.images[0] } }));
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (m.images.length) {
|
|
214
|
+
const items = [
|
|
215
|
+
...(m.text ? [{ msgtype: "text", text: { content: m.text } }] : []),
|
|
216
|
+
...m.images.map((u) => ({ msgtype: "image", image: { url: u } })),
|
|
217
|
+
];
|
|
218
|
+
emit("message.mixed", frameOf(m, { msgtype: "mixed", mixed: { msg_item: items } }));
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (m.text)
|
|
222
|
+
emit("message.text", frameOf(m, { msgtype: "text", text: { content: m.text } }));
|
|
223
|
+
});
|
|
224
|
+
return { openCards: (chatId) => live(chatId) };
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=weixin-port.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weixin-port.js","sourceRoot":"","sources":["../../daemon/weixin-port.ts"],"names":[],"mappings":"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"}
|