whatsapp-cli

作者 vicentereig已验证

Danger. Danger. High Voltage. Give your codex/claude access to WhatsApp

173
Stars
22
Forks
Go
语言
2026/8/23
添加时间

⚠️ 第三方软件声明

本 Skill 为第三方开源软件,独立托管于 GitHub。SkillTip 仅为信息目录,不控制或维护底层仓库。所显示的安全检查为自动化且范围有限,安装前请自行审查源码。

阅读服务条款

安装

添加到你的 Claude Code skills 目录:

# Add to your Claude Code skills
git clone https://github.com/vicentereig/whatsapp-cli

快速入门

使用 whatsapp-cli 等 Skills 的指南。

安全报告

已验证

上次扫描:—

{
  "status": "PASSED",
  "issues": []
}

README.md

WhatsApp CLI - Complete Reference

For Humans & LLMs: This document covers the WhatsApp CLI tool: installation, usage, the API reference, examples, architecture, and troubleshooting. Humans and large language models can both read it.

Version: 1.3.2 Repository: https://github.com/vicentereig/whatsapp-cli License: MIT Language: Go 1.24+


Table of Contents


Overview

What is WhatsApp CLI?

WhatsApp CLI is a standalone command-line tool for WhatsApp. It uses the WhatsApp Web multidevice protocol. Every command returns structured JSON output. Use it for:

  • Automation: Shell scripts, cron jobs, CI/CD pipelines
  • AI Integration: Codex, Claude Code, GPT-based tools
  • Data Analysis: Extract and analyze WhatsApp conversations
  • Custom Applications: Build tools on top of WhatsApp

Key Features

FeatureDescription
Zero DependenciesSingle compiled binary (21MB), no runtime required
JSON OutputAll commands return structured JSON for easy parsing
Persistent SessionsAuthenticate once via QR code, auto-reconnect for ~20 days
Local StorageSQLite database, no cloud dependencies
Full MessagingSend, receive, search messages; manage contacts & chats
Group SupportSend/receive messages in group chats
TDD Implementation100% test coverage, production-ready

System Requirements

  • Operating System: Linux, macOS, Windows
  • Architecture: x86_64, ARM64
  • Go Version: 1.24+ (for building from source)
  • Storage: ~50MB for binary + variable for message database
  • Network: Internet connection required
  • WhatsApp Account: Active WhatsApp account with smartphone

Installation

Method 1: Homebrew (Recommended)

brew install vicentereig/tap/whatsapp-cli

Or tap first, then install:

brew tap vicentereig/tap
brew install whatsapp-cli

Method 2: Download Pre-built Binary

# Linux (x86_64)
curl -LO https://github.com/vicentereig/whatsapp-cli/releases/latest/download/whatsapp-cli-linux-amd64.tar.gz
tar -xzf whatsapp-cli-linux-amd64.tar.gz
sudo mv whatsapp-cli-linux-amd64 /usr/local/bin/whatsapp-cli

# macOS (ARM64 - M1/M2/M3)
curl -LO https://github.com/vicentereig/whatsapp-cli/releases/latest/download/whatsapp-cli-darwin-arm64.tar.gz
tar -xzf whatsapp-cli-darwin-arm64.tar.gz
sudo mv whatsapp-cli-darwin-arm64 /usr/local/bin/whatsapp-cli

# macOS (Intel)
curl -LO https://github.com/vicentereig/whatsapp-cli/releases/latest/download/whatsapp-cli-darwin-amd64.tar.gz
tar -xzf whatsapp-cli-darwin-amd64.tar.gz
sudo mv whatsapp-cli-darwin-amd64 /usr/local/bin/whatsapp-cli

# Windows (x86_64) - download and extract whatsapp-cli-windows-amd64.zip from releases page

Method 3: Build from Source

# Clone repository
git clone https://github.com/vicentereig/whatsapp-cli.git
cd whatsapp-cli

# Install dependencies
go mod download

# Build
go build -o whatsapp-cli .

# Install (optional)
sudo mv whatsapp-cli /usr/local/bin/

# Verify installation
whatsapp-cli --help

Method 4: Install via Go

go install github.com/vicentereig/whatsapp-cli@latest

Release & Distribution Notes

  • Version tags use semantic versioning (vMAJOR.MINOR.PATCH). For reproducible builds, use a specific tag, for example v1.0.0, with go install github.com/vicentereig/whatsapp-cli@v1.0.0.
  • The GitHub Releases page has pre-built artifacts for Linux, macOS, and Windows. Each archive has a matching SHA-256 entry in checksums.txt. Before you install, run shasum -a 256 -c checksums.txt --ignore-missing to verify the archive.
  • Binaries use the name whatsapp-cli-<os>-<arch> (Windows adds .exe). After you extract the file, mark it executable with chmod +x and place it in your PATH, for example /usr/local/bin/whatsapp-cli.
  • Each uploaded file, including checksums.txt, also has a Sigstore cosign signature (.sig) and certificate (.pem). To verify a file, run cosign verify-blob --certificate <file>.pem --signature <file>.sig <file>. GitHub Actions uses OIDC identities, so you can enforce provenance during verification.
  • To build from source, follow Method 3. Use this method to audit the code, change compilation flags, or test changes before you tag a release.
  • Maintainers can follow the steps in docs/RELEASE.md. It covers go install, source builds, and GitHub Release automation.

Quick Start

