add-whatsapp
# ClaudeWave Description This skill integrates WhatsApp messaging into NanoClaw projects using the native Baileys adapter for direct device connection without intermediary SDKs. Use it when you need to add WhatsApp channel support with QR code or pairing code authentication, requiring installation of adapter files, setup steps, and dependencies from the channels branch.
git clone --depth 1 https://github.com/nanocoai/nanoclaw /tmp/add-whatsapp && cp -r /tmp/add-whatsapp/.claude/skills/add-whatsapp ~/.claude/skills/add-whatsappSKILL.md
# Add WhatsApp Channel Adds WhatsApp support via the native Baileys adapter — a direct WhatsApp Web connection, no Chat SDK bridge. NanoClaw doesn't ship channels in trunk — this skill copies the WhatsApp adapter in from the `channels` branch. The mechanical steps under **Apply** carry `nc:` directive fences: an agent reads the prose and applies them, and a parser can apply them deterministically from the same document. Every directive is idempotent, so the whole skill is safe to re-run; anything a parser can't apply falls back to the prose beside it. ## Number safety check (required) Complete this check before running any install or authentication command. If the user already said they want to use their **shared**, **personal**, **main**, **existing**, or **everyday** WhatsApp number, treat it as a shared number and show the warning immediately. Do not ask the number-type question again. Otherwise, ask which WhatsApp number NanoClaw will use: ```nc:prompt number_mode validate:^(dedicated|shared)$ Which WhatsApp number will NanoClaw use? `dedicated` (recommended) — a separate number used only for NanoClaw (spare SIM, eSIM, or old phone). `shared` — your existing everyday / personal WhatsApp number. ``` If the answer is `shared`, show this warning — tell the user: ```nc:operator when:number_mode=shared ⚠️ Risk to your WhatsApp account Connecting your shared or personal number could cause WhatsApp to temporarily suspend or permanently ban that number. You could lose access to the WhatsApp account, chats, and groups you rely on. We strongly recommend using a separate, dedicated number for NanoClaw. On your personal number, the agent lives only in your "You" / self-chat. Messages other people send you are ignored entirely — never read, never answered, never flagged for approval. Nobody else can talk to the agent. If you want the agent reachable as its own contact, consider: • Telegram — a bot takes ~2 minutes to set up • a dedicated WhatsApp number — spare SIM, eSIM, or old phone • /add-whatsapp-cloud — the official Meta Business API ``` Then confirm how to proceed. Do not continue with installation or authentication unless the user explicitly selects the second option: ```nc:prompt shared_confirm validate:^(continue|dedicated)$ when:number_mode=shared How would you like to proceed? `dedicated` (recommended) — go back and use a dedicated number. `continue` — I understand the risk, continue with my shared number. ``` Remember the effective mode for the rest of this workflow: it is `shared` only when the user explicitly acknowledged the risk and continued; anyone who chose a dedicated number — up front or at the warning — continues as a dedicated-number install without seeing the warning again: ```nc:run capture:mode effect:fetch when:number_mode=dedicated echo dedicated ``` ```nc:run capture:mode effect:fetch when:shared_confirm=continue echo shared ``` ```nc:run capture:mode effect:fetch when:shared_confirm=dedicated echo dedicated ``` ## Apply ### 1. Copy the adapter and its registration test Fetch the `channels` branch and copy the WhatsApp adapter, its registration test, and the `whatsapp-formatting` container skill (overwrite — the branch is canonical). The `whatsapp-auth` setup step is maintained in trunk, so it is not copied here: ```nc:copy from-branch:channels src/channels/whatsapp.ts src/channels/whatsapp-registration.test.ts container/skills/whatsapp-formatting/SKILL.md container/skills/whatsapp-formatting/instructions.md ``` The `whatsapp-formatting` container skill is part of the channel payload: its `instructions.md` is inlined as a section of every group's composed project document (see `src/project-doc-compose.ts`), teaching agents WhatsApp's formatting syntax. Trunk does not ship it — without this copy step agents format WhatsApp messages with generic markdown that renders literally. ### 2. Register the adapter Append the self-registration import to the channel barrel (skipped if the line is already present). This one line is the skill's only reach-in into core: ```nc:append to:src/channels/index.ts import './whatsapp.js'; ``` ### 3. Install the adapter packages Pinned to exact versions — the supply-chain policy rejects ranges and `latest`. Baileys is the WhatsApp Web client; `qrcode` renders the device-link QR in the terminal; `pino` is Baileys' logger: ```nc:dep @whiskeysockets/baileys@7.0.0-rc.9 qrcode@1.5.4 @types/qrcode@1.5.6 pino@9.6.0 ``` ### 4. Build and validate Build first: it typechecks the adapter against core and proves the dependencies are installed. Then run the one integration test. ```nc:run effect:build pnpm run build ``` ```nc:run effect:test pnpm exec vitest run src/channels/whatsapp-registration.test.ts ``` `whatsapp-registration.test.ts` imports the real channel barrel and asserts the registry contains `whatsapp`. It goes red if the `import './whatsapp.js';` line is deleted or drifts, if the barrel fails to evaluate, or if `@whiskeysockets/baileys` isn't installed (the import throws) — so it also covers the dependency from step 3. End-to-end delivery against a real WhatsApp number is verified manually once the service runs. ## Authenticate WhatsApp uses linked-device authentication — no API key, just a one-time pairing from your phone. The adapter is installed and registered, but its factory returns `null` (and the channel stays dark) until `store/auth/creds.json` exists. The number safety check above is still required even when credentials already exist. If `store/auth/creds.json` exists, skip ahead to "Dedicated vs personal number" after completing the safety check — the link step below reports the already-linked number and moves on. Pick how to link the device. `qr` shows a rotating QR you scan with your phone's camera; `pairing-code` shows an 8-character code you type into WhatsApp (no camera needed, but it needs your phone number): ```nc:prompt auth_method validate:^(qr|pairing-code)$ How do you want to link What
Add Atomic Chat MCP server so the container agent can call local models served by the Atomic Chat desktop app via its OpenAI-compatible API.
Use Codex (OpenAI's codex app-server) as a full agent provider — planning, tool orchestration, MCP tools, server-side history, session resume — alongside or instead of Claude. ChatGPT subscription or OpenAI API key, vault-only via OneCLI. Per-group via `ncl groups config update --provider codex`. Distinct from using OpenAI as an MCP tool (where Claude remains the planner).
Add a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.
Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.
Add Discord bot channel integration via Chat SDK.
Add Emacs as a channel. Opens an interactive chat buffer and org-mode integration so you can talk to NanoClaw from within Emacs (Doom, Spacemacs, or vanilla). Local HTTP bridge — no bot token or external service needed.
Add Google Calendar as an MCP tool (list calendars, list/search/create events, free/busy queries) using OneCLI-managed OAuth. Multi-calendar and multi-account supported. Mirrors /add-gmail-tool's stub pattern — no raw credentials ever reach the container; OneCLI injects real tokens at request time.
Add Google Chat channel integration via Chat SDK.