New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more β†’
Get Started

lunaaa-baileys

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lunaaa-baileys

Modded Baileys with interactive message, album, newsletter, and VoIP support

latest
npmnpm
Version
9.0.23
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
Β 
Created
Source

Modded Baileys V7 Forked From ourin-baileys β€” Interactive Messages, AI Rich Responses, Albums & More

npm version npm downloads License Node ESM

A modded build of WhiskeySockets/Baileys with native support for interactive messages, album messages, unified rich responses, newsletter helpers, status mentions, and additional business/community utilities.

This repository is a distribution/build repo for lunaaa-baileys. It ships compiled runtime files in lib/ and protobuf artifacts in WAProto/, and is intended to be consumed directly from npm or as a vendored dependency inside the Luna-MD ecosystem.

πŸ†• Changelog / Updates (v2.0.2)

1. Fix additionalNodes Conflict (v2.0.2)

  • Fixed an issue where supplying a custom <biz> node in additionalNodes alongside interactive messages caused duplicate <biz> nodes in the stanza, which led to the message being silently rejected by WhatsApp.

2. Built-in VoIP (Voice Call) Engine (v9.0.0)

  • Full integration of the WebRTC and WASM engines to enable native WhatsApp voice calling, eliminating the need for a separate package.

2. Fix View Once Error (Anti-Crash)

  • WhatsApp (Meta) Web API no longer receives media content for View Once messages, which previously caused the socket to crash. We've added robust parsing (viewOnceMessageV3 & ptvMessage) to gracefully handle these empty stubs without crashing your bot.

2. Decryption Retry Fix (Private Chats)

  • Fixed an issue in messages-recv.js where "Bad MAC" / decryption errors would close the connection. Combined with a proper getMessage hook in your main connection setup, the bot now seamlessly retries failed decryptions.
  • Browser parameter spoofing upgraded to MacOS to prevent Error 405 (Method Not Allowed) during pairing.

3. AI Rich Implementation (ORich)

  • Added the ORich class (an extension of AIRich from message_builder.js) to generate stunning AI response layouts easily.

  • Example Usage:

    import { ORich } from 'lunaaa-baileys';
    
    const luna = new ORich(sock)
      .addText('Hello from ORich AI!')
      .addSuggest(['Tell me more', 'Next']);
    
    await luna.send(jid);
    

Table of Contents

✨ Features

FeatureDescriptionStatus
VoIP Voice CallsNative VoIP engine (WASM/WebRTC) via VoipClient, single shared socketβœ…
Interactive MessagesNative flow buttons, list/select menus, button wrappers, carousel support via Dugongβœ…
Album MessagesMulti-image/video album relay with count metadata and grouped deliveryβœ…
Rich Response HelperssendTable, sendList, sendCodeBlock, sendRichMessage, sendUnifiedResponseβœ…
Unified Response V2sendTableV2, sendCodeBlockV2, sendLinkV2 with Meta-AI-style unified sectionsβœ…
Link MessagesRich inline links with citations, proofs, and forwarded bot contextβœ…
Latex Rendering HookssendLatex, sendLatexImage, sendLatexInlineImage helper APIsβœ…
Payment MessagesRequest payment messages with note/sticker supportβœ…
Product / CatalogBusiness product messages, catalog fetch/create/update/delete, cover photo helpersβœ…
Event / Poll ResultEvent message builders and poll result snapshotsβœ…
Newsletter ExtrasURL resolve, metadata fetch, create/update, bulk follow, admin utilities, live updatesβœ…
Communities & GroupsCommunity CRUD, linked groups, invite workflows, join approval, labelsβœ…
Status MentionsendStatusMention() helper to mention users/groups in status flowsβœ…
LID & Session HandlingLID↔PN mapping, session migration, retry/session recreation helpersβœ…
Build Output ReadyPublished runtime in lib/ and protobuf artifacts in WAProto/βœ…
TypeScript DeclarationsIncluded .d.ts files for exported APIs and socket methodsβœ…

βœ… Requirements

  • Node.js >= 20.0.0
  • ESM project ("type": "module" in your package.json)
  • A persistent auth store implementation for production use
  • Optional helpers depending on your use case:
    • pino for logging
    • qrcode-terminal if you want to render QR codes in the terminal yourself
    • sharp, jimp, audio-decode, link-preview-js for optional media/rich utilities

[!IMPORTANT] lunaaa-baileys is ESM-only. CommonJS projects will need migration or dynamic import wrappers.

πŸ“ What’s Inside This Repo

This package is not the TypeScript source workspace. It contains the compiled distributable files you actually publish/use.

PathPurpose
lib/Main compiled runtime, types, socket layers, utilities
WAProto/Generated protobuf runtime and typings
package.jsonPublished package metadata, dependencies, build script
tsconfig.jsonTypeScript config used for authoring/build pipeline
tsconfig.build.jsonBuild-specific TS emit config targeting lib/
proto-extract/Protobuf-related extraction/build assets

If you are documenting or integrating this project, treat lib/index.js and lib/index.d.ts as the primary public surface.

πŸ“¦ Installation

From NPM

npm install lunaaa-baileys

Recommended companion packages for examples in this README:

npm install pino qrcode-terminal

Add to package.json:

{
  "dependencies": {
    "luna": "npm:lunaaa-baileys@latest"
  }
}

Then run:

npm install

[!TIP] Using the alias luna allows you to import luna from 'luna' without changing existing code.

[!NOTE] Peer dependencies such as sharp, jimp, audio-decode, and link-preview-js are optional. Install only what your bot features need.

