diff --git a/README.md b/README.md index e8180ce06..bdef93c09 100644 --- a/README.md +++ b/README.md @@ -22,12 +22,12 @@ You can also use a personal WhatsApp Web session (QR login) via `--provider web` ## 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`). -- **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 - 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 (force web): `pnpm warelay relay --provider web` - Auto-replies (force Twilio poll): `pnpm warelay relay --provider twilio --interval 5 --lookback 10 --verbose` diff --git a/src/index.commands.test.ts b/src/index.commands.test.ts index 21b76a4d8..51c6b0280 100644 --- a/src/index.commands.test.ts +++ b/src/index.commands.test.ts @@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createMockTwilio } from "../test/mocks/twilio.js"; import { statusCommand } from "./commands/status.js"; import { createDefaultDeps, defaultRuntime } from "./index.js"; +import * as providerWeb from "./provider-web.js"; vi.mock("twilio", () => { const { factory } = createMockTwilio(); @@ -55,6 +56,12 @@ describe("CLI commands", () => { 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 () => { const twilio = (await import("twilio")).default; twilio._client.messages.list diff --git a/src/index.ts b/src/index.ts index 09a046be3..bd73db489 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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 .command("send") .description("Send a WhatsApp message")