


























@@ -2,6 +2,12 @@ import type { ChannelAgentTool } from "openclaw/plugin-sdk/channel-contract";
22import { Type } from "typebox";
33import { startWebLoginWithQr, waitForWebLogin } from "../login-qr-api.js";
445+const QR_DATA_URL_MAX_LENGTH = 16_384;
6+7+function readOptionalString(value: unknown): string | undefined {
8+return typeof value === "string" && value.trim() ? value : undefined;
9+}
10+511export function createWhatsAppLoginTool(): ChannelAgentTool {
612return {
713label: "WhatsApp Login",
@@ -17,23 +23,64 @@ export function createWhatsAppLoginTool(): ChannelAgentTool {
1723}),
1824timeoutMs: Type.Optional(Type.Number()),
1925force: Type.Optional(Type.Boolean()),
26+accountId: Type.Optional(Type.String()),
27+currentQrDataUrl: Type.Optional(
28+Type.String({
29+maxLength: QR_DATA_URL_MAX_LENGTH,
30+pattern: "^data:image/png;base64,",
31+}),
32+),
2033}),
2134execute: async (_toolCallId, args) => {
35+const renderQrReply = (params: {
36+message: string;
37+qrDataUrl: string;
38+connected?: boolean;
39+}) => {
40+const text = [
41+params.message,
42+"",
43+"Open WhatsApp → Linked Devices and scan:",
44+"",
45+``,
46+].join("\n");
47+return {
48+content: [{ type: "text" as const, text }],
49+details: {
50+connected: params.connected ?? false,
51+qr: true,
52+},
53+};
54+};
55+2256const action = (args as { action?: string })?.action ?? "start";
57+const accountId = readOptionalString((args as { accountId?: unknown }).accountId);
2358if (action === "wait") {
2459const result = await waitForWebLogin({
60+ accountId,
2561timeoutMs:
2662typeof (args as { timeoutMs?: unknown }).timeoutMs === "number"
2763 ? (args as { timeoutMs?: number }).timeoutMs
2864 : undefined,
65+currentQrDataUrl: readOptionalString(
66+(args as { currentQrDataUrl?: unknown }).currentQrDataUrl,
67+),
2968});
69+if (result.qrDataUrl) {
70+return renderQrReply({
71+message: result.message,
72+qrDataUrl: result.qrDataUrl,
73+connected: result.connected,
74+});
75+}
3076return {
3177content: [{ type: "text", text: result.message }],
3278details: { connected: result.connected },
3379};
3480}
35813682const result = await startWebLoginWithQr({
83+ accountId,
3784timeoutMs:
3885typeof (args as { timeoutMs?: unknown }).timeoutMs === "number"
3986 ? (args as { timeoutMs?: number }).timeoutMs
@@ -56,17 +103,11 @@ export function createWhatsAppLoginTool(): ChannelAgentTool {
56103};
57104}
5810559-const text = [
60-result.message,
61-"",
62-"Open WhatsApp → Linked Devices and scan:",
63-"",
64-``,
65-].join("\n");
66-return {
67-content: [{ type: "text", text }],
68-details: { qr: true },
69-};
106+return renderQrReply({
107+message: result.message,
108+qrDataUrl: result.qrDataUrl,
109+connected: result.connected,
110+});
70111},
71112};
72113}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。