πŸ› οΈ Quick Start

1. Project Setup

mkdir my-bot && cd my-bot
npm init -y

Ensure package.json has "type": "module":

{
  "name": "my-bot",
  "type": "module",
  "dependencies": {
    "luna": "npm:lunaaa-baileys@latest"
  }
}

[!IMPORTANT] Required: "type": "module" β€” lunaaa-baileys is ESM-only. Without this, imports will fail.

2. Install Dependencies

npm install lunaaa-baileys pino qrcode-terminal

3. Create index.js

import makeWASocket, {
  useMultiFileAuthState,
  DisconnectReason,
  Browsers,
} from "lunaaa-baileys";
import pino from "pino";
import qrcode from "qrcode-terminal";

const logger = pino({ level: "silent" });

async function startBot() {
  const { state, saveCreds } = await useMultiFileAuthState("./session");

  const sock = makeWASocket({
    auth: state,
    logger,
    browser: Browsers.ubuntu("Chrome"),
    syncFullHistory: false,
  });

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

  sock.ev.on("connection.update", ({ connection, lastDisconnect, qr }) => {
    if (qr) {
      qrcode.generate(qr, { small: true });
    }

    if (connection === "close") {
      const shouldReconnect =
        lastDisconnect?.error?.output?.statusCode !==
        DisconnectReason.loggedOut;
      if (shouldReconnect) startBot();
    }
    if (connection === "open") console.log("Connected!");
  });

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

    const text =
      msg.message.conversation || msg.message.extendedTextMessage?.text || "";

    if (text === ".ping") {
      await sock.sendMessage(msg.key.remoteJid, { text: "Pong!" });
    }
  });
}

startBot();

4. Run

node index.js

Scan the QR code, wait until the socket reaches connection: "open", then send .ping to test.

5. Pairing Code Example

If you prefer pairing code over QR:

const sock = makeWASocket({
  auth: state,
  logger,
  browser: Browsers.windows("Chrome"),
});

sock.ev.on("connection.update", async ({ connection }) => {
  if (connection === "connecting") {
    const code = await sock.requestPairingCode("6283874851613");
    console.log("Pairing code:", code);
  }
});

You can also provide your own custom pairing code:

const code = await sock.requestPairingCode("6283874851613", "LUNABAIL");
console.log("Custom pairing code:", code);

Custom pairing codes must be exactly 8 characters.

[!WARNING] printQRInTerminal still exists in the type surface for compatibility, but it is deprecated in the current build. Prefer handling the qr value from connection.update yourself.

πŸ—οΈ Architecture

Socket Layer Chain

Each socket layer extends the previous via composition, adding functionality from bottom to top:

makeSocket          β†’ WebSocket + Noise protocol + pre-key management
  makeChatsSocket   β†’ App state sync + chat modifications + profile
    makeGroupsSocket β†’ Group CRUD + participant management
      makeMessagesSendSocket β†’ Message sending + rich messages + relay
        makeMessagesRecvSocket β†’ Message receiving + decryption + notifications
          makeBusinessSocket   β†’ Product catalog + business profile
            makeCommunitiesSocket β†’ Community CRUD + sub-groups
              makeNewsletterSocket β†’ Newsletter follow/unfollow/metadata
                makeWASocket      ← TOP LEVEL EXPORT

Key Modules

ModulePathDescription
Socketlib/Socket/Connection, messaging, groups, newsletter, business, communities
Signallib/Signal/Signal protocol: 1:1 encryption, group SenderKey, LID mapping
WABinarylib/WABinary/Binary node encoding/decoding, JID utilities
Utilslib/Utils/Crypto, auth state, noise handler, rich messages, media
WAProtoWAProto/Compiled protobuf encode/decode
WAUSynclib/WAUSync/User sync protocol (contact, device, LID)
WAMlib/WAM/WhatsApp analytics binary encoding
Typeslib/Types/Full TypeScript type definitions

Build Repo Layout

This repository does not currently expose a src/ directory in the checked-in package tree.

