npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

chat-adapter-baileys

v1.1.0

Published

WhatsApp (Baileys) adapter for Chat SDK

Downloads

775

Readme

chat-adapter-baileys

WhatsApp (Baileys) adapter for the Chat SDK.

[!WARNING] This adapter uses Baileys, a third-party unofficial WhatsApp Web API. It is not an official WhatsApp/Meta API and may break when WhatsApp changes internal protocols. WhatsApp may also suspend or ban numbers/accounts that use unofficial automation. Use at your own risk and evaluate compliance requirements before production use.

...with that out of the way, let's continue with the docs.

This package lets you run Chat SDK bots on WhatsApp via Baileys. It handles the WhatsApp WebSocket connection, message parsing, formatting, media attachments, reactions, and typing indicators — so you can focus on your bot logic.

Install

pnpm add chat-adapter-baileys baileys chat @chat-adapter/state-memory

Optional — for terminal QR rendering during development:

pnpm add qrcode

Quick Start

The setup has six steps: prepare auth, create the adapter, create a Chat instance, register handlers, initialize chat, then connect. Always register handlers before connecting — messages can arrive as soon as connect() is called.

import { Chat } from "chat";
import { createMemoryState } from "@chat-adapter/state-memory";
import { useMultiFileAuthState } from "baileys";
import { createBaileysAdapter } from "chat-adapter-baileys";

// 1. Load (or create) the session credentials
const { state, saveCreds } = await useMultiFileAuthState("./auth_info");

// 2. Create the adapter
const whatsapp = createBaileysAdapter({
  auth: { state, saveCreds },
  userName: "my-bot",
  // Called when a QR code is available — scan with WhatsApp → Linked Devices
  onQR: async (qr) => {
    const QRCode = await import("qrcode");
    console.log(await QRCode.toString(qr, { type: "terminal" }));
  },
});

// 3. Create the Chat instance
const bot = new Chat({
  userName: "my-bot",
  adapters: { whatsapp },
  state: createMemoryState(),
});

// 4. Register handlers
bot.onNewMention(async (thread, message) => {
  // Fires when the bot is @-mentioned in a group it hasn't subscribed to
  await thread.post(`Hello ${message.author.userName}!`);
  await thread.subscribe(); // subscribe so follow-up messages are also handled
});

bot.onSubscribedMessage(async (thread, message) => {
  // Fires for every message in a subscribed thread
  if (message.author.isMe) return;
  await thread.post(`You said: ${message.text}`);
});

bot.onNewMessage(/.+/, async (thread, message) => {
  // Fires for any message matching the pattern in an unsubscribed thread
  if (!thread.isDM || message.author.isMe) return;
  await thread.post(`DM received: ${message.text}`);
});

// 5. Initialize Chat so adapters are attached
await bot.initialize();

// 6. Connect — open the WhatsApp WebSocket
await whatsapp.connect();

Credentials are saved to ./auth_info on first login. Subsequent startups reuse the saved session — no QR scan needed.

Multi-Account Support

Run one adapter instance per WhatsApp account. Give each a unique adapterName to avoid thread ID collisions:

const { state: stateMain, saveCreds: saveMain } = await useMultiFileAuthState("./auth_main");
const { state: stateSales, saveCreds: saveSales } = await useMultiFileAuthState("./auth_sales");

const waMain = createBaileysAdapter({
  adapterName: "baileys-main",   // unique — used as thread ID prefix
  auth: { state: stateMain, saveCreds: saveMain },
});

const waSales = createBaileysAdapter({
  adapterName: "baileys-sales",
  auth: { state: stateSales, saveCreds: saveSales },
});

const bot = new Chat({
  userName: "my-bot",
  adapters: { whatsappMain: waMain, whatsappSales: waSales },
  state: createMemoryState(),
});

await bot.initialize();
await waMain.connect();
await waSales.connect();

All handlers receive messages from both accounts. The thread ID prefix (baileys-main: vs baileys-sales:) tells you which account a message came from.

Adapter Config

createBaileysAdapter({
  // Unique name for this adapter — used as thread ID prefix. No ":" allowed.
  adapterName: "baileys",           // default

  // Required. Your Baileys auth state + credential-save callback.
  auth: { state, saveCreds },

  // Display name for the bot in Chat SDK logs.
  userName: "my-bot",

  // Override the WhatsApp Web protocol version. Fetched automatically if omitted.
  version: [2, 3000, 1015901307],

  // Called with a QR string when a new QR is available. Render it however you like.
  onQR: async (qr) => { /* ... */ },

  // Phone number for pairing-code auth (E.164, no "+"). Use instead of onQR.
  phoneNumber: "12345678901",

  // Called with the 8-digit pairing code. User enters it in WhatsApp → Linked Devices.
  onPairingCode: (code) => { /* ... */ },

  // Advanced: extra options passed directly to Baileys' makeWASocket().
  socketOptions: {},
});

WhatsApp Extensions

BaileysAdapter exposes extra methods for WhatsApp features that have no equivalent in the Chat SDK interface:

| Method | Description | |---|---| | whatsapp.reply(message, text) | Send a quoted reply (native WhatsApp reply bubble) | | whatsapp.markRead(threadId, messageIds) | Send read receipts (blue double-ticks) | | whatsapp.setPresence("available" \| "unavailable") | Set bot's global online/offline status | | whatsapp.sendLocation(threadId, lat, lon, options?) | Send a native location pin | | whatsapp.sendPoll(threadId, question, options, selectableCount?) | Send a WhatsApp poll | | whatsapp.fetchGroupParticipants(threadId) | List group members with admin roles |

For multi-account setups, use createBaileysExtensions(waMain, waSales) to get a router that auto-selects the right adapter — no manual routing needed.

See Extensions for full documentation and examples.

Behavior Notes

  • Transport: WebSocket-based (connect()), not HTTP webhooks. handleWebhook() returns 501.
  • Message history: fetchMessages() / fetchChannelMessages() return empty arrays — WhatsApp has no REST history API. Persist messages.upsert events yourself if you need history.
  • Cards: Sent as plain-text fallback — WhatsApp has no native card format.
  • Media: Incoming attachments include a lazy fetchData() for on-demand binary download.
  • Reconnect: Automatic on unexpected disconnects. Does not reconnect after logout or explicit disconnect().

Development

pnpm typecheck
pnpm test
pnpm build

Docs

License

MIT