Step 1: First-Time Authentication

whatsapp-cli auth

What happens:

  1. QR code appears in terminal
  2. Open WhatsApp on your phone → Settings → Linked Devices → Link a Device
  3. Scan the QR code
  4. Session saved to ./store/whatsapp.db

Output:

{
  "success": true,
  "data": {
    "authenticated": true,
    "message": "Successfully authenticated"
  },
  "error": null
}

Session Duration: ~20 days before re-authentication required

Step 2: Sync Messages

Before you list or search messages, sync them from WhatsApp:

# Start syncing messages (run this in the background or a separate terminal)
whatsapp-cli sync
# Press Ctrl+C when done syncing

What happens:

  1. Connects to WhatsApp and stays connected
  2. Downloads message history from WhatsApp servers
  3. Receives new messages in real-time
  4. Stores everything in ./store/messages.db
  5. Runs until you press Ctrl+C

Tip: Run sync in a tmux or screen session, or as a background service, so it keeps receiving messages.

Step 3: Basic Operations

# List your chats
whatsapp-cli chats list --limit 10

# Search for a contact
whatsapp-cli contacts search --query "John"

# Send a message
whatsapp-cli send --to 1234567890 --message "Hello from CLI!"

# Search messages
whatsapp-cli messages search --query "meeting"

Step 4: Check the Installed Version

whatsapp-cli version

Example Output:

{
  "success": true,
  "data": {
    "version": "v1.1.0"
  },
  "error": null
}

Complete Command Reference

Global Options

All commands support these global flags:

FlagTypeDefaultDescription
--storestring./storeDirectory for session and message databases

Example:

whatsapp-cli --store /var/lib/whatsapp chats list

Command: auth

Authenticate with WhatsApp via QR code.

Syntax:

whatsapp-cli auth

Parameters: None

Returns:

{
  "success": true,
  "data": {
    "authenticated": boolean,
    "message": string
  },
  "error": null
}

Behavior:

  • If already authenticated: Returns success immediately
  • If not authenticated: Displays QR code and waits for scan
  • Timeout: 5 minutes
  • Creates store/whatsapp.db with session data

Example:

whatsapp-cli auth
# Scan QR code with phone
# ✓ Successfully authenticated!

Command: sync

⚠️ IMPORTANT: Run this command to fill the message database. If you do not run sync, messages list and messages search return empty results.

Sync messages from WhatsApp to the local database continuously. This command:

  • Downloads message history from WhatsApp servers
  • Receives new messages in real time
  • Stores all messages in the SQLite database
  • Runs until you press Ctrl+C

Syntax:

whatsapp-cli sync

Parameters: None

Returns: (on exit via Ctrl+C)

{
  "success": true,
  "data": {
    "synced": true,
    "messages_count": 1234
  },
  "error": null
}

Behavior:

  • Connects to WhatsApp (authenticates if needed)
  • Registers event handlers for incoming messages and history sync
  • Processes *events.Message for real-time messages
  • Processes *events.HistorySync for message history batches
  • Stores all messages in store/messages.db
  • Sends progress to stderr (does not affect JSON output)
  • Runs until interrupted (Ctrl+C)
  • Disconnects on exit

Progress Output (stderr):

🚀 Starting WhatsApp sync...
✓ Connected to WhatsApp
🔄 Listening for messages... (Press Ctrl+C to stop)
📜 Processing history sync (42 conversations)...
💬 Synced 1234 messages...
^C
✓ Sync completed. Total messages synced: 1234

Examples:

# Basic sync - run in foreground
whatsapp-cli sync

# Run in background (recommended for continuous syncing)
whatsapp-cli sync > sync.json 2> sync.log &

# Run in tmux/screen session
tmux new -s whatsapp
whatsapp-cli sync
# Detach with Ctrl+B D

# Run with custom storage directory
whatsapp-cli --store /var/lib/whatsapp sync

# Stop sync gracefully
kill -INT <pid>
# Or press Ctrl+C in foreground

Use Cases:

  1. Initial Setup: Run once to download all message history
  2. Continuous Sync: Run as background service to receive messages
  3. Periodic Sync: Run via cron to update messages on a schedule
  4. Development: Run in terminal while testing queries

Notes:

  • Message history sync can take time. The duration depends on the number of messages.
  • SQLite PRIMARY KEY constraints prevent duplicate messages.
  • The CLI does not download media files. It stores only metadata: type, filename, and URL.
  • The connection stays open until you interrupt it.
  • You can restart the sync safely. It does not create duplicate messages.

Command: messages list

List messages from all chats or a specific chat.

Syntax:

whatsapp-cli messages list [OPTIONS]

Parameters:

FlagTypeRequiredDefaultDescription
--chatstringNo-Filter by chat JID (e.g., 1234567890@s.whatsapp.net)
--limitintNo20Maximum number of messages to return
--pageintNo0Page number for pagination (0-indexed)

Returns:

{
  "success": true,
  "data": [
    {
      "id": "msg_unique_id",
      "chat_jid": "1234567890@s.whatsapp.net",
      "chat_name": "John Doe",
      "sender": "1234567890",
      "content": "Message text content",
      "timestamp": "2025-10-26T10:30:00Z",
      "is_from_me": false,
      "media_type": ""
    }
  ],
  "error": null
}

Examples:

# List 50 most recent messages across all chats
whatsapp-cli messages list --limit 50