That means:

  • Documentation should reference lib/ as the public implementation
  • API discovery is best done through:
    • lib/index.js
    • lib/index.d.ts
    • lib/Socket/*.d.ts
    • lib/Utils/*.d.ts
  • Consumers should treat this repo as a ready-to-install runtime artifact, not the authoring source tree

Connection Flow

  • WebSocket connect β†’ Noise XX handshake (Curve25519 + AES-256-GCM)
  • QR code or Pairing Code authentication
  • CB:success β†’ upload pre-keys β†’ send passive IQ β†’ emit connection: 'open'
  • Store own LID↔PN mapping, migrate own session
  • Buffer events β†’ process offline notifications β†’ flush β†’ receivedPendingNotifications: true

πŸ“‘ Socket API Reference

Connection & Authentication

const sock = makeWASocket({
  auth: state, // AuthenticationState from useMultiFileAuthState
  logger, // pino logger instance
  browser: Browsers.ubuntu("Chrome"), // Browser identity
  version: [2, 3000, 1035194821], // WA version
  connectTimeoutMs: 20_000, // Connection timeout
  defaultQueryTimeoutMs: 60_000, // Query timeout
  retryRequestDelayMs: 250, // Retry delay
  maxMsgRetryCount: 5, // Max message retry count
  enableRecentMessageCache: true, // Enable message retry manager
  enableAutoSessionRecreation: true,
  syncFullHistory: false, // Sync full chat history
  shouldIgnoreJid: (jid) => false, // Filter specific JIDs
  qrTimeout: 60_000,
  generateHighQualityLinkPreview: false,
});

Pairing Code Authentication:

const sock = makeWASocket({
  auth: state,
  logger,
  browser: Browsers.windows("Chrome"),
});

sock.ev.on("connection.update", async ({ connection, qr, isNewLogin }) => {
  if (qr) {
    // QR code available (fallback)
  }
});

// Request pairing code
const code = await sock.requestPairingCode("6283874851613");
console.log("Pairing code:", code); // e.g. "LUNA-BAIL"

Authentication State:

import { useMultiFileAuthState } from "lunaaa-baileys";

const { state, saveCreds } = await useMultiFileAuthState("./session");
// state.creds β†’ credentials (me, platform, noise keys, etc.)
// state.keys β†’ SignalKeyStore (pre-keys, sessions, identity keys, etc.)
// saveCreds() β†’ persist credentials to disk

Custom Data Store / Memory Store Pattern:

import {
  BufferJSON,
  initAuthCreds,
  makeCacheableSignalKeyStore,
} from "lunaaa-baileys";

const credsStore = new Map();
const keyStoreData = new Map();

const creds = credsStore.get("creds") || initAuthCreds();

const keys = makeCacheableSignalKeyStore({
  get: async (type, ids) => {
    const data = {};
    for (const id of ids) {
      data[id] = keyStoreData.get(`${type}:${id}`);
    }
    return data;
  },
  set: async (data) => {
    for (const category in data) {
      for (const id in data[category]) {
        const value = data[category][id];
        const key = `${category}:${id}`;
        if (value == null) keyStoreData.delete(key);
        else keyStoreData.set(key, value);
      }
    }
  },
});

const state = { creds, keys };

const saveCreds = async () => {
  credsStore.set(
    "creds",
    JSON.parse(
      JSON.stringify(state.creds, BufferJSON.replacer),
      BufferJSON.reviver,
    ),
  );
};

This package does not currently ship a built-in makeInMemoryStore() helper.

Use these patterns instead:

  • useMultiFileAuthState() for bot/local usage
  • initAuthCreds() + custom SignalKeyStore for DB/Redis/in-memory persistence
  • makeCacheableSignalKeyStore() when you want faster repeated key access with caching

[!WARNING] useMultiFileAuthState() is convenient for bots and local testing, but the package itself warns against using it as your long-term production persistence layer. For production, write your own SQL/NoSQL-backed auth store.

Useful companion helpers:

import {
  Browsers,
  DisconnectReason,
  fetchLatestBaileysVersion,
  makeCacheableSignalKeyStore,
} from "lunaaa-baileys";

const { version, isLatest } = await fetchLatestBaileysVersion();
console.log(version, isLatest);

VoIP (Voice Calls)

Modul VoIP kini terintegrasi langsung di lunaaa-baileys menggunakan VoipClient dan memanfaatkan shared socket (tanpa double pairing). Aset WebAssembly sudah built-in.

Inisiasi VoIP Client:

import { VoipClient, CallState } from "lunaaa-baileys";

// Lakukan ini SETELAH connection === "open"
if (!global.voipClient) {
  global.voipClient = new VoipClient();
  await global.voipClient.connectWithSocket(sock);
  console.log("VoIP engine aktif!");
}

Melakukan Panggilan:

try {
  // Panggil nomor target (PN) - harus terhubung
  const call = await global.voipClient.call("6281234567890", {
    durationMs: 60000, // Timeout dalam ms
    audioSource: "silence", // Atau "mic" / "file" (butuh audio-feeder & ffmpeg)
  });

  call.on("ringing", () => console.log("Berdering..."));
  call.on("connected", () => console.log("Terhubung!"));
  call.on("ended", (reason) => console.log("Panggilan berakhir:", reason));

  // Menunggu hingga panggilan selesai
  await call.waitForEnd();
} catch (e) {
  console.error("Gagal menelpon:", e);
}

Message Sending

// Text
await sock.sendMessage(jid, { text: "Hello!" });

// Text with mention
await sock.sendMessage(jid, {
  text: "Hello @628xxx!",
  mentions: ["628xxx@s.whatsapp.net"],
});

// Image
await sock.sendMessage(jid, {
  image: { url: "./photo.jpg" },
  caption: "A photo",
});

// Video
await sock.sendMessage(jid, {
  video: { url: "./video.mp4" },
  caption: "A video",
  gifPlayback: false,
});

// Audio
await sock.sendMessage(jid, {
  audio: { url: "./audio.ogg" },
  mimetype: "audio/ogg; codecs=opus",
  ptt: true, // voice note
});

// Sticker
await sock.sendMessage(jid, {
  sticker: { url: "./sticker.webp" },
});

// Sticker pack
await sock.sendMessage(
  jid,
  makeStickerPack({
    name: "luna Starter Pack",
    publisher: "luna",
    description: "Starter sticker pack",
    stickers: [
      { url: "./stickers/1.webp", emojis: ["πŸ”₯"] },
      { url: "./stickers/2.webp", emojis: ["😎"] },
    ],
    cover: { url: "./stickers/cover.webp" },
  }),
);

// Document
await sock.sendMessage(jid, {
  document: { url: "./file.pdf" },
  fileName: "document.pdf",
  mimetype: "application/pdf",
});

// Reaction
await sock.sendMessage(jid, {
  react: { key: msg.key, text: "πŸ‘" },
});

// Location
await sock.sendMessage(jid, {
  location: {
    degreesLatitude: -6.2,
    degreesLongitude: 106.8,
    name: "Jakarta",
  },
});

// Contact
await sock.sendMessage(jid, {
  contacts: {
    displayName: "Contacts",
    contacts: [
      { vcard: "BEGIN:VCARD\nVERSION:3.0\nFN:John\nTEL:+628xxx\nEND:VCARD" },
    ],
  },
});

// Poll
await sock.sendMessage(jid, {
  poll: {
    name: "Vote!",
    values: ["Option A", "Option B", "Option C"],
    selectableCount: 1,
  },
});

// Forward message
await sock.sendMessage(jid, {
  forward: msg,
  forwardingScore: 1,
  isForwarded: true,
});

// Delete message
await sock.sendMessage(jid, { delete: msg.key });

// Edit message
await sock.sendMessage(jid, {
  text: "Edited text",
  edit: msg.key,
});

Interactive Messages

Native Flow Buttons:

await sock.sendMessage(jid, {
  interactiveMessage: {
    title: "Welcome!",
    footer: "Powered by luna",
    buttons: [
      {
        name: "quick_reply",
        buttonParamsJson: JSON.stringify({
          display_text: "Menu",
          id: "menu",
        }),
      },
      {
        name: "cta_url",
        buttonParamsJson: JSON.stringify({
          display_text: "Website",
          url: "https://example.com",
        }),
      },
      {
        name: "cta_copy",
        buttonParamsJson: JSON.stringify({
          display_text: "Copy Code",
          copy_code: "LUNA2026",
        }),
      },
    ],
    header: "Choose an option",
    image: { url: "https://example.com/banner.jpg" },
  },
});

List Menu (single_select):

await sock.sendMessage(jid, {
  interactiveMessage: {
    title: "Select Category",
    footer: "Powered by luna",
    buttons: [
      {
        name: "single_select",
        buttonParamsJson: JSON.stringify({
          title: "Menu",
          sections: [
            {
              title: "Games",
              rows: [
                { title: "Quiz", id: ".quiz" },
                { title: "Tebak Gambar", id: ".tebakgambar" },
              ],
            },
            {
              title: "Tools",
              rows: [
                { title: "Sticker", id: ".sticker" },
                { title: "TTS", id: ".tts" },
              ],
            },
          ],
        }),
      },
    ],
    header: "Bot Menu",
  },
});

Album Messages

await sock.sendMessage(jid, {
  albumMessage: [
    { image: { url: "./photo1.jpg" }, caption: "First" },
    { image: { url: "./photo2.jpg" }, caption: "Second" },
    { video: { url: "./clip.mp4" }, caption: "Video" },
  ],
});

[!NOTE] Albums automatically set expectedImageCount and expectedVideoCount based on array content.

AI Rich Response Messages

Send messages styled like Meta AI β€” tables, code blocks, and rich text. All rendered via botForwardedMessage > richResponseMessage.

Table (with heading):

await sock.sendTable(
  jid,
  "Java vs JavaScript",
  ["Feature", "Java", "JavaScript"],
  [
    ["Type", "Compiled", "Interpreted"],
    ["Typing", "Static", "Dynamic"],
    ["Main Use", "Enterprise", "Web, Full-stack"],
  ],
  quoted,
  {
    headerText: "Comparison:",
    footer: "Hope this helps!",
  },
);

List (without heading):

await sock.sendList(
  jid,
  "Bot Info",
  [
    ["Name", "Luna-MD"],
    ["Version", "2.0.0"],
    ["Developer", "noxXza.exe"],
  ],
  quoted,
  { footer: "Β© Luna-MD" },
);

Code Block V1 (basic syntax highlighting):

await sock.sendCodeBlock(
  jid,
  `const greeting = "Hello World"
function sayHello(name) {
    return greeting + " " + name
}
sayHello("luna")`,
  quoted,
  {
    language: "javascript",
    title: "Example Code",
    footer: "Powered by Luna-MD",
  },
);

Supported V1 languages: javascript, typescript, python

Table V2 (Unified Response):

The V2 table uses the unified response format with GenATableUXPrimitive typename and base64-encoded data, matching the Meta AI rich response protocol.

Features over V1:

  • String-based table input with flexible delimiters (| or , for columns, ;; for rows)
  • Unified response sections with GenATableUXPrimitive / GenAIMarkdownTextUXPrimitive typenames
  • Dual output: rows (for submessages) + unified_rows (for sections)
  • Enhanced contextInfo with botMessageSharingInfo
await sock.sendTableV2(
  jid,
  [
    "Java vs JavaScript", // title
    "Feature | Java | JavaScript", // header (pipe-delimited)
    "Type | Compiled | Interpreted;;Typing | Static | Dynamic;;Main Use | Enterprise | Web, Full-stack", // rows (;; separated, | or , delimited)
  ],
  quoted,
  {
    headerText: "Comparison:",
    text: "Here is a comparison table:",
    footer: "Hope this helps!",
  },
);

Input format:

  • table[0] β€” title string
  • table[1] β€” header row (columns separated by | or ,)
  • table[2+] β€” data rows (rows separated by ;;, columns by | or ,)

V2 Options:

OptionTypeDefaultDescription
titlestringβ€”Title (used if headerText not set)
headerTextstringβ€”Text shown before the table
textstringβ€”Markdown text section (GenAIMarkdownTextUXPrimitive)
footerstringβ€”Text shown after the table

Code Block V2 (Unified Response)

The V2 code block uses the unified response format with sections/view_model/primitive structure and base64-encoded data, matching the Meta AI rich response protocol exactly.

Features over V1:

  • 6 language families with keyword detection
  • /* */ block comment support
  • # comment support for python/bash/lua
  • Hex/binary/octal number literals
  • Dual token output: numeric codeBlock + string-typed unified_codeBlock
  • Unified response sections with GenAICodeUXPrimitive / GenAIMarkdownTextUXPrimitive typenames
  • Enhanced contextInfo with botMessageSharingInfo
