feat(cli): add --json flag to channels login for programmatic QR access
Adds JSON output mode for that returns QR code as base64 PNG data URL instead of terminal graphics. Useful for web dashboards and hosting platforms that need to display the QR in a browser. - Add --json and --timeout flags to channels login command - Use gateway.loginWithQrStart/Wait methods for JSON mode - Output two JSON objects: QR data, then connection result - Document new mode in docs/cli/channels.md
This commit is contained in:
parent
a7534dc223
commit
d3cf62a1e5
@ -40,6 +40,27 @@ moltbot channels login --channel whatsapp
|
||||
moltbot 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 `moltbot 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,
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user