# List messages from specific chat
whatsapp-cli messages list --chat 1234567890@s.whatsapp.net

# Pagination: Get second page of results
whatsapp-cli messages list --limit 20 --page 1

# Get JID first, then list messages
JID=$(whatsapp-cli contacts search --query "Alice" | jq -r '.data[0].jid')
whatsapp-cli messages list --chat "$JID" --limit 100

Sorting: Messages returned in reverse chronological order (newest first)


Command: messages search

Search messages by content across all chats.

Syntax:

whatsapp-cli messages search --query TEXT [OPTIONS]

Parameters:

FlagTypeRequiredDefaultDescription
--querystringYes-Search term (case-insensitive, partial match)
--limitintNo20Maximum number of results
--pageintNo0Page number for pagination

Returns: Same format as messages list

Examples:

# Search for messages containing "meeting"
whatsapp-cli messages search --query "meeting"

# Search with more results
whatsapp-cli messages search --query "project" --limit 100

# Case-insensitive search
whatsapp-cli messages search --query "URGENT"  # Finds "urgent", "Urgent", etc.

Search Behavior:

  • Case-insensitive
  • Partial word matching
  • Searches message content only (not sender names)
  • Returns messages from all chats

Command: contacts search

Search contacts by name or phone number.

Syntax:

whatsapp-cli contacts search --query TEXT

Parameters:

FlagTypeRequiredDefaultDescription
--querystringYes-Search term for name or phone number

Returns:

{
  "success": true,
  "data": [
    {
      "phone_number": "1234567890",
      "name": "John Doe",
      "jid": "1234567890@s.whatsapp.net"
    }
  ],
  "error": null
}

Examples:

# Search by name
whatsapp-cli contacts search --query "John"

# Search by partial phone number
whatsapp-cli contacts search --query "5551234"

# Extract JID for further operations
JID=$(whatsapp-cli contacts search --query "Alice" | jq -r '.data[0].jid')
echo "Alice's JID: $JID"

Behavior:

  • Returns maximum 50 results
  • Excludes group chats (only individual contacts)
  • Sorted alphabetically by name
  • Partial matching on both name and JID

Command: chats list

List all chats sorted by recent activity.

Syntax:

whatsapp-cli chats list [OPTIONS]

Parameters:

FlagTypeRequiredDefaultDescription
--querystringNo-Filter chats by name or JID
--limitintNo20Maximum number of chats
--pageintNo0Page number for pagination

Returns:

{
  "success": true,
  "data": [
    {
      "jid": "1234567890@s.whatsapp.net",
      "name": "John Doe",
      "last_message_time": "2025-10-26T10:30:00Z"
    }
  ],
  "error": null
}

Examples:

# List 20 most recent chats
whatsapp-cli chats list

# List all chats (with pagination)
whatsapp-cli chats list --limit 100

# Filter chats by name
whatsapp-cli chats list --query "Team"

# Get list of all group chats
whatsapp-cli chats list | jq '.data[] | select(.jid | endswith("@g.us"))'

Sorting: Chats ordered by last_message_time (most recent first)

Chat Types:

  • Individual chats: JID ends with @s.whatsapp.net
  • Group chats: JID ends with @g.us

Command: send

Send a text message to an individual or group.

Syntax:

whatsapp-cli send --to RECIPIENT --message TEXT

Parameters:

FlagTypeRequiredDefaultDescription
--tostringYes-Phone number or JID
--messagestringYes-Message text content

Recipient Formats:

FormatExampleUse Case
Phone number1234567890Individual chats (auto-converted to JID)
Individual JID1234567890@s.whatsapp.netIndividual chats
Group JID123456789@g.usGroup chats (must use JID)

Returns:

{
  "success": true,
  "data": {
    "sent": true,
    "recipient": "1234567890",
    "message": "Hello!"
  },
  "error": null
}

Examples:

# Send to individual (phone number)
whatsapp-cli send --to 1234567890 --message "Hello from CLI!"

# Send to individual (full JID)
whatsapp-cli send --to 1234567890@s.whatsapp.net --message "Hi there!"

# Send to group (requires JID)
whatsapp-cli send --to 123456789@g.us --message "Hello everyone!"

# Send with special characters (use quotes)
whatsapp-cli send --to 1234567890 --message "It's working! 🎉"

# Multi-line messages
whatsapp-cli send --to 1234567890 --message "Line 1
Line 2
Line 3"

# Send result of command
whatsapp-cli send --to 1234567890 --message "Server status: $(uptime)"

Behavior:

  • Requires active connection (authenticates if needed)
  • Message stored locally in database
  • Returns immediately after sending (does not wait for delivery)
  • Supports Unicode (emojis, international characters)

Limitations:

  • The send command supports text messages only. To download attachments, use media download.
  • No delivery/read receipt information returned
  • Maximum message length: WhatsApp's standard limit (~65,536 characters)

Command: media download

Download media attachments (images, videos, audio, documents) that sync stored in the local database.

Syntax:

whatsapp-cli media download --message-id ID [--chat JID] [--output PATH]

Parameters:

FlagTypeRequiredDescription
--message-idstringYesMessage identifier from messages list/search
--chatstringNoChat JID to disambiguate duplicate message IDs
--outputstringNoDestination file or directory (defaults to auto-structured path)

Default storage:

  • The CLI stores media next to the SQLite databases, under STORE/media/{chat}/{message}/{media_type}/filename
  • The CLI sanitizes paths automatically
  • If --output points to a directory, the CLI uses the original filename (or a name based on the message ID)

