Skip to main content
ClaudeWave
Skill29.8k 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 (no Chat SDK bridge).

## Install

NanoClaw doesn't ship channels in trunk. This skill copies the native WhatsApp (Baileys) adapter and its `whatsapp-auth` setup step in from the `channels` branch. No Chat SDK bridge.

### Pre-flight (idempotent)

Skip to **Credentials** if all of these are already in place:

- `src/channels/whatsapp.ts` exists
- `src/channels/whatsapp-registration.test.ts` exists
- `src/channels/whatsapp.test.ts` exists
- `src/channels/index.ts` contains `import './whatsapp.js';`
- `setup/whatsapp-auth.ts` and `setup/groups.ts` both exist
- `setup/index.ts`'s `STEPS` map contains both `'whatsapp-auth':` and `groups:`
- `@whiskeysockets/baileys`, `qrcode`, `pino` are listed in `package.json` dependencies
- `.claude/skills/add-whatsapp/scripts/wa-qr-browser.ts` exists (ships with this skill)

Otherwise continue. Every step below is safe to re-run.

### 1. Fetch the channels branch

```bash
git fetch origin channels
```

### 2. Copy the adapter and setup steps

```bash
git show origin/channels:src/channels/whatsapp.ts                      > src/channels/whatsapp.ts
git show origin/channels:src/channels/whatsapp-registration.test.ts    > src/channels/whatsapp-registration.test.ts
git show origin/channels:src/channels/whatsapp.test.ts                 > src/channels/whatsapp.test.ts
git show origin/channels:setup/whatsapp-auth.ts                        > setup/whatsapp-auth.ts
git show origin/channels:setup/groups.ts                               > setup/groups.ts
```

### 3. Append the self-registration import

Append to `src/channels/index.ts` (skip if already present):

```typescript
import './whatsapp.js';
```

### 4. Register the setup steps

In `setup/index.ts`, add these entries to the `STEPS` map (skip lines already present):

```typescript
groups: () => import('./groups.js'),
'whatsapp-auth': () => import('./whatsapp-auth.js'),
```

### 5. Install the adapter packages (pinned)

```bash
pnpm install @whiskeysockets/baileys@7.0.0-rc.9 qrcode@1.5.4 @types/qrcode@1.5.6 pino@9.6.0
```

### 6. Build and validate

```bash
pnpm run build
pnpm exec vitest run src/channels/whatsapp-registration.test.ts
```

Both must be clean before proceeding. `whatsapp-registration.test.ts` is the one integration test: it 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 (so the channel genuinely would not register), or if `@whiskeysockets/baileys` isn't installed (the import throws) — so it also implicitly verifies the dependency from step 5.

End-to-end message delivery against a real WhatsApp number is verified manually once the service is running — see Credentials, Wiring, and Troubleshooting.

## Credentials

WhatsApp uses linked-device authentication — no API key, just a one-time pairing from your phone.

### Check current state

Check if WhatsApp is already authenticated. If `store/auth/creds.json` exists, skip to "Shared vs dedicated number".

```bash
test -f store/auth/creds.json && echo "WhatsApp auth exists" || echo "No WhatsApp auth"
```

### Detect environment

Check whether the environment is headless (no display server):

```bash
[[ -z "$DISPLAY" && -z "$WAYLAND_DISPLAY" && "$OSTYPE" != darwin* ]] && echo "IS_HEADLESS=true" || echo "IS_HEADLESS=false"
```

### Ask the user

Use `AskUserQuestion` to collect configuration. **Adapt auth options based on environment:**

If IS_HEADLESS=true AND not WSL → AskUserQuestion: How do you want to authenticate WhatsApp?
- **Pairing code** (Recommended) - Enter a numeric code on your phone (no camera needed, requires phone number)
- **QR code in terminal** - Displays QR code in the terminal (can be too small on some displays)

Otherwise (macOS, desktop Linux, or WSL) → AskUserQuestion: How do you want to authenticate WhatsApp?
- **QR code in browser** (Recommended) - Runs a small local HTTP server that renders the rotating QR as a PNG and auto-opens your default browser
- **Pairing code** - Enter a numeric code on your phone (no camera needed, requires phone number)
- **QR code in terminal** - Displays QR code in the terminal (can be too small on some displays)

If they chose pairing code:

AskUserQuestion: What is your phone number? (Digits only — country code followed by your 10-digit number, no + prefix, spaces, or dashes. Example: 14155551234 where 1 is the US country code and 4155551234 is the phone number.)

### Clean previous auth state (if re-authenticating)

```bash
rm -rf store/auth/
```

### Run WhatsApp authentication

For QR code in browser (recommended):

```bash
pnpm exec tsx .claude/skills/add-whatsapp/scripts/wa-qr-browser.ts
```

(Bash timeout: 150000ms)

The wrapper spawns `setup/index.ts --step whatsapp-auth -- --method qr`, parses each rotating QR from its `WHATSAPP_AUTH_QR` status blocks, and serves the current QR as a PNG on a local HTTP server (default port `8765`, falls back to a free port). Flags: `--clean` (wipes `store/auth/` before spawning) and `--port N`.

Tell the user:

> A browser window will open with a QR code.
>
> 1. Open WhatsApp > **Settings** > **Linked Devices** > **Link a Device**
> 2. Scan the QR code in the browser
> 3. The page will show "Authenticated!" when done

For QR code in terminal:

```bash
pnpm exec tsx setup/index.ts --step whatsapp-auth -- --method qr
```

(Bash timeout: 150000ms)

The setup driver emits each rotating QR as a `WHATSAPP_AUTH_QR` status block; when run directly (not through `setup:auto`) the raw QR string is printed and your terminal must render it as ASCII. If your terminal can't render it readably, use the browser method above.

Tell the user:

> 1. Open WhatsApp > **Settings** > **Linked Devices** > **Link a Device**
> 2. Scan the QR code displayed in the terminal

For pairing code:

Tell the user to have WhatsApp open on **Settings > Linked Devices > Link a Dev