Skip to main content
ClaudeWave
Skill30.7k repo starsupdated yesterday

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.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/nanocoai/nanoclaw /tmp/add-whatsapp && cp -r /tmp/add-whatsapp/.claude/skills/add-whatsapp ~/.claude/skills/add-whatsapp
Then start a new Claude Code session; the skill loads automatically.

SKILL.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-toolSkill

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.

add-codexSkill

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-dashboardSkill

Add a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.

add-deltachatSkill

Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.

add-discordSkill

Add Discord bot channel integration via Chat SDK.

add-emacsSkill

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-gcal-toolSkill

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-gchatSkill

Add Google Chat channel integration via Chat SDK.