Return value:

{
  "success": true,
  "data": {
    "message_id": "ABCD1234",
    "chat_jid": "1234567890@s.whatsapp.net",
    "path": "/path/to/media/1234567890@s.whatsapp.net/ABCD1234/image/ABCD1234.jpg",
    "bytes": 204800,
    "media_type": "image",
    "mime_type": "image/jpeg",
    "downloaded_at": "2025-02-01T12:34:56.789Z"
  },
  "error": null
}

Examples:

# Download image using auto-organised directory layout
whatsapp-cli media download --message-id ABCD1234

# Save into a specific directory (filename auto-generated)
whatsapp-cli media download --message-id ABCD1234 --output /tmp/media/

# Save using explicit path and disambiguate by chat JID
whatsapp-cli media download --message-id XYZ987 --chat 1234567890@s.whatsapp.net --output ~/Downloads/report.pdf

Notes:

  • Requires that whatsapp-cli sync captured the message metadata first
  • The sync loop downloads media in the background, without blocking new messages
  • If you run the command again, it overwrites the existing file with a fresh download
  • Errors include metadata issues (an expired link or a missing direct path) or file permission problems

JSON Response Format

All commands return JSON in this format:

Success Response

{
  "success": true,
  "data": <result_data>,
  "error": null
}

Error Response

{
  "success": false,
  "data": null,
  "error": "Error message describing what went wrong"
}

Data Types by Command

CommandData TypeStructure
authobject{"authenticated": bool, "message": string}
messages listarray[Message, ...]
messages searcharray[Message, ...]
contacts searcharray[Contact, ...]
chats listarray[Chat, ...]
sendobject{"sent": bool, "recipient": string, "message": string}

Usage Examples

Example 1: Send Daily Report via Cron

#!/bin/bash
# File: /usr/local/bin/daily-report.sh

RECIPIENT="1234567890"  # Your phone number

# Generate report
REPORT=$(cat <<EOF
📊 Daily Report - $(date +%Y-%m-%d)

Server Status: $(systemctl is-active nginx)
Disk Usage: $(df -h / | awk 'NR==2 {print $5}')
Memory: $(free -h | awk 'NR==2 {print $3 "/" $2}')
Uptime: $(uptime -p)
EOF
)

# Send via WhatsApp
whatsapp-cli send --to "$RECIPIENT" --message "$REPORT"

Cron entry:

0 9 * * * /usr/local/bin/daily-report.sh

Example 2: Search and Bulk Message

#!/bin/bash
# Send message to all contacts matching "Team"

CONTACTS=$(whatsapp-cli contacts search --query "Team" | jq -r '.data[].jid')

for JID in $CONTACTS; do
  whatsapp-cli send --to "$JID" --message "Team meeting at 3 PM today!"
  sleep 2  # Rate limiting
done

Example 3: Export Chat History

#!/bin/bash
# Export specific chat to JSON file

JID="1234567890@s.whatsapp.net"
OUTPUT_FILE="chat_export_$(date +%Y%m%d).json"

# Get all messages (paginated)
PAGE=0
ALL_MESSAGES=[]

while true; do
  RESPONSE=$(whatsapp-cli messages list --chat "$JID" --limit 100 --page $PAGE)
  MESSAGES=$(echo "$RESPONSE" | jq '.data')
  COUNT=$(echo "$MESSAGES" | jq 'length')

  if [ "$COUNT" -eq 0 ]; then
    break
  fi

  ALL_MESSAGES=$(echo "$ALL_MESSAGES" | jq ". + $MESSAGES")
  PAGE=$((PAGE + 1))
done

echo "$ALL_MESSAGES" | jq '.' > "$OUTPUT_FILE"
echo "Exported to $OUTPUT_FILE"

Example 4: Monitor for Keywords

#!/bin/bash
# Alert when specific keywords appear in messages

ALERT_RECIPIENT="your_phone@s.whatsapp.net"
LAST_CHECK_FILE="/tmp/whatsapp_last_check"

# Get timestamp of last check
if [ -f "$LAST_CHECK_FILE" ]; then
  LAST_CHECK=$(cat "$LAST_CHECK_FILE")
else
  LAST_CHECK=$(date -u -d "1 hour ago" +%Y-%m-%dT%H:%M:%SZ)
fi

# Search for urgent messages since last check
MESSAGES=$(whatsapp-cli messages search --query "URGENT" --limit 100 | \
  jq --arg since "$LAST_CHECK" '.data[] | select(.timestamp > $since)')

if [ -n "$MESSAGES" ]; then
  COUNT=$(echo "$MESSAGES" | jq -s 'length')
  whatsapp-cli send --to "$ALERT_RECIPIENT" \
    --message "⚠️ $COUNT urgent messages found!"
fi

# Update last check timestamp
date -u +%Y-%m-%dT%H:%M:%SZ > "$LAST_CHECK_FILE"

Integration with LLMs/AI Tools

Parsing JSON with jq

# Extract specific fields
whatsapp-cli contacts search --query "John" | jq '.data[0].jid'
# Output: "1234567890@s.whatsapp.net"

# Count results
whatsapp-cli chats list | jq '.data | length'
# Output: 42

# Filter and transform
whatsapp-cli messages list | jq '[.data[] | {name: .chat_name, msg: .content}]'