await sock.sendCodeBlockV2(
  jid,
  `package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}`,
  quoted,
  {
    language: "go",
    title: "Go Example",
    text: "Here is a Go code snippet:",
    footer: "Powered by Luna-MD",
  },
);

Supported V2 languages:

Language KeyAliases
javascriptjs, typescript, ts
pythonpy
gogolang
luaβ€”
bashsh, shell

V2 Options:

OptionTypeDefaultDescription
languagestring'javascript'Programming language for syntax highlighting
titlestringβ€”Title text shown before the code block
textstringβ€”Markdown text section (GenAIMarkdownTextUXPrimitive)
footerstringβ€”Footer text shown after the code block

V2 Token Types:

CodeV1 NameV2 NameDescription
0DEFAULTDEFAULTNormal text, whitespace, operators
1KEYWORDKEYWORDLanguage keywords (const, func, if, etc.)
2METHODMETHODFunction/method calls (identifier followed by ()
3STRINGSTRString literals ("...", '...', `...`)
4NUMBERNUMBERNumeric values (int, float, hex, binary, octal)
5COMMENTCOMMENTComments (//, /* */, #)

Send rich text with inline clickable links using {{IE_N}}display_text{{/IE_N}} placeholders, with optional citation metadata and verification proofs.

await sock.sendLink(
  jid,
  "Upload results:\nβœ… Freeimage\nπŸ”— Klik: {{IE_0}}link disini{{/IE_0}}\nβœ… Yardsansh\nπŸ”— Klik: {{IE_1}}link disini{{/IE_1}}",
  ["https://example.com/upload1", "https://example.com/upload2"],
  quoted,
  {
    headerText: "πŸ“ Media Uploader V3",
    footer: "✨ Selesai!",
    botJid: "867051314767696@bot",
    forwardingScore: 3,
    citations: [
      {
        sourceTitle: "Freeimage",
        citationNumber: 1,
        faviconCdnUrl: "https://cdn.example.com/favicon.ico",
      },
      { sourceTitle: "Yardsansh", citationNumber: 2 },
    ],
    proofs: [
      {
        version: 1,
        useCase: 1,
        signature: "base64signature==",
        certificateChain: ["base64cert1", "base64cert2"],
      },
    ],
  },
);

Link Options:

OptionTypeDefaultDescription
headerTextstringβ€”Text shown before the link content
footerstringβ€”Text shown after the link content
botJidstring'867051314767696@bot'Bot JID for forwardedAiBotMessageInfo
forwardingScorenumber3Forward score for context info
citationsCitation[][]Citation metadata entries
proofsProof[][]Verification proof entries

Citation object:

FieldTypeDescription
sourceQuerystringSource query text
faviconCdnUrlstringCDN URL for favicon
citationNumbernumberCitation index (auto-incremented if omitted)
sourceTitlestringTitle of the source

Proof object:

FieldTypeDescription
versionnumberProof version
useCasenumberUse case identifier
signaturestringBase64 signature
certificateChainstring[]Base64 certificate chain

Link V2 (search-result style):

await sock.sendLinkV2(
  jid,
  "Search results:\n- {{IE_0}}Official docs{{/IE_0}}\n- {{IE_1}}GitHub repo{{/IE_1}}",
  [
    {
      url: "https://www.npmjs.com/package/lunaaa-baileys",
      displayName: "Official docs",
      sourceDisplayName: "npm",
      sourceSubtitle: "package registry",
    },
    {
      url: "https://github.com/noxXza/lunaaa-baileys",
      displayName: "GitHub repo",
      sourceDisplayName: "github",
      sourceSubtitle: "source hosting",
    },
  ],
  quoted,
  {
    headerText: "lunaaa-baileys",
    footer: "Reference links",
    searchEngine: "MAME",
  },
);

Other Message Types

Payment Request:

await sock.sendMessage(jid, {
  requestPaymentMessage: {
    amount: 50000,
    currency: "IDR",
    note: "Payment for order #123",
    from: "628xxx@s.whatsapp.net",
  },
});

Event:

await sock.sendMessage(jid, {
  eventMessage: {
    name: "Community Meetup",
    description: "Join us for the monthly meetup!",
    startTime: Date.now() + 86400000,
    endTime: Date.now() + 90000000,
    location: {
      name: "Jakarta",
      degreesLatitude: -6.2,
      degreesLongitude: 106.8,
    },
  },
});

Poll Result:

await sock.sendMessage(jid, {
  pollResultMessage: {
    name: "Favorite Color?",
    pollVotes: [
      { optionName: "Red", optionVoteCount: 42 },
      { optionName: "Blue", optionVoteCount: 38 },
      { optionName: "Green", optionVoteCount: 25 },
    ],
  },
});

Status with Mentions:

await sock.sendStatusMention({ text: "Big update coming!" }, [
  "628xxx@s.whatsapp.net",
  "groupid@g.us",
]);

Product Message:

await sock.sendMessage(jid, {
  productMessage: {
    title: "Wireless Headphones",
    description: "High quality bluetooth headphones",
    productId: "WH-001",
    retailerId: "luna-shop",
    url: "https://example.com/product",
    priceAmount1000: 299000,
    currencyCode: "IDR",
    thumbnail: { url: "https://example.com/product.jpg" },
    body: "Check out this product!",
    footer: "luna Shop",
    buttons: [
      {
        name: "quick_reply",
        buttonParamsJson: JSON.stringify({
          display_text: "Buy Now",
          id: "buy_wh001",
        }),
      },
    ],
  },
});

Mixed Rich Message (custom submessages):

await sock.sendRichMessage(
  jid,
  [
    { messageType: 2, messageText: "Here is some info:" },
    {
      messageType: 4,
      tableMetadata: {
        title: "Stats",
        rows: [
          { items: ["Metric", "Value"], isHeading: true },
          { items: ["Users", "1000"] },
          { items: ["Uptime", "99.9%"] },
        ],
      },
    },
    { messageType: 2, messageText: "And some code:" },
    {
      messageType: 5,
      codeMetadata: {
        codeLanguage: "javascript",
        codeBlocks: [{ highlightType: 0, codeContent: 'console.log("OK")' }],
      },
    },
  ],
  quoted,
);

SubMessage Types:

messageTypeNamePayload Field
0UNKNOWNβ€”
1GRID_IMAGEgridImageMetadata
2TEXTmessageText
3INLINE_IMAGEimageMetadata
4TABLEtableMetadata
5CODEcodeMetadata
6DYNAMICdynamicMetadata
7MAPmapMetadata
8LATEXlatexMetadata
9CONTENT_ITEMScontentItemsMetadata

Newsletter Methods

// Resolve channel URL to metadata
const info = await sock.cekIDSaluran("https://whatsapp.com/channel/xxxxx");
console.log(info.name, info.subscribers);

// Bulk follow multiple channels
await sock.newsletterMultipleFollow("id1@newsletter id2@newsletter");

// Fetch all subscribed channels
const channels = await sock.newsletterFetchAllSubscribe();

// Generic action (follow/unfollow/mute/unmute)
await sock.newsletterAction("id@newsletter", "follow");

// Create newsletter
const nl = await sock.newsletterCreate("My Channel", "Description");

// Update newsletter
await sock.newsletterUpdate("id@newsletter", { name: "New Name" });

// Get subscriber count
const { subscribers } = await sock.newsletterSubscribers("id@newsletter");

// Get metadata
const meta = await sock.newsletterMetadata("jid", "id@newsletter");

// Follow / Unfollow
await sock.newsletterFollow("id@newsletter");
await sock.newsletterUnfollow("id@newsletter");

// Mute / Unmute
await sock.newsletterMute("id@newsletter");
await sock.newsletterUnmute("id@newsletter");

// Update name / description / picture
await sock.newsletterUpdateName("id@newsletter", "New Name");
await sock.newsletterUpdateDescription("id@newsletter", "New Desc");
await sock.newsletterUpdatePicture("id@newsletter", mediaUpload);
await sock.newsletterRemovePicture("id@newsletter");

// React to message
await sock.newsletterReactMessage("id@newsletter", serverId, "πŸ‘");

// Fetch messages
const msgs = await sock.newsletterFetchMessages("id@newsletter", 50, 0, 0);

// Admin operations
const count = await sock.newsletterAdminCount("id@newsletter");
await sock.newsletterChangeOwner("id@newsletter", newOwnerJid);
await sock.newsletterDemote("id@newsletter", userJid);
await sock.newsletterDelete("id@newsletter");

Group Methods

// Fetch group metadata
const meta = await sock.groupMetadata("id@g.us");

// Create group
const group = await sock.groupCreate("My Group", ["628xxx@s.whatsapp.net"]);

// Leave group
await sock.groupLeave("id@g.us");

// Update subject / description
await sock.groupUpdateSubject("id@g.us", "New Subject");
await sock.groupUpdateDescription("id@g.us", "New Description");

// Participant actions: add, remove, promote, demote
const result = await sock.groupParticipantsUpdate(
  "id@g.us",
  ["628xxx@s.whatsapp.net"],
  "add", // 'remove' | 'promote' | 'demote'
);

// Handle join requests
const requests = await sock.groupRequestParticipantsList("id@g.us");
await sock.groupRequestParticipantsUpdate(
  "id@g.us",
  ["628xxx@s.whatsapp.net"],
  "approve",
);

// Invite code
const code = await sock.groupInviteCode("id@g.us");
await sock.groupRevokeInvite("id@g.us");
await sock.groupAcceptInvite("ABCDE12345");
const info = await sock.groupGetInviteInfo("ABCDE12345");

// Settings: announcement, not_announcement, locked, unlocked
await sock.groupSettingUpdate("id@g.us", "announcement");
await sock.groupSettingUpdate("id@g.us", "locked");

// Member add mode / Join approval
await sock.groupMemberAddMode("id@g.us", "admin_add");
await sock.groupJoinApprovalMode("id@g.us", "on");

// Toggle disappearing messages
await sock.groupToggleEphemeral("id@g.us", 86400); // 24h

// Fetch all participating groups
const groups = await sock.groupFetchAllParticipating();

// Update member label
await sock.updateMemberLabel("id@g.us", "VIP");

Community Methods

// Fetch community metadata
const meta = await sock.communityMetadata("communityid@g.us");

// Create community
const community = await sock.communityCreate(
  "Our Community",
  "Community description",
);

// Create a subgroup under a community
const subgroup = await sock.communityCreateGroup(
  "Announcements",
  ["628xxx@s.whatsapp.net"],
  "communityid@g.us",
);

// Link / unlink an existing group
await sock.communityLinkGroup("groupid@g.us", "communityid@g.us");
await sock.communityUnlinkGroup("groupid@g.us", "communityid@g.us");

// Fetch linked groups
const linked = await sock.communityFetchLinkedGroups("communityid@g.us");

// Invite handling
const code = await sock.communityInviteCode("communityid@g.us");
await sock.communityRevokeInvite("communityid@g.us");
await sock.communityAcceptInvite(code);
const inviteInfo = await sock.communityGetInviteInfo(code);

// Requests / participants
const requests =
  await sock.communityRequestParticipantsList("communityid@g.us");
await sock.communityRequestParticipantsUpdate(
  "communityid@g.us",
  ["628xxx@s.whatsapp.net"],
  "approve",
);
await sock.communityParticipantsUpdate(
  "communityid@g.us",
  ["628xxx@s.whatsapp.net"],
  "add",
);

// Settings
await sock.communityUpdateSubject("communityid@g.us", "New Subject");
await sock.communityUpdateDescription("communityid@g.us", "New Description");
await sock.communityToggleEphemeral("communityid@g.us", 86400);
await sock.communitySettingUpdate("communityid@g.us", "announcement");
await sock.communityMemberAddMode("communityid@g.us", "admin_add");
await sock.communityJoinApprovalMode("communityid@g.us", "on");

// Leave / list all
await sock.communityLeave("communityid@g.us");
const communities = await sock.communityFetchAllParticipating();

Business Methods

// Catalog
const { products, nextPageCursor } = await sock.getCatalog({
  jid: "628xxx@s.whatsapp.net",
  limit: 10,
});

const { collections } = await sock.getCollections("628xxx@s.whatsapp.net", 10);

// Orders
const order = await sock.getOrderDetails(orderId, tokenBase64);

// Product CRUD
const product = await sock.productCreate({
  name: "Premium Package",
  description: "Official premium plan",
  price: 150000,
  currency: "IDR",
  originCountryCode: "ID",
  images: [mediaUpload],
});

await sock.productUpdate(product.id, {
  name: "Premium Package Plus",
  description: "Official premium plan plus",
  price: 175000,
  currency: "IDR",
  images: [mediaUpload],
});

await sock.productDelete([product.id]);

// Business profile
await sock.updateBusinessProfile({
  address: "Jakarta, Indonesia",
  description: "Official store",
  websites: ["https://example.com"],
  email: "hello@example.com",
  hours: {
    timezone: "Asia/Jakarta",
    days: [{ day: "mon", mode: "open_24h" }],
  },
});

// Legacy alias is still available for backward compatibility
await sock.updateBussinesProfile({
  description: "Legacy alias still works",
});

await sock.updateCoverPhoto(mediaUpload);
await sock.removeCoverPhoto(coverId);

// Quick replies
await sock.addOrEditQuickReply({
  shortcut: "hello",
  message: "Hello from business account",
});

await sock.removeQuickReply(timestamp);

Chat & Profile Methods

// Profile picture
const url = await sock.profilePictureUrl(jid, "image");
await sock.updateProfilePicture(jid, mediaUpload);
await sock.removeProfilePicture(jid);

// Profile name / status
await sock.updateProfileName("My Name");
await sock.updateProfileStatus("Available");

// Presence
await sock.sendPresenceUpdate("available", jid);
await sock.presenceSubscribe(jid);

// Read receipts
await sock.readMessages([msg.key]);
await sock.sendReceipt(jid, participant, [msgId], "read");

// Block / Unblock
await sock.updateBlockStatus(jid, "block");
await sock.updateBlockStatus(jid, "unblock");

// Fetch blocklist
const list = await sock.fetchBlocklist();

// Chat modifications
await sock.chatModify(
  {
    archive: true,
    lastMessageOrig: msg,
    lastMessage: msg,
  },
  jid,
);

// Star messages
await sock.star(jid, [{ id: msgId, fromMe: true }], true);

// Contact management
await sock.addOrEditContact(jid, { displayName: "Name" });
await sock.removeContact(jid);

// Labels
await sock.addChatLabel(jid, labelId);
await sock.removeChatLabel(jid, labelId);
await sock.addMessageLabel(jid, messageId, labelId);

// App state sync
await sock.resyncAppState(["regular", "critical_block"], true);

// Business profile
const biz = await sock.getBusinessProfile(jid);

Privacy Settings

await sock.updateLastSeenPrivacy("all"); // 'all' | 'contacts' | 'contact_blacklist' | 'nobody'
await sock.updateOnlinePrivacy("all"); // 'all' | 'match_last_seen'
await sock.updateProfilePicturePrivacy("contacts");
await sock.updateStatusPrivacy("contacts");
await sock.updateReadReceiptsPrivacy("all"); // 'all' | 'none'
await sock.updateGroupsAddPrivacy("all"); // 'all' | 'contacts'
await sock.updateMessagesPrivacy("all"); // 'all' | 'contacts' | 'nobody'
await sock.updateCallPrivacy("everyone");
await sock.updateDefaultDisappearingMode(86400);
await sock.updateDisableLinkPreviewsPrivacy(true);

πŸ“‘ Event Reference

sock.ev.on('connection.update', ({ connection, lastDisconnect, qr, isNewLogin, receivedPendingNotifications, isOnline }) => {})
sock.ev.on('creds.update', (update) => {})
sock.ev.on('messaging-history.set', ({ chats, contacts, messages, isLatest }) => {})
sock.ev.on('chats.upsert', (chats) => {})
sock.ev.on('chats.update', (updates) => {})
sock.ev.on('chats.delete', (jids) => {})
sock.ev.on('contacts.upsert', (contacts) => {})
sock.ev.on('contacts.update', (updates) => {})
sock.ev.on('messages.upsert', ({ messages, type }) => {})
sock.ev.on('messages.update', (updates) => {})
sock.ev.on('messages.delete', (keys) => {})
sock.ev.on('messages.reaction', (reactions) => {})
sock.ev.on('message-receipt.update', (updates) => {})
sock.ev.on('groups.update', (updates) => {})
sock.ev.on('group-participants.update', (update) => {})
sock.ev.on('group.join-request', (update) => {})
sock.ev.on('call', (calls) => {})
sock.ev.on('labels.edit', (label) => {})
sock.ev.on('labels.associations', ({ associated, label, type }) => {})
sock.ev.on('newsletter.update', (updates) => {})
sock.ev.on('newsletter.follow', (jid) => {})
sock.ev.on('newsletter.unfollow', (jid) => {})
sock.ev.on('settings.update', ({ isAutoEmojiEnabled, isReadReceiptsEnabled, ... }) => {})

πŸ”§ Utility Exports

import {
  // Auth
  useMultiFileAuthState,
  makeCacheableSignalKeyStore,
  initAuthCreds,
  BufferJSON,
  fetchLatestBaileysVersion,

  // Code tokenization
  tokenizeCode,
  tokenizeCodeV2,
  CodeHighlightType,
  RichSubMessageType,

  // Rich message generators
  generateTableContent,
  generateTableContentV2,
  toTableMetadataV2,
  generateListContent,
  generateCodeBlockContent,
  generateCodeBlockContentV2,
  generateLinkContent,
  generateLinkContentV2,
  generateRichMessageContent,
  generateLatexContent,
  generateLatexImageContent,
  generateLatexInlineImageContent,
  generateUnifiedResponseContent,
  captureUnifiedResponse,

  // Rich message builders
  buildRichContextInfo,
  buildBotForwardedMessage,

  // Sticker pack helper
  makeStickerPack,

  // Language keyword sets
  JS_KEYWORDS,
  PYTHON_KEYWORDS,
  GO_KEYWORDS,
  LUA_KEYWORDS,
  BASH_KEYWORDS,
  LANGUAGE_KEYWORDS,

  // Crypto
  Curve,
  signedKeyPair,
  aesEncryptGCM,
  aesDecryptGCM,

  // JID utilities
  jidEncode,
  jidDecode,
  jidNormalizedUser,
  areJidsSameUser,
  isJidGroup,
  isJidNewsletter,
  isLidUser,
  isPnUser,
  isJidBot,
  isJidMetaAI,
  isJidBroadcast,
  isJidStatusBroadcast,

  // Connection
  DisconnectReason,
  Browsers,

  // Dugong (advanced message types)
  Dugong,

  // Types
  WASocket,
} from "lunaaa-baileys";

[!NOTE] In this build, some advanced helper typings may appear first in lib/Socket/messages-send.d.ts before they are reflected everywhere else in aggregated socket declarations. If your editor autocomplete lags behind runtime behavior, inspect lib/Socket/messages-send.js and lib/Utils/rich-messages.d.ts for the most complete helper surface.

πŸ—οΈ Building This Package

This repository ships compiled files, but it still includes the build script used to emit/update lib/.

npm install
npm run build

What the build does:

  • runs TypeScript with tsconfig.build.json
  • emits JavaScript and declaration files into lib/
  • runs tsc-esm-fix so generated ESM imports resolve cleanly

Important build notes:

  • tsconfig.json is authoring-oriented and uses noEmit: true
  • tsconfig.build.json flips emit back on and excludes test files
  • published package files are limited to lib/**/* and WAProto/**/*

πŸ”€ Differences from Official Baileys

AreaOfficial Baileys v7lunaaa-baileys
Interactive messagesNo native supportFull support via Dugong
Album messagesNot supportedMulti-media albums
AI Rich ResponseNot availableTable, code block, rich text
Table V1Not availableBasic table with headers
Table V2Not availableUnified response + GenATableUXPrimitive
Code Block V1Not availableSyntax highlighting (JS/TS/Python)
Code Block V2Not availableUnified response + 6 languages
Link MessageNot availableInline embeds + citations + verification
Business nodesManual injectionAuto-inject on relay
Newsletter extrasBasic onlyAuto-follow, bulk follow, URL resolve
Button detectionNot availablegetButtonType() auto-detect
Payment messagesNot supportedFull support
Event messagesBasicEnhanced all fields
Status mentionsNot availablesendStatusMention()
Product messagesNot supportedCatalog + buttons
LID supportBasicFull LID↔PN mapping + session migration
Identity changesNo handlingDebounced session refresh
Message retryBasicMessageRetryManager with cache

🀝 Contributing

  • Fork this repo
  • Create a branch (git checkout -b feature/name)
  • Commit changes (git commit -m 'feat: add feature')
  • Push to branch (git push origin feature/name)
  • Open a Pull Request

πŸ“„ License

MIT Β© noxXza

[!CAUTION] This library is for educational purposes. Ensure compliance with WhatsApp Terms of Service.

Made with πŸ’š by noxXza.exe

⭐ Star this repo Β· πŸ› Report Bug Β· πŸ’‘ Request Feature

Keywords

baileys

FAQs

Package last updated on 25 Oct 2026

Related posts