Skip to main content

Overview

The WhatsApp channel uses the Baileys library to connect to WhatsApp Web. It supports both personal WhatsApp numbers (shared) and dedicated numbers (separate device).

Installation

Run the /add-whatsapp skill in Claude Code:
/add-whatsapp
The skill will:
  • Install the WhatsApp channel code
  • Add required dependencies (@whiskeysockets/baileys, qrcode, qrcode-terminal)
  • Guide you through authentication
  • Register your first chat

Authentication Methods

WhatsApp offers three authentication methods: Displays a large, scannable QR code in your browser. When to use: Desktop environments, best user experience
npx tsx setup/index.ts --step whatsapp-auth -- --method qr-browser
1

Browser Opens

A browser window opens with a QR code
2

Open WhatsApp

On your phone: Settings > Linked Devices > Link a Device
3

Scan Code

Scan the QR code from the browser window
4

Done

The page shows “Authenticated!” when complete

Pairing Code

Enter a numeric code on your phone (no camera needed). When to use: Headless servers, camera issues, preference for typing
npx tsx setup/index.ts --step whatsapp-auth -- --method pairing-code --phone 1234567890
The pairing code expires in ~60 seconds and must be entered immediately. Have WhatsApp open and ready before running the command.
1

Code Appears

The skill displays a numeric code
2

Open WhatsApp

On your phone: Settings > Linked Devices > Link a Device
3

Tap Link with Phone Number

Tap “Link with phone number instead”
4

Enter Code

Enter the code immediately (it expires in ~60 seconds)

QR Code in Terminal

Displays a QR code directly in the terminal. When to use: SSH sessions, minimal environments
npx tsx setup/index.ts --step whatsapp-auth -- --method qr-terminal
QR codes in terminal can be too small to scan on some displays. Use QR-browser or pairing-code instead.

Configuration

Shared vs Dedicated Number

Shared Number (Personal WhatsApp)
  • Use your personal WhatsApp number
  • Recommended: Use self-chat or a solo group
  • All messages from linked device appear in your WhatsApp
Dedicated Number (Separate Device)
  • Use a separate phone/SIM for the assistant
  • Users DM the bot’s number or add it to groups
  • Complete separation from personal messages

Chat Registration

After authentication, register your first chat: Self-Chat (Recommended for shared numbers)
npx tsx setup/index.ts --step register \
  --jid "<your-number>@s.whatsapp.net" \
  --name "Main Chat" \
  --trigger "@Andy" \
  --folder "whatsapp_main" \
  --channel whatsapp \
  --assistant-name "Andy" \
  --is-main \
  --no-trigger-required
Group Chat (Trigger required) First, sync groups to get the JID:
npx tsx setup/index.ts --step groups
npx tsx setup/index.ts --step groups --list
Then register:
npx tsx setup/index.ts --step register \
  --jid "<group-jid>@g.us" \
  --name "Family Chat" \
  --trigger "@Andy" \
  --folder "whatsapp_family-chat" \
  --channel whatsapp

How It Works

Connection

  1. WhatsApp channel reads credentials from store/auth/creds.json
  2. Connects to WhatsApp Web using Baileys library
  3. Maintains persistent session (credentials last ~20 days)
  4. Auto-reconnects on disconnection

Message Handling

  1. Incoming: Messages arrive via Baileys WebSocket
  2. Storage: Stored in SQLite with sender info and timestamp
  3. Routing: Main loop polls and routes to registered chats
  4. Processing: Agent processes in isolated container
  5. Outgoing: Response sent back through Baileys

Group Metadata Sync

WhatsApp groups need metadata sync to get group names:
npx tsx setup/index.ts --step groups
This runs automatically every 24 hours. Force sync anytime with:
npx tsx setup/index.ts --step groups --force

Troubleshooting

QR Code Expired

QR codes expire after ~60 seconds. Delete auth and retry:
rm -rf store/auth/
npx tsx setup/index.ts --step whatsapp-auth -- --method qr-browser

Pairing Code Not Working

Codes expire in ~60 seconds. Ensure:
  1. Phone number includes country code without + (e.g., 1234567890)
  2. Phone has internet access
  3. WhatsApp is updated to latest version
  4. You enter the code immediately when it appears
If issues persist, switch to QR-browser:
rm -rf store/auth/
npx tsx setup/index.ts --step whatsapp-auth -- --method qr-browser

“conflict” Disconnection

Happens when two instances connect with the same credentials. Ensure only one NanoClaw process is running:
pkill -f "node dist/index.js"
# Then restart service
launchctl kickstart -k gui/$(id -u)/com.nanoclaw  # macOS
systemctl --user restart nanoclaw  # Linux

Bot Not Responding

1

Check Auth

ls store/auth/creds.json
If missing, re-run authentication
2

Check Registration

sqlite3 store/messages.db "SELECT * FROM registered_groups WHERE jid LIKE '%@g.us' OR jid LIKE '%@s.whatsapp.net'"
3

Check Service

# macOS
launchctl list | grep nanoclaw

# Linux
systemctl --user status nanoclaw
4

Check Logs

tail -50 logs/nanoclaw.log

Group Names Not Showing

Run group metadata sync:
npx tsx setup/index.ts --step groups
This fetches all group names from WhatsApp. Runs automatically every 24 hours.

Implementation Details

Dependencies

  • @whiskeysockets/baileys - WhatsApp Web protocol implementation
  • qrcode - QR code generation for browser display
  • qrcode-terminal - QR code rendering in terminal

Session Storage

Credentials are stored in store/auth/:
  • creds.json - Authentication credentials
  • app-state-sync-*.json - App state sync data
  • sender-key-*.json - E2E encryption keys
The store/auth/ directory contains sensitive credentials. Ensure it’s in .gitignore and has proper file permissions (700).

JID Format

Self-Registration Code

registerChannel('whatsapp', (opts: ChannelOpts) => {
  const authPath = path.join(STORE_DIR, 'auth', 'creds.json');
  if (!existsSync(authPath)) return null;
  return new WhatsAppChannel(opts);
});
The channel only activates if store/auth/creds.json exists.

Next Steps

Add Telegram

Add Telegram as a second channel

Channel Overview

Learn about the channel system

Build docs developers (and LLMs) love