Back to Blog
TutorialFebruary 2, 202614 min

How to Use ChatGPT on WhatsApp (Self-Hosted Guide)

Run ChatGPT or Claude on WhatsApp with Baileys. Complete self-hosted setup guide with code examples and deployment options.

whatsappchatgptclaudeself-hostedbaileysai chatbot

Molted Team

Molted.cloud

ChatGPT on WhatsApp sounds like a dream: ask questions, get instant AI responses, all within the app you already use daily. The official Meta AI integration exists but it is limited. Self-hosting gives you full control over the model, conversation history, and privacy.

This guide shows two paths: build it yourself with Baileys and Node.js, or deploy OpenClaw which handles the WhatsApp integration out of the box.

Why self-host ChatGPT on WhatsApp?

  • Privacy - Your conversations stay on your server, not Meta's
  • Model choice - Use Claude, GPT-4, Llama, or any model you prefer
  • No limits - No rate limits imposed by third-party services
  • Custom behavior - Add system prompts, tools, memory
  • Cost control - Use your existing API subscription

Option 1: Build with Baileys

Baileys is the most popular WhatsApp Web library for Node.js. It connects to WhatsApp via the web protocol, no official API needed.

Prerequisites

  • Node.js 18+
  • A WhatsApp account (will be paired via QR code)
  • OpenAI or Anthropic API key

Project setup

mkdir whatsapp-ai
cd whatsapp-ai
npm init -y
npm install @whiskeysockets/baileys @anthropic-ai/sdk qrcode-terminal

Create .env:

ANTHROPIC_API_KEY=your-key-here

Basic bot code

require('dotenv').config();
const { default: makeWASocket, useMultiFileAuthState, DisconnectReason } = require('@whiskeysockets/baileys');
const Anthropic = require('@anthropic-ai/sdk');
const qrcode = require('qrcode-terminal');

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

// Store conversation history per chat
const conversations = new Map();

async function connectToWhatsApp() {
  const { state, saveCreds } = await useMultiFileAuthState('auth_info');

  const sock = makeWASocket({
    auth: state,
    printQRInTerminal: false,
  });

  sock.ev.on('connection.update', async (update) => {
    const { connection, lastDisconnect, qr } = update;

    if (qr) {
      qrcode.generate(qr, { small: true });
      console.log('Scan the QR code above with WhatsApp');
    }

    if (connection === 'close') {
      const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
      if (shouldReconnect) {
        connectToWhatsApp();
      }
    } else if (connection === 'open') {
      console.log('Connected to WhatsApp');
    }
  });

  sock.ev.on('creds.update', saveCreds);

  sock.ev.on('messages.upsert', async ({ messages }) => {
    const msg = messages[0];
    if (!msg.message || msg.key.fromMe) return;

    const chatId = msg.key.remoteJid;
    const text = msg.message.conversation ||
                 msg.message.extendedTextMessage?.text || '';

    if (!text) return;

    // Get or create conversation history
    if (!conversations.has(chatId)) {
      conversations.set(chatId, []);
    }
    const history = conversations.get(chatId);

    // Add user message
    history.push({ role: 'user', content: text });

    // Keep last 20 messages
    if (history.length > 20) {
      history.splice(0, history.length - 20);
    }

    try {
      // Send typing indicator
      await sock.sendPresenceUpdate('composing', chatId);

      // Call Claude
      const response = await anthropic.messages.create({
        model: 'claude-sonnet-4-20250514',
        max_tokens: 1024,
        system: 'You are a helpful WhatsApp assistant. Keep responses concise for mobile reading.',
        messages: history,
      });

      const reply = response.content[0].text;

      // Add to history
      history.push({ role: 'assistant', content: reply });

      // Send response
      await sock.sendMessage(chatId, { text: reply });
    } catch (error) {
      console.error('Error:', error);
      await sock.sendMessage(chatId, { text: 'Sorry, I encountered an error.' });
    }
  });
}

connectToWhatsApp();

Run it

node index.js

Scan the QR code with WhatsApp (Settings → Linked Devices → Link a Device). Once connected, any message sent to this WhatsApp number will get an AI response.

Want it easier?

OpenClaw handles WhatsApp pairing with a web UI. No code needed.

Start free trial

Option 2: Use OpenAI instead of Claude

npm install openai
const OpenAI = require('openai');
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

// Replace the Claude call with:
const response = await openai.chat.completions.create({
  model: 'gpt-4o',
  max_tokens: 1024,
  messages: [
    { role: 'system', content: 'You are a helpful WhatsApp assistant.' },
    ...history,
  ],
});

const reply = response.choices[0].message.content;

Handling media messages

WhatsApp supports images, voice notes, and documents. To handle images with vision models:

sock.ev.on('messages.upsert', async ({ messages }) => {
  const msg = messages[0];
  if (!msg.message) return;

  const chatId = msg.key.remoteJid;

  // Handle image messages
  if (msg.message.imageMessage) {
    const buffer = await downloadMediaMessage(msg, 'buffer', {});
    const base64 = buffer.toString('base64');

    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 1024,
      messages: [{
        role: 'user',
        content: [
          {
            type: 'image',
            source: {
              type: 'base64',
              media_type: 'image/jpeg',
              data: base64,
            },
          },
          {
            type: 'text',
            text: msg.message.imageMessage.caption || 'What is in this image?',
          },
        ],
      }],
    });

    await sock.sendMessage(chatId, { text: response.content[0].text });
  }
});

Persistence and reliability

For production, add proper error handling and session persistence:

// Use PM2 for process management
// pm2 start index.js --name whatsapp-ai

// Add reconnection logic
let reconnectAttempts = 0;
const MAX_RECONNECTS = 5;

sock.ev.on('connection.update', async (update) => {
  const { connection, lastDisconnect } = update;

  if (connection === 'close') {
    const statusCode = lastDisconnect?.error?.output?.statusCode;

    if (statusCode === DisconnectReason.loggedOut) {
      console.log('Logged out. Delete auth_info folder and restart.');
      return;
    }

    if (reconnectAttempts < MAX_RECONNECTS) {
      reconnectAttempts++;
      console.log(`Reconnecting... attempt ${reconnectAttempts}`);
      setTimeout(connectToWhatsApp, 5000 * reconnectAttempts);
    }
  } else if (connection === 'open') {
    reconnectAttempts = 0;
    console.log('Connected');
  }
});

Security considerations

  • Allowlist - Only respond to specific phone numbers
  • Rate limiting - Prevent abuse and API cost spikes
  • Content filtering - Block harmful requests
const ALLOWED_NUMBERS = [
  '1234567890@s.whatsapp.net',
  '0987654321@s.whatsapp.net',
];

sock.ev.on('messages.upsert', async ({ messages }) => {
  const msg = messages[0];
  const chatId = msg.key.remoteJid;

  // Only respond to allowed numbers
  if (!ALLOWED_NUMBERS.includes(chatId)) {
    return;
  }

  // ... rest of handler
});

Skip the code entirely

Molted deploys OpenClaw with WhatsApp ready. QR pairing from a web UI, no coding.

Try free for 24 hours

Option 3: Deploy OpenClaw

If you want WhatsApp AI without maintaining code, OpenClaw (formerly MoltBot) includes WhatsApp integration. The setup is:

  1. Deploy OpenClaw instance on Molted (or self-host)
  2. Go to Channels → WhatsApp
  3. Scan QR code from the web UI
  4. Done. Messages flow through instantly.

OpenClaw handles reconnection, session persistence, and multi-device sync automatically. You can switch between Claude, GPT-4, or other models from the config without touching code.

Cost comparison

ApproachMonthly costEffort
DIY Baileys + API$5-50 (API usage)High (code + maintain)
OpenClaw on VPS$5-10 (hosting) + APIMedium (deploy + configure)
OpenClaw on Molted$5-10/monthLow (click + scan)

The DIY approach is great for learning and full customization. OpenClaw makes sense when you want it working reliably without ongoing maintenance.

Related guides

Free 24-hour trial

WhatsApp AI in 60 seconds

OpenClaw on Molted includes WhatsApp integration. Scan QR, start chatting.

Start free trial

24-hour free trial · No credit card required · Cancel anytime

Ready to try OpenClaw?

Deploy your AI personal assistant in 60 seconds. No coding required.

Start free trial

24-hour free trial · No credit card required