Add login alias for web QR and update docs/tests

This commit is contained in:
Peter Steinberger
2025-11-25 00:19:21 +01:00
parent 9dd257a92d
commit 9595964419
3 changed files with 23 additions and 2 deletions

View File

@@ -22,12 +22,12 @@ You can also use a personal WhatsApp Web session (QR login) via `--provider web`
## Providers (choose per command) ## Providers (choose per command)
- **Twilio (default)** — full feature set: send, wait/poll delivery, status, inbound polling/webhook, auto-replies. Requires `.env` Twilio creds and a WhatsApp-enabled number (`TWILIO_WHATSAPP_FROM`). - **Twilio (default)** — full feature set: send, wait/poll delivery, status, inbound polling/webhook, auto-replies. Requires `.env` Twilio creds and a WhatsApp-enabled number (`TWILIO_WHATSAPP_FROM`).
- **Web (`--provider web`)** — personal WhatsApp Web session via QR. Supports outbound sends and inbound auto-replies when you run `pnpm warelay relay --provider web`. No delivery-status polling for web sends. Setup: `pnpm warelay web:login` then either send with `--provider web` or keep `relay --provider web` running. Session data lives in `~/.warelay/credentials.json`; if logged out, rerun `web:login`. Use at your own risk (personal-account automation can be rate-limited or logged out by WhatsApp). - **Web (`--provider web`)** — personal WhatsApp Web session via QR. Supports outbound sends and inbound auto-replies when you run `pnpm warelay relay --provider web`. No delivery-status polling for web sends. Setup: `pnpm warelay web:login` (alias: `pnpm warelay login`) then either send with `--provider web` or keep `relay --provider web` running. Session data lives in `~/.warelay/credentials.json`; if logged out, rerun `web:login`/`login`. Use at your own risk (personal-account automation can be rate-limited or logged out by WhatsApp).
## Common Commands ## Common Commands
- Send: `pnpm warelay send --to +12345550000 --message "Hello" --wait 20 --poll 2` - Send: `pnpm warelay send --to +12345550000 --message "Hello" --wait 20 --poll 2`
- Send via personal WhatsApp Web: first `pnpm warelay web:login` (scan QR), then `pnpm warelay send --provider web --to +12345550000 --message "Hi"` - Send via personal WhatsApp Web: first `pnpm warelay web:login` (alias: `pnpm warelay login`, scan QR), then `pnpm warelay send --provider web --to +12345550000 --message "Hi"`
- Auto-replies (auto provider): `pnpm warelay relay` (uses web if logged in, otherwise twilio poll) - Auto-replies (auto provider): `pnpm warelay relay` (uses web if logged in, otherwise twilio poll)
- Auto-replies (force web): `pnpm warelay relay --provider web` - Auto-replies (force web): `pnpm warelay relay --provider web`
- Auto-replies (force Twilio poll): `pnpm warelay relay --provider twilio --interval 5 --lookback 10 --verbose` - Auto-replies (force Twilio poll): `pnpm warelay relay --provider twilio --interval 5 --lookback 10 --verbose`

View File

@@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createMockTwilio } from "../test/mocks/twilio.js"; import { createMockTwilio } from "../test/mocks/twilio.js";
import { statusCommand } from "./commands/status.js"; import { statusCommand } from "./commands/status.js";
import { createDefaultDeps, defaultRuntime } from "./index.js"; import { createDefaultDeps, defaultRuntime } from "./index.js";
import * as providerWeb from "./provider-web.js";
vi.mock("twilio", () => { vi.mock("twilio", () => {
const { factory } = createMockTwilio(); const { factory } = createMockTwilio();
@@ -55,6 +56,12 @@ describe("CLI commands", () => {
expect(wait).not.toHaveBeenCalled(); expect(wait).not.toHaveBeenCalled();
}); });
it("login alias calls web login", async () => {
const spy = vi.spyOn(providerWeb, "loginWeb").mockResolvedValue();
await index.program.parseAsync(["login"], { from: "user" });
expect(spy).toHaveBeenCalled();
});
it("status command prints JSON", async () => { it("status command prints JSON", async () => {
const twilio = (await import("twilio")).default; const twilio = (await import("twilio")).default;
twilio._client.messages.list twilio._client.messages.list

View File

@@ -1927,6 +1927,20 @@ program
} }
}); });
program
.command("login")
.description("Alias for web:login (personal WhatsApp Web QR link)")
.option("--verbose", "Verbose connection logs", false)
.action(async (opts) => {
setVerbose(Boolean(opts.verbose));
try {
await loginWeb(Boolean(opts.verbose));
} catch (err) {
defaultRuntime.error(danger(`Web login failed: ${String(err)}`));
defaultRuntime.exit(1);
}
});
program program
.command("send") .command("send")
.description("Send a WhatsApp message") .description("Send a WhatsApp message")