Skip to content

About

An Agent Skill for reading and writing WhatsApp from your terminal, plus wa — a thin, testable bash facade over whatsapp-cli.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

whatsapp-agent-skill

An Agent Skill for reading and writing WhatsApp from your terminal — plus wa, the thin, testable bash facade it's built on. The skill format is the open standard; Claude Code is what it's been exercised against.

It wraps whatsapp-cli (a whatsmeow-based Go CLI that links as a WhatsApp companion device). The point of the facade is that your workflows call wa, not the binary — so when the transport changes, one file changes.

wa doctor                       # which binary, which store, how stale, any strays
wa sync                         # drain new messages into the local DB
wa search "quarterly report"    # full-text over local history
wa chat 254712345678@s.whatsapp.net | jq '.[-20:]'

Why a wrapper and not just the CLI

Most of this exists because unattended use surfaces failures that interactive use hides.

  • sync can report success while doing nothing. When the linked-device session dies, the underlying CLI has returned {"success":true,"messages_count":0}. A store of mine went 31 days stale without a single error. wa doctor reports staleness in days, and weekly-sync.sh treats staleness — not exit code — as the health signal.
  • Decoy stores are the main way to lose data. The binary defaults --store to a CWD-relative ./store and creates it unconditionally, so running it from the wrong directory silently makes a second, empty store. You then sync into the decoy while reading the real one. wa always passes --store explicitly, and doctor hunts for strays — including ~/store, the one the docs warn about.
  • Scheduled jobs need pinning. launchd/cron give you a near-empty PATH. wa auto-discovers the binary from local-only locations, and the plist template pins every path so nothing is resolved at runtime.

Install

# 1. the underlying CLI
go install github.com/vicentereig/whatsapp-cli@latest    # lands in ~/go/bin

# 2. this skill
git clone https://github.com/mikrub/whatsapp-agent-skill
cd whatsapp-agent-skill
ln -s "$PWD" ~/.claude/skills/whatsapp                   # auto-discovered by Claude Code

# 3. pair (scan the QR with WhatsApp → Settings → Linked Devices)
scripts/wa auth
scripts/wa sync 60
scripts/wa doctor

wa auth --full-history requests the full archive at pair time rather than the default recent window, and wa history extend backfills older messages on demand. Both rely on features not yet in an upstream release — they exist in a fork and are being submitted upstream, so install upstream unless you need them. wa doctor reports which build you have. Note that --full-history only takes effect while pairing.

Commands

Command Purpose
wa auth / wa reauth Pair, or force a fresh QR (preserves message history)
wa doctor Health check: binary, store, freshness, stray stores
wa sync [SECONDS] Connect, drain offline messages, exit
wa chats [LIMIT] List chats
wa chat <JID> [LIMIT] Messages in one chat
wa search "<query>" Full-text search
wa contacts "<query>" Find a contact's JID
wa send <JID> "<msg>" Send text — requires human approval, see below
wa send-image <JID> <PATH> ["caption"] Send an image
wa history extend … Backfill older messages on demand

Config via env: WA_CLI_BIN, WA_STORE, WA_SYNC_TIMEOUT, WA_SCAN_ROOT, WA_DRY_RUN=1 (print the resolved command instead of running it).

Sending requires human approval

The skill instructs the agent never to send a message without the human confirming the exact text first — including when asked to "reply to X" — and to send one message per turn. Preview any send with WA_DRY_RUN=1 before approving.

Security

Read SKILL.md before automating anything. In short:

  • store/whatsapp.db holds session keys. Anyone with that file can impersonate your WhatsApp account. store/messages.db holds your plaintext message history. Both are gitignored; keep them 0600 in a 0700 directory.
  • Don't put the store in a cloud-synced folder unless you accept the tradeoff: it replicates to every linked device, and reauth revokes the session while prior revisions of the key database remain in version history.
  • Don't run a scheduled job out of a synced folder. Deploy to ~/.local/bin — see examples/.

Tests

bats tests/wa.bats            # 39 tests; the live-session ones need WA_LIVE=1

Most tests assert the resolved command via WA_DRY_RUN=1; a stub binary on PATH covers signal handling and exit-code propagation.

Status

Used daily against a ~100k-message store. The macOS specifics (launchd, osascript notifications, BSD date/stat) are what's actually exercised — Linux would need small adjustments in weekly-sync.sh and doctor.

Acknowledgements

Built on whatsapp-cli by @vicentereig, which does the real work of speaking WhatsApp's multi-device protocol via whatsmeow. This is an independent wrapper, not affiliated with or endorsed by either project.

Largely written through agentic development; commits carry Co-Authored-By trailers. Reviewed and run against a real ~100k-message store before publishing.

License

MIT — see LICENSE.

About

An Agent Skill for reading and writing WhatsApp from your terminal, plus wa — a thin, testable bash facade over whatsapp-cli.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages