Merge 9ed0f1be56 into fa9ec6e854
This commit is contained in:
commit
48008a1e73
@ -40,6 +40,27 @@ openclaw channels login --channel whatsapp
|
||||
openclaw channels logout --channel whatsapp
|
||||
```
|
||||
|
||||
### JSON mode (programmatic)
|
||||
|
||||
For programmatic use (e.g., web dashboards, hosting platforms), use `--json` to get QR data as JSON instead of terminal output:
|
||||
|
||||
```bash
|
||||
moltbot channels login --channel whatsapp --json --timeout 60000
|
||||
```
|
||||
|
||||
This outputs two JSON objects:
|
||||
1. Initial response with QR data:
|
||||
```json
|
||||
{"status":"pending","qrDataUrl":"data:image/png;base64,...","message":"Scan this QR...","accountId":"default","channel":"whatsapp"}
|
||||
```
|
||||
|
||||
2. Final response after scan (or timeout):
|
||||
```json
|
||||
{"status":"connected","connected":true,"message":"✅ Linked!","accountId":"default","channel":"whatsapp"}
|
||||
```
|
||||
|
||||
The `qrDataUrl` is a base64-encoded PNG that can be displayed directly in an `<img>` tag.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Run `openclaw status --deep` for a broad probe.
|
||||
|
||||
@ -9,6 +9,8 @@ type ChannelAuthOptions = {
|
||||
channel?: string;
|
||||
account?: string;
|
||||
verbose?: boolean;
|
||||
json?: boolean;
|
||||
timeoutMs?: number;
|
||||
};
|
||||
|
||||
export async function runChannelLogin(
|
||||
@ -21,6 +23,54 @@ export async function runChannelLogin(
|
||||
throw new Error(`Unsupported channel: ${channelInput}`);
|
||||
}
|
||||
const plugin = getChannelPlugin(channelId);
|
||||
|
||||
// JSON mode: use gateway QR login methods for programmatic access
|
||||
if (opts.json) {
|
||||
if (!plugin?.gateway?.loginWithQrStart || !plugin?.gateway?.loginWithQrWait) {
|
||||
throw new Error(`Channel ${channelId} does not support JSON login mode`);
|
||||
}
|
||||
setVerbose(Boolean(opts.verbose));
|
||||
const cfg = loadConfig();
|
||||
const accountId = opts.account?.trim() || resolveChannelDefaultAccountId({ plugin, cfg });
|
||||
const timeoutMs = opts.timeoutMs ?? 60000;
|
||||
|
||||
// Start QR login and get QR data
|
||||
const startResult = await plugin.gateway.loginWithQrStart({
|
||||
accountId,
|
||||
force: false,
|
||||
timeoutMs,
|
||||
verbose: Boolean(opts.verbose),
|
||||
});
|
||||
|
||||
// Output QR data as JSON
|
||||
const output = {
|
||||
status: "pending",
|
||||
qrDataUrl: startResult.qrDataUrl ?? null,
|
||||
message: startResult.message,
|
||||
accountId,
|
||||
channel: channelId,
|
||||
};
|
||||
runtime.log(JSON.stringify(output));
|
||||
|
||||
// Wait for connection
|
||||
const waitResult = await plugin.gateway.loginWithQrWait({
|
||||
accountId,
|
||||
timeoutMs,
|
||||
});
|
||||
|
||||
// Output final result
|
||||
const finalOutput = {
|
||||
status: waitResult.connected ? "connected" : "failed",
|
||||
connected: waitResult.connected,
|
||||
message: waitResult.message,
|
||||
accountId,
|
||||
channel: channelId,
|
||||
};
|
||||
runtime.log(JSON.stringify(finalOutput));
|
||||
return;
|
||||
}
|
||||
|
||||
// Standard interactive mode
|
||||
if (!plugin?.auth?.login) {
|
||||
throw new Error(`Channel ${channelId} does not support login`);
|
||||
}
|
||||
|
||||
@ -215,6 +215,8 @@ export function registerChannelsCli(program: Command) {
|
||||
.option("--channel <channel>", "Channel alias (default: whatsapp)")
|
||||
.option("--account <id>", "Account id (accountId)")
|
||||
.option("--verbose", "Verbose connection logs", false)
|
||||
.option("--json", "Output QR data as JSON (for programmatic use)", false)
|
||||
.option("--timeout <ms>", "Timeout for QR generation in ms", "60000")
|
||||
.action(async (opts) => {
|
||||
await runChannelsCommandWithDanger(async () => {
|
||||
await runChannelLogin(
|
||||
@ -222,6 +224,8 @@ export function registerChannelsCli(program: Command) {
|
||||
channel: opts.channel as string | undefined,
|
||||
account: opts.account as string | undefined,
|
||||
verbose: Boolean(opts.verbose),
|
||||
json: Boolean(opts.json),
|
||||
timeoutMs: parseInt(String(opts.timeout), 10) || 60000,
|
||||
},
|
||||
defaultRuntime,
|
||||
);
|
||||
|
||||
@ -208,7 +208,7 @@ describe("cli program (smoke)", () => {
|
||||
from: "user",
|
||||
});
|
||||
expect(runChannelLogin).toHaveBeenCalledWith(
|
||||
{ channel: undefined, account: "work", verbose: false },
|
||||
{ channel: undefined, account: "work", verbose: false, json: false, timeoutMs: 60000 },
|
||||
runtime,
|
||||
);
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user