Python Integration

#!/usr/bin/env python3
import subprocess
import json

def whatsapp_cli(command):
    """Execute whatsapp-cli command and return parsed JSON."""
    result = subprocess.run(
        ['whatsapp-cli'] + command.split(),
        capture_output=True,
        text=True
    )
    return json.loads(result.stdout)

# Search contacts
contacts = whatsapp_cli('contacts search --query "Team"')
if contacts['success']:
    for contact in contacts['data']:
        print(f"{contact['name']}: {contact['jid']}")

# Send message
result = whatsapp_cli('send --to 1234567890 --message "Hello from Python!"')
print(f"Message sent: {result['success']}")

Node.js/TypeScript Integration

import { execSync } from 'child_process';

interface WhatsAppResponse<T> {
  success: boolean;
  data: T | null;
  error: string | null;
}

function whatsappCli<T>(command: string): WhatsAppResponse<T> {
  const output = execSync(`whatsapp-cli ${command}`).toString();
  return JSON.parse(output);
}

// Usage
const contacts = whatsappCli<Contact[]>('contacts search --query "Alice"');
if (contacts.success && contacts.data) {
  const jid = contacts.data[0].jid;
  whatsappCli(`send --to ${jid} --message "Hi from Node!"`);
}

Claude Code / Codex Integration

// Example Claude Code MCP tool wrapper

import { execSync } from 'child_process';

export const whatsappTools = {
  sendMessage: async (to: string, message: string) => {
    const result = execSync(
      `whatsapp-cli send --to "${to}" --message "${message}"`
    ).toString();
    return JSON.parse(result);
  },

  searchContacts: async (query: string) => {
    const result = execSync(
      `whatsapp-cli contacts search --query "${query}"`
    ).toString();
    return JSON.parse(result);
  },

  getRecentMessages: async (chatJid: string, limit = 20) => {
    const result = execSync(
      `whatsapp-cli messages list --chat "${chatJid}" --limit ${limit}`
    ).toString();
    return JSON.parse(result);
  }
};

// Use in Claude Code
const contacts = await whatsappTools.searchContacts("Alice");
if (contacts.success) {
  await whatsappTools.sendMessage(
    contacts.data[0].jid,
    "Automated message from Claude Code!"
  );
}

Data Model

Message Object

interface Message {
  id: string;                    // Unique message ID
  chat_jid: string;              // Chat identifier (JID)
  chat_name: string;             // Display name of chat
  sender: string;                // Phone number of sender
  content: string;               // Message text content
  timestamp: string;             // ISO 8601 timestamp
  is_from_me: boolean;           // true if sent by you
  media_type?: string;           // "image", "video", "audio", "document", or ""
}

Example:

{
  "id": "3EB0F2A8B9C4D1E5F6A7",
  "chat_jid": "1234567890@s.whatsapp.net",
  "chat_name": "John Doe",
  "sender": "1234567890",
  "content": "See you at the meeting!",
  "timestamp": "2025-10-26T14:30:00Z",
  "is_from_me": false,
  "media_type": ""
}

Contact Object

interface Contact {
  phone_number: string;          // Phone number (without country code prefix)
  name: string;                  // Display name
  jid: string;                   // WhatsApp JID
}

Example:

{
  "phone_number": "1234567890",
  "name": "John Doe",
  "jid": "1234567890@s.whatsapp.net"
}

Chat Object

interface Chat {
  jid: string;                   // Chat identifier
  name: string;                  // Display name
  last_message_time: string;     // ISO 8601 timestamp of last message
}

Example:

{
  "jid": "123456789@g.us",
  "name": "Project Team",
  "last_message_time": "2025-10-26T16:45:00Z"
}

JID (Jabber ID) Format

WhatsApp uses JIDs to identify chats:

TypeFormatExample
Individual{phone}@s.whatsapp.net1234567890@s.whatsapp.net
Group{group_id}@g.us120363012345678901@g.us

Extracting Components:

# Get phone number from individual JID
echo "1234567890@s.whatsapp.net" | cut -d'@' -f1
# Output: 1234567890

# Check if JID is a group
echo "$JID" | grep -q "@g.us" && echo "Group" || echo "Individual"

Storage & Persistence

Database Location

Default storage directory: ./store/

store/
├── whatsapp.db      # Session data (managed by whatsmeow)
└── messages.db      # Message history (managed by CLI)

Custom Location:

whatsapp-cli --store /var/lib/whatsapp chats list

Session Database (whatsapp.db)

  • Format: SQLite3
  • Managed by: whatsmeow library
  • Contents:
    • Device ID and encryption keys
    • Contact information
    • Session tokens
  • Persistence: ~20 days before re-authentication required
  • Security: Contains sensitive data. Protect it with file permissions.

Recommended Permissions:

chmod 600 store/whatsapp.db
chown $USER:$USER store/whatsapp.db

Message Database (messages.db)

  • Format: SQLite3
  • Managed by: WhatsApp CLI
  • Schema:
-- Chats table
CREATE TABLE chats (
    jid TEXT PRIMARY KEY,
    name TEXT,
    last_message_time TIMESTAMP
);

