whatsapp-web-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/dist/wwa.js +343016 -0
- package/package.json +50 -0
- package/skills/whatsapp-cli/SKILL.md +112 -0
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "whatsapp-web-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A local WhatsApp Web CLI for agents and scripts.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"wwa": "./dist/wwa.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"skills",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"wwa": "node --no-deprecation ./dist/wwa.js",
|
|
17
|
+
"typecheck": "tsc --noEmit",
|
|
18
|
+
"build": "bun build ./bin/wwa.ts --target=node --outdir=dist --external @aws-sdk/client-s3",
|
|
19
|
+
"lint": "tsc --noEmit",
|
|
20
|
+
"prepack": "bun run typecheck && bun run build",
|
|
21
|
+
"pack:dry": "bun pm pack --dry-run"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"whatsapp",
|
|
25
|
+
"whatsapp-web",
|
|
26
|
+
"cli",
|
|
27
|
+
"agent",
|
|
28
|
+
"codex"
|
|
29
|
+
],
|
|
30
|
+
"author": "",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"engines": {
|
|
33
|
+
"bun": ">=1.3.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"commander": "^14.0.2",
|
|
37
|
+
"mime-types": "^3.0.2",
|
|
38
|
+
"qrcode": "^1.5.4",
|
|
39
|
+
"qrcode-terminal": "^0.12.0",
|
|
40
|
+
"whatsapp-web.js": "1.34.6",
|
|
41
|
+
"zod": "^4.1.13"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/bun": "^1.3.3",
|
|
45
|
+
"@types/mime-types": "^3.0.1",
|
|
46
|
+
"@types/qrcode": "^1.5.6",
|
|
47
|
+
"@types/qrcode-terminal": "^0.12.2",
|
|
48
|
+
"typescript": "^5.9.3"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# WhatsApp CLI
|
|
2
|
+
|
|
3
|
+
Use this skill when the user wants to inspect or send WhatsApp messages through the local `wwa` CLI.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
- Use `wwa` as the low-level WhatsApp control surface.
|
|
8
|
+
- Treat the installed/built `wwa` binary as a Node runtime CLI. The project may use Bun for install/build, but `whatsapp-web.js` should run under Node.
|
|
9
|
+
- Never bypass `wwa` or `whatsapp-web.js` by scraping WhatsApp Web DOM, reading browser IndexedDB/cache, using Chrome DevTools/CDP, or poking Puppeteer internals directly.
|
|
10
|
+
- If the CLI gets stuck, reset with `wwa daemon stop --json`, then restart/login through `wwa`; fix the CLI wrapper if needed instead of creating a shortcut around it.
|
|
11
|
+
- The daemon should run one headless browser session only. Do not set `WWA_HEADLESS=false` unless the user explicitly wants a visible browser for debugging.
|
|
12
|
+
- Do not use MCP for this workflow unless the user explicitly asks for an MCP implementation.
|
|
13
|
+
- Do not add classification or reply-generation behavior to the CLI; those are higher-level workflows.
|
|
14
|
+
- `wwa transcribe` and `wwa tts` are available when `OPENAI_API_KEY` is configured. Classification and reply drafting still belong in the agent/workflow layer.
|
|
15
|
+
- For voice notes, use `wwa send audio --voice` or `wwa reply audio --voice`. If the local audio is MP3, AIFF, WAV, or another non-OGG format, the CLI converts it to OGG/Opus with `ffmpeg` before sending.
|
|
16
|
+
- For generated speech, prefer `wwa tts --text "..." --to <chatId> --json`. This command uses OpenAI `gpt-4o-mini-tts` with voice `nova`, then sends the generated MP3 as a WhatsApp voice note.
|
|
17
|
+
- For transcription, prefer `wwa transcribe --message <messageId> --json`. It saves media through `wwa`, normalizes WhatsApp `.oga` voice notes to `.ogg`, and uses OpenAI `gpt-4o-mini-transcribe`.
|
|
18
|
+
- For generated replies, draft first and ask for confirmation before sending unless the user explicitly requested auto-send.
|
|
19
|
+
- Prefer `--json` for commands that return structured data.
|
|
20
|
+
- Start with the user's actual data command, such as `wwa chat-search "<name>" --json`. Data commands auto-start the daemon and wait for readiness.
|
|
21
|
+
- If a data command returns `ok: false` with `nextCommand`, run that command instead of manually guessing a recovery path. For login, this should usually be `wwa auth login --image --json`.
|
|
22
|
+
- Prefer `wwa events next --chat <chatId> --incoming --timeout 120 --json` for turn-by-turn live conversation. It waits for one new matching event, prints it, and exits.
|
|
23
|
+
- Use `wwa events tail --jsonl` only when the user explicitly wants a long-running stream. `tail` starts from new events by default, so do not replace it with repeated `events list --since ...` polling for realtime replies.
|
|
24
|
+
- When several messages arrive quickly in the same chat, coalesce the newest burst and answer the latest user intent. Do not respond to each stale queued message one by one.
|
|
25
|
+
- For auth, prefer `wwa auth qr --image --json` and render the returned `imagePath` for the user. This is easier to scan than terminal QR text.
|
|
26
|
+
- QR image auth should not require opening a visible Chrome window; the CLI saves the image from the QR payload emitted by `whatsapp-web.js`.
|
|
27
|
+
- `wwa auth qr` waits up to 30 seconds for a QR by default; do not manually retry immediately unless it times out.
|
|
28
|
+
- Heavy WhatsApp accounts can have hundreds of unread chats. Use `wwa unread --limit 20 --json` for a quick first pass, then fetch messages for selected chats.
|
|
29
|
+
- Chat listing can take a while on first sync after login. Wait for the command to finish instead of interrupting early.
|
|
30
|
+
- If a stateful command says login is required, run `wwa auth login --image --json`, render the returned `imagePath`, let the user scan it, then retry the original command.
|
|
31
|
+
- Do not require `wwa doctor` or `wwa ready` in normal usage; keep them for diagnostics only.
|
|
32
|
+
- If `phase` is `failed`, `UNLAUNCHED`, or a browser profile lock is reported, run `wwa daemon stop --json`, then `wwa auth login --image --json`.
|
|
33
|
+
|
|
34
|
+
## Common Commands
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
wwa daemon start --json
|
|
38
|
+
wwa daemon status --json
|
|
39
|
+
wwa auth login --image --json
|
|
40
|
+
wwa auth qr --image --json
|
|
41
|
+
wwa auth status --json
|
|
42
|
+
wwa chat-search "<query>" --json
|
|
43
|
+
wwa message-search "<query>" --limit-chats 20 --messages-per-chat 50 --json
|
|
44
|
+
wwa message-search "<query>" --chat <chatId> --json
|
|
45
|
+
wwa unread --limit 20 --json
|
|
46
|
+
wwa unread messages --limit-chats 10 --messages-per-chat 5 --json
|
|
47
|
+
wwa chats list --unread --limit 20 --json
|
|
48
|
+
wwa messages list --chat <chatId> --limit 50 --json
|
|
49
|
+
wwa messages get --id <messageId> --json
|
|
50
|
+
wwa events list --since 24h --json
|
|
51
|
+
wwa events next --chat <chatId> --incoming --timeout 120 --json
|
|
52
|
+
wwa events tail --jsonl
|
|
53
|
+
wwa events tail --chat <chatId> --incoming --jsonl
|
|
54
|
+
wwa media save --message <messageId> --json
|
|
55
|
+
wwa transcribe --message <messageId> --json
|
|
56
|
+
wwa transcribe --file ./audio.oga --json
|
|
57
|
+
wwa tts --text "Mensagem em voz natural." --to <chatId> --json
|
|
58
|
+
wwa send text --to <chatId> --body "..."
|
|
59
|
+
wwa send media --to <chatId> --file ./image.png --caption "..."
|
|
60
|
+
wwa send audio --to <chatId> --file ./note.ogg --voice
|
|
61
|
+
wwa reply text --message <messageId> --body "..."
|
|
62
|
+
wwa reply media --message <messageId> --file ./file.pdf --as-document
|
|
63
|
+
wwa reply audio --message <messageId> --file ./note.ogg --voice
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Workflow Guidance
|
|
67
|
+
|
|
68
|
+
To review unread messages, list a bounded set of unread chats, fetch recent messages per chat, and save media only when needed. If an audio attachment is saved, use `wwa transcribe --message <messageId> --json`.
|
|
69
|
+
|
|
70
|
+
To find a person or conversation, prefer:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
wwa chat-search "<name or phone fragment>" --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
To find text in recent messages, prefer:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
wwa message-search "<text>" --limit-chats 20 --messages-per-chat 50 --json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If you already know the chat ID, narrow the message search:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
wwa message-search "<text>" --chat <chatId> --json
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Golden path for agents:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
wwa chat-search "<name>" --json
|
|
92
|
+
wwa auth login --image --json
|
|
93
|
+
wwa chat-search "<name>" --json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Use the returned `nextCommand` when it is present. After `auth login`, render the returned `imagePath`, wait for the user to scan it, and retry the original command.
|
|
97
|
+
|
|
98
|
+
Live conversation loop:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
wwa events next --chat <chatId> --incoming --timeout 120 --json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
For each turn, wait for `events next`, answer the returned event's newest user intent, then run `wwa reply text --message <messageId> --body "..." --json`. Do not use `--replay` unless the user explicitly wants to process stored history.
|
|
105
|
+
|
|
106
|
+
When showing auth to the user in Codex, run:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
wwa auth login --image --json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Then render the `imagePath` as an image in the response. If it reports `connected: true`, skip QR display and continue with `wwa auth status --json`.
|