-- Messages table
CREATE TABLE messages (
    id TEXT,
    chat_jid TEXT,
    sender TEXT,
    content TEXT,
    timestamp TIMESTAMP,
    is_from_me BOOLEAN,
    media_type TEXT,
    filename TEXT,
    url TEXT,
    media_key BLOB,
    file_sha256 BLOB,
    file_enc_sha256 BLOB,
    file_length INTEGER,
    PRIMARY KEY (id, chat_jid),
    FOREIGN KEY (chat_jid) REFERENCES chats(jid)
);

Direct Database Access

# Open with sqlite3
sqlite3 store/messages.db

# Query examples
sqlite> SELECT COUNT(*) FROM messages;
sqlite> SELECT chat_name, COUNT(*) FROM messages
        JOIN chats ON messages.chat_jid = chats.jid
        GROUP BY chat_name;
sqlite> .quit

Backup & Migration

# Backup
tar -czf whatsapp-backup-$(date +%Y%m%d).tar.gz store/

# Restore
tar -xzf whatsapp-backup-20251026.tar.gz

# Migrate to new machine
rsync -avz store/ newserver:/path/to/store/

Authentication & Security

Authentication Flow

  1. First Run: QR code displayed
  2. User Action: Scan with WhatsApp mobile app
  3. Session Creation: Credentials saved to store/whatsapp.db
  4. Subsequent Runs: Auto-reconnect using saved session
  5. Expiration: After ~20 days, re-authentication required

Security Considerations

Session Protection

The store/whatsapp.db file contains your WhatsApp session credentials. Treat it like a password:

# Set proper permissions
chmod 600 store/whatsapp.db
chmod 700 store/

# Never commit to version control
echo "store/" >> .gitignore

# Use environment variable for custom location
export WHATSAPP_STORE="/secure/path/to/store"
whatsapp-cli --store "$WHATSAPP_STORE" chats list

Multi-Device Limit

WhatsApp allows up to 5 linked devices. If you reach this limit:

  1. Open WhatsApp on phone
  2. Go to Settings → Linked Devices
  3. Remove an old device
  4. Re-authenticate CLI

Network Security

  • All communication with WhatsApp uses end-to-end encryption
  • CLI communicates via WhatsApp Web protocol (WSS)
  • No data sent to third parties
  • Local storage only

Privacy

  • Message Storage: All messages stored locally in SQLite
  • No Cloud Sync: Data never leaves your machine
  • Media: Metadata stored, actual files downloaded on-demand
  • Deletion: Delete store/ directory to remove all data

Architecture

System Design

┌─────────────────────────────────────────────────┐
│                  whatsapp-cli                    │
│                   (Go Binary)                    │
├─────────────────────────────────────────────────┤
│  ┌───────────┐  ┌──────────┐  ┌─────────────┐  │
│  │  Commands │  │  Client  │  │   Storage   │  │
│  │   Layer   │→ │  Wrapper │→ │   (SQLite)  │  │
│  └───────────┘  └──────────┘  └─────────────┘  │
│        ↓             ↓                           │
│  ┌───────────┐  ┌──────────┐                    │
│  │   Output  │  │whatsmeow │                    │
│  │   (JSON)  │  │ Library  │                    │
│  └───────────┘  └──────────┘                    │
│                      ↓                           │
└──────────────────────┼──────────────────────────┘
                       ↓
              ┌────────────────┐
              │  WhatsApp Web  │
              │   API (WSS)    │
              └────────────────┘

Component Layers

LayerLocationResponsibility
CLImain.goArgument parsing, command routing
Commandsinternal/commands/Business logic for each command
Clientinternal/client/WhatsApp protocol wrapper
Storageinternal/store/Database operations
Outputinternal/output/JSON formatting

Dependencies

whatsmeow (github.com/tulir/whatsmeow)
├── WebSocket communication
├── Protocol buffer encoding/decoding
├── End-to-end encryption
└── Session management

go-sqlite3 (github.com/mattn/go-sqlite3)
└── SQLite database driver

qrterminal (github.com/mdp/qrterminal)
└── QR code rendering in terminal

Build Process

# Build with all dependencies statically linked
go build -ldflags="-s -w" -o whatsapp-cli .

# Cross-compile
GOOS=linux GOARCH=amd64 go build -o whatsapp-cli-linux .
GOOS=darwin GOARCH=arm64 go build -o whatsapp-cli-mac .
GOOS=windows GOARCH=amd64 go build -o whatsapp-cli.exe .

Binary Size Optimization:

# Standard build
go build -o whatsapp-cli .          # ~21MB

# Optimized build
go build -ldflags="-s -w" .         # ~15MB

# Ultra-compressed (requires UPX)
upx --best --lzma whatsapp-cli      # ~5MB

For more about the architecture, see docs/architecture.md.


Error Handling

Common Error Responses

Not Authenticated

{
  "success": false,
  "data": null,
  "error": "not authenticated"
}

Solution: Run whatsapp-cli auth

Connection Failed

{
  "success": false,
  "data": null,
  "error": "failed to connect: connection refused"
}

Solutions:

  • Check internet connection
  • Verify WhatsApp is active on phone
  • Check firewall rules

Invalid JID

{
  "success": false,
  "data": null,
  "error": "invalid JID format"
}

Solution: Use the correct JID format (phone@s.whatsapp.net or id@g.us)

Database Locked

{
  "success": false,
  "data": null,
  "error": "database is locked"
}

Solution: Close other instances of whatsapp-cli

Exit Codes

CodeMeaning
0Success
1General error (check JSON error field)

Troubleshooting

Authentication Issues

Problem: QR code does not appear

# Check terminal supports UTF-8
echo $LANG
# Should output: en_US.UTF-8 or similar

# Try with different QR code size
QRSIZE=small whatsapp-cli auth

Problem: "Session expired" after a few days

  • WhatsApp sessions expire after ~20 days
  • Re-run whatsapp-cli auth
  • Sessions also expire if you unlink the device from the phone

Connection Issues

Problem: "Connection timeout"

# Test network connectivity
ping -c 3 web.whatsapp.com

# Check DNS resolution
nslookup web.whatsapp.com

# Try with custom store path (permission issues)
whatsapp-cli --store /tmp/wa-test auth

Problem: "WebSocket connection failed"

  • Corporate firewalls can block WSS
  • A VPN can interfere with the connection
  • Try a different network

WhatsApp Web Version Bumps (405 / close 1006)

WhatsApp sometimes requires a newer desktop or web build. When that happens, the bundled whatsmeow dependency logs Client outdated (405). It then closes the websocket with code 1006. As a result, whatsapp-cli stops right after you scan the QR code.

To fix it:

  1. Bump the dependency:
    go get go.mau.fi/whatsmeow@latest
    go mod tidy
    
  2. Rebuild the binary:
    go build -o whatsapp-cli .
    
  3. Verify: Run ./whatsapp-cli version, then ./whatsapp-cli auth or ./whatsapp-cli sync. You will see ✓ Connected to WhatsApp with no Client outdated (405) messages.

If the upstream library does not yet have a new version, watch the tulir/whatsmeow issues for Client outdated (405) reports. Once a fix lands, repeat the steps above to update your local binary.

Database Issues

Problem: "Database is locked"

# Check for other processes
ps aux | grep whatsapp-cli

# Check for stale lock files
rm -f store/*.db-shm store/*.db-wal

# If corrupted, restore from backup
mv store/messages.db store/messages.db.bak
# Re-run cli to recreate

Problem: "Disk full" or "No space left"

# Check database size
du -h store/messages.db

# Vacuum database to reclaim space
sqlite3 store/messages.db "VACUUM;"

# Delete old messages
sqlite3 store/messages.db "DELETE FROM messages WHERE timestamp < datetime('now', '-30 days');"

Message Issues

Problem: Messages not appearing in searches

  • The CLI searches only messages stored locally
  • Messages received before the CLI was running are not stored
  • To re-sync, list messages from specific chats

Problem: Cannot send to a group

  • Use the group JID (it ends in @g.us), not a phone number
  • Get the group JID from the chats list command

Performance Issues

Problem: Slow searches on large databases

# Add indexes
sqlite3 store/messages.db <<EOF
CREATE INDEX IF NOT EXISTS idx_content ON messages(content);
CREATE INDEX IF NOT EXISTS idx_timestamp ON messages(timestamp);
CREATE INDEX IF NOT EXISTS idx_chat_jid ON messages(chat_jid);
EOF

Debug Mode

# Enable verbose logging (if implemented)
export WHATSAPP_DEBUG=1
whatsapp-cli chats list

# Check SQLite directly
sqlite3 store/messages.db "SELECT * FROM messages LIMIT 5;"

Development

Setting Up Development Environment

# Clone repository
git clone https://github.com/vicentereig/whatsapp-cli.git
cd whatsapp-cli

# Install dependencies
go mod download

# Run tests
go test ./...

# Run with race detector
go test -race ./...

# Build development version
go build -o whatsapp-cli-dev .

Building with a Local Module Cache

Some environments, for example sandboxes or CI systems, cannot write to the global Go module cache. If your environment has this limit, point GOMODCACHE to a writable directory in the repository before you build:

GOMODCACHE=$(pwd)/.gomodcache go build ./...

This command compiles the full project and stores downloaded modules under .gomodcache. The workspace then stays self-contained.

Running Tests

# All tests
go test ./...

# Specific package
go test ./internal/store

# With coverage
go test -cover ./...
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

# Verbose output
go test -v ./...

# Run specific test
go test -run TestStoreMessage ./internal/store

Code Structure

internal/
├── client/
│   └── client.go          # WhatsApp client wrapper
├── commands/
│   └── commands.go        # CLI command implementations
├── output/
│   ├── output.go          # JSON formatting
│   └── output_test.go     # Output tests
└── store/
    ├── store.go           # Database operations
    └── store_test.go      # Storage tests

Adding New Commands

  1. Define command in internal/commands/commands.go:
func (a *App) NewCommand(param string) string {
    // Implementation
    result := doSomething(param)
    return output.Success(result)
}
  1. Add routing in main.go:
case "newcommand":
    cmdFlags := flag.NewFlagSet("newcommand", flag.ExitOnError)
    param := cmdFlags.String("param", "", "description")
    cmdFlags.Parse(args[1:])
    result = app.NewCommand(*param)
  1. Write tests in internal/commands/commands_test.go:
func TestNewCommand(t *testing.T) {
    // Test implementation
}

Testing Guide

Follow TDD (Test-Driven Development):

  1. Write test first
  2. Run test (it fails)
  3. Implement feature
  4. Run test (it passes)
  5. Refactor

Example:

// store_test.go
func TestStoreMessage(t *testing.T) {
    store := setupTestDB(t)
    err := store.StoreMessage("id1", "chat@s.whatsapp.net", "sender",
        "Hello", time.Now(), false, "", "", "", nil, nil, nil, 0)
    assert.NoError(t, err)
}

Contributing

See CONTRIBUTING.md for guidelines.


FAQ

General

Q: Is this an official WhatsApp tool? A: No. This is a third-party tool. It uses the unofficial WhatsApp Web protocol, through the whatsmeow library.

Q: Can I use this with WhatsApp Business? A: Yes. It works with personal and business accounts.

Q: Does this work on multiple devices simultaneously? A: Yes. WhatsApp supports up to 5 linked devices.

Features

Q: Can I send images/videos? A: Not yet. The CLI currently sends text only. Media support is planned for a future release.

Q: Can I create/manage groups? A: Not yet. The CLI currently gives read-only access to groups.

Q: Can I see delivery/read receipts? A: Not in the current version. This feature is planned for a future release.

Q: Can I receive real-time messages? A: Yes. Run whatsapp-cli sync to receive and store messages continuously. Run it in the background or in a tmux session.

Technical

Q: Why Go instead of Python/Node.js? A: Go gives single-binary distribution and strong performance. Also, whatsmeow is written in Go.

Q: Can I run this in Docker? A: Yes, but QR code authentication needs terminal access. Use the -it flags for interactive mode.

Q: Does it support proxy/VPN? A: The CLI respects system proxy settings. Set the HTTP_PROXY and HTTPS_PROXY environment variables.

Q: Can I access messages from before installing CLI? A: Yes. When you run whatsapp-cli sync, it downloads message history from WhatsApp servers. The amount of history depends on how long WhatsApp retains it on its servers.

Privacy & Security

Q: Is my data safe? A: The CLI stores all data locally, with no cloud sync. Protect your store/ directory.

Q: Can WhatsApp detect/ban this? A: The CLI uses the official WhatsApp Web protocol. The risk is low, but use it at your own discretion.

Q: Is end-to-end encryption maintained? A: Yes. WhatsApp's protocol encrypts all messages end-to-end.


Credits

Authors

  • Vicente Reig - Initial development
  • Built with assistance from Claude Code (Anthropic)

Dependencies

License

MIT License - see LICENSE file

Support

Acknowledgments

  • WhatsApp for the multidevice protocol
  • Tulir Asokan for the excellent whatsmeow library
  • Go community for excellent tooling
  • Anthropic for Claude Code

Last Updated: 2025-12-13 Version: 1.3.2 Documentation: https://github.com/vicentereig/whatsapp-cli/blob/main/README.md

常见问题

What is whatsapp-cli?

whatsapp-cli is an open-source api integration skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by vicentereig. Danger. Danger. High Voltage. Give your codex/claude access to WhatsApp. It has 173 GitHub stars.

Is whatsapp-cli safe to use?

Yes. whatsapp-cli passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.

How do I install whatsapp-cli?

Clone the repository with "git clone https://github.com/vicentereig/whatsapp-cli" and add it to your Claude Code skills directory (see the Installation section above).

What programming language is whatsapp-cli written in?

whatsapp-cli is primarily written in Go. It is open-source under vicentereig on GitHub, so you can review or fork the full source.

Are there alternatives to whatsapp-cli?

Yes. SkillsLLM lists many other API Integration skills you can browse and compare side by side. Open the API Integration category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh whatsapp-cli against similar tools.

评论 (0)

暂无评论,成为第一个分享想法的人!

CLIProxyAPI

by router-for-me

Wrap Antigravity, ChatGPT Codex, Claude Code, Grok Build as an OpenAI/Gemini/Claude/Codex compatible API service, allowing you to enjoy the free Gemini 3.1 Pro, GPT 5.6 Series, Grok 4.5, Claude model through API

48,3767,452Go
API Integration
查看详情

sub2api

by Wei-Shaw

Sub2API 一站式开源中转服务,让 Claude、Openai 、Gemini、Grok订阅统一接入,支持拼车共享,更高效分摊成本,原生工具无缝使用。

38,8308,041Go
API Integration
查看详情

claude-code-hub

by ding113

一个现代化的 Claude Code & Codex API 代理服务,提供智能负载均衡、用户管理和使用统计功能。

3,328387TypeScript
API Integration
查看详情

cc-gateway

by motiful

AI API identity gateway — reverse proxy that normalizes device fingerprints and telemetry for privacy-preserving API proxying

3,013501TypeScript
API Integration
查看详情

octopus

by bestruirui

One Hub All LLMs For You | 为个人打造的 LLM API 聚合网关

2,483394TypeScript
API Integration
查看详情

开发者还喜欢

基于喜欢此 Skill 的开发者投票和收藏

ECC

by affaan-m

10

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

242,21936,702JavaScript
AI 智能体ai-agentsanthropicclaude-code
查看详情
15

An agentic skills framework & software development methodology that works.

234,96620,863Shell
AI 智能体ai-agentsbrainstorming
查看详情

hermes-agent

by NousResearch

10

The agent that grows with you

234,43747,175Python
AI 智能体ai-agentsagent-orchestration
查看详情

n8n

by n8n-io

12

Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.

201,88160,308TypeScript
MCP 服务器apisai-tools
查看详情

The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.

185,94028,768JavaScript
AI 智能体ai-agentsanthropicclaude-code
查看详情

cc-switch

by farion1231

3

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

128,8688,826Rust
AI 智能体claude-codeai-tools
查看详情
whatsapp-cli — Claude Code AI Skill | SkillTip