{"_id":"@chatunitycenter/baileys","_rev":"2-3d1e63abab9358fdde1c1da9d37440c2","name":"@chatunitycenter/baileys","dist-tags":{"latest":"1.0.0"},"versions":{"0.0.0-stage":{"name":"@chatunitycenter/baileys","version":"0.0.0-stage","_id":"@chatunitycenter/baileys@0.0.0-stage","stub":true,"maintainers":[{"name":"chatunitycenter","email":"pescstuort67@gmail.com"}],"dist":{"shasum":"426cccae0223d89eb93e5fd5644a881fad536dd1","tarball":"https://registry.npmjs.org/@chatunitycenter/baileys/-/baileys-0.0.0-stage.tgz","fileCount":2,"integrity":"sha512-a9MTQkwV0WkuSwxmtHlf1XGcOtwtu/8AeH7+cwHAjJ7Mg45E7kDt0jjM177+p/zRICeUhADJsFJvraQy3x6i7Q==","signatures":[{"sig":"MEUCIDQ2lzs6g7Fv2lXbH9MAvrpvTRhqOtCqNpMBuQuFJvf6AiEAwc/GKUczESh+luZCCtfi1R14LiPrBfHY1zby2yQFSto=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":346},"_npmUser":{"name":"chatunitycenter","email":"pescstuort67@gmail.com"},"description":"Temporary package placeholder for staged publishing","directories":{}},"1.0.0":{"_id":"@chatunitycenter/baileys@1.0.0","dist":{"shasum":"4baf4d4a969c30750cd7020b869979d2795a99ed","tarball":"https://registry.npmjs.org/@chatunitycenter/baileys/-/baileys-1.0.0.tgz","fileCount":248,"integrity":"sha512-dPrW7HCjYtLrN/ePUUbTzwM4XP5r3lkfIUcF76K/JSof3VE2i5D5TCi2/c9gv36mjYkTL3ok6csPej2gbQW7Qw==","signatures":[{"sig":"MEYCIQCyhFWBCHs33DDrstvleYv8a3vUdh1iHB8ocer/6hjVQgIhAJmPfXdQqUGB3Ba8UvGlBVBM0gUda6JClOx7n/mx5EIV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCY3pg7NtZxOfTGhcJQnl/aM6E8Kss6Hev3O035+vfYjQIhAJYqHFaDS086bPmkD6prhkSnM4wkL6Q1Nq+FsvLhuCK4"}],"unpackedSize":16092877},"main":"lib/index.js","name":"@chatunitycenter/baileys","types":"lib/index.d.ts","author":{"name":"chatunity"},"engines":{"node":">=20.0.0"},"license":"MIT","scripts":{"lint":"eslint lib --ext .js","test":"jest --runInBand","example":"node --inspect -r ts-node/register Example/example.ts","release":"release-it","lint:fix":"eslint lib --fix --ext .js","build:all":"tsc && typedoc","build:tsc":"tsc","build:docs":"typedoc","preinstall":"node ./engine-requirements.js","gen:protobuf":"sh WAProto/GenerateStatics.sh","changelog:last":"conventional-changelog -p angular -r 2","verify:package":"node scripts/verify-package.js","changelog:update":"conventional-changelog -p angular -i CHANGELOG.md -s -r 0","changelog:preview":"conventional-changelog -p angular -u"},"version":"1.0.0","_npmUser":{"name":"chatunitycenter","email":"pescstuort67@gmail.com"},"homepage":"https://www.npmjs.com/package/@chatunity/baileys","keywords":["baileys","chatunity","wabot","whatsapp","js-whatsapp","whatsapp-api","whatsapp-web","whatsapp-bot","automation","multi-device","chatunity"],"repository":{"url":"https://www.npmjs.com/package/@chatunity/baileys"},"_npmVersion":"11.19.0","description":"Build WhatsApp bots and integrations with ChatUnity Baileys: a powerful, open-source multi-device WhatsApp Web API for Node.js.","directories":{},"maintainers":[{"name":"chatunitycenter","email":"pescstuort67@gmail.com"}],"_nodeVersion":"24.21.0","dependencies":{"ws":"^8.18.0","jimp":"^0.22.10","long":"^5.2.3","pino":"^10.1.0","axios":"^1.13.2","chalk":"^4.1.2","lodash":"^4.17.21","cheerio":"^1.1.2","libsignal":"github:chatunitycenter/libsignal-node","@hapi/boom":"^10.0.1","node-cache":"^5.1.2","protobufjs":"^7.6.6","async-mutex":"^0.5.0","music-metadata":"^11.7.0","@adiwajshing/keyed-db":"^0.2.4","@cacheable/node-cache":"^1.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"yarn@1.22.19","devDependencies":{"jest":"^29.7.0","json":"^11.0.0","open":"^10.1.0","eslint":"^9.0.0","ts-jest":"^29.1.2","ts-node":"^10.9.2","typedoc":"^0.27.0","@types/ws":"^8.5.10","unfurl.js":"^6.4.0","@types/got":"^9.6.11","release-it":"^16.1.0","typescript":"5.8.3","@types/jest":"^29.5.12","@types/node":"^20.14.0","protobufjs-cli":"2.0.0","qrcode-terminal":"^0.12.0","@adiwajshing/eslint-config":"github:adiwajshing/eslint-config","conventional-changelog-cli":"^2.2.2"},"peerDependencies":{"unfurl.js":"^6.4.0","audio-decode":"^2.1.3","qrcode-terminal":"^0.12.0"},"peerDependenciesMeta":{"jimp":{"optional":true},"unfurl.js":{"optional":true},"audio-decode":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/baileys_1.0.0_1792228531953_0.41664692290167205"}}},"time":{"created":"2026-10-17T09:12:51.403Z","modified":"2026-10-17T09:15:32.253Z","0.0.0-stage":"2026-10-17T09:12:51.403Z","1.0.0":"2026-10-17T09:15:32.051Z"},"description":"Build WhatsApp bots and integrations with ChatUnity Baileys: a powerful, open-source multi-device WhatsApp Web API for Node.js.","maintainers":[{"name":"chatunitycenter","email":"pescstuort67@gmail.com"}],"readme":"# <div align='center'>ChatUnity Baileys - TypeScript & Node.js Based</div>\n\n<div align=\"center\">\n\n<img src=\"https://files.catbox.moe/inl9it.gif\" alt=\"Header Image\" width=\"100%\"/>\n\n<br/>\n\n<p>\n  <img src=\"https://img.shields.io/npm/dw/%40chatunitycenter%2Fbaileys?label=npm&color=%23CB3837\" alt=\"NPM Downloads\"/>\n  <img src=\"https://img.shields.io/github/v/release/chatunitycenter/baileys?include_prereleases&sort=semver\" alt=\"Latest Release\"/>\n  <img src=\"https://img.shields.io/github/languages/code-size/chatunitycenter/baileys\" alt=\"Code Size\"/>\n  <img src=\"https://img.shields.io/github/license/chatunitycenter/baileys\" alt=\"License\"/>\n  <img src=\"https://img.shields.io/github/stars/chatunitycenter/baileys\" alt=\"Stars\"/>\n  <img src=\"https://img.shields.io/github/forks/chatunitycenter/baileys\" alt=\"Forks\"/>\n</p>\n\n#### Responsibility and License Information\nThe developers of Baileys and its maintainers cannot be held responsible for misuse of the application, as indicated in the [MIT License](https://github.com/WhiskeySockets/Baileys/blob/master/LICENSE).  \nThe team does not approve any use that violates WhatsApp's Terms of Service. Every user is invited to act responsibly and use the tool only for its intended purposes.\n\n---\n\n## 🚀 Features\n\n- **No Selenium/Chromium** - Uses WebSocket directly, saving ~500MB RAM\n- **Multi-device Support** - Works with both WhatsApp Web and multi-device versions\n- **Production Ready** - 7 defensive systems for stability, security, and performance\n- **Zero Breaking Changes** - 100% backward compatible with Baileys v1.0.5\n- **TypeScript Support** - Fully typed with complete .d.ts files\n- **Zero Dependencies** - Uses only Node.js native modules\n\n> [!IMPORTANT]  \n> This is the official ChatUnity-maintained community version. The original repository was archived – development continues here.\n\n> [!WARNING]  \n> Starting from 3.2.1, `key.fromMe` is no longer used for authentication, owner, sudo, or admin checks. Use the identity helpers and `serializeMessage` instead. See [SECURITY_IDENTITY.md](./SECURITY_IDENTITY.md).\n\n---\n\n## ✨ What's New in 4.4.0\n\n### Ghost JID Messages\n\n- Added `ghostJid` and `ghostJids` message options for group replies visible only to the selected participant(s).\n- Added `ghostExcludeJids` for delivering a message to every group member except the listed JIDs.\n- Ghost delivery is implemented in the encrypted group fan-out, not with custom protocol attributes. PN and LID participant JIDs are accepted.\n- The intended command-reply pattern is `ghostJid: message.key.participant`.\n\n```ts\nconst caller = message.key.participant || message.key.remoteJid\n\nawait sock.sendMessage(message.key.remoteJid, {\n    text: 'This reply is visible only to the command caller.'\n}, {\n    ghostJid: caller\n})\n```\n\nGhost options are valid only for group chats. Use `ghostJids` when more than one participant must receive the reply.\n\n### iOS-Compatible List Messages\n\n- Private chats keep the legacy `listMessage` protobuf payload for Android/iOS compatibility.\n- Group chats use a direct `interactiveMessage.nativeFlowMessage` with a `single_select` button, `messageVersion: 1`, device-list metadata, and the `biz > interactive > native_flow` relay hint required by iOS clients.\n- `sections`, `buttonText`, row IDs, descriptions, optional footer, and `sendListButton()` share the same normalized path; no automatic text fallback is used for native-flow failures.\n\n### Additional Message Types\n\n- Added protobuf and TypeScript support for conditional reveal, poll V6 and add-option messages, event invites, group root-key sharing, payment reminders, split payments, music messages, and status link-preview metadata.\n- Added the related protocol enum values and fields without replacing ChatUnity's existing protobuf namespace or identity extensions.\n\n## ✨ What's New in 3.3.1\n\n### AIRich MessageBuilder 4.7\n\n- Added `AIRich`, `Button`, and `Carousel` builders with fluent sections, IDs, replacement, deletion, and editing support.\n- Added `addText`, `addCode`, `addTable`, `addSource`, `addReels`, `addImage`, `addVideo`, `addProduct`, `addPost`, `addMetadata`, `addTip`, `addWidget`, `addFooterAction`, and `addSuggest`.\n- Added `htmlSection`, `sendHtmlApp`, `checkHtmlApp`, `decodeAIRich`, and `decodeHtmlRich`.\n- AIRich payloads use `AIRichResponseMessage.unifiedResponse.data` and the `botForwardedMessage` wire envelope.\n- `GenAIaeacdsnwHtmlPrimitive` remains Android-only. iOS, Web, and Desktop may ignore or flatten it because this is a WhatsApp client limitation.\n\n### Standard List Button\n\n- Added the standard `interactive: { type: 'list', ... }` content shape and `sendListButton()`.\n- List Button messages are emitted as the local proto `listMessage` with the business capability node required by WhatsApp clients, without carousel wrapping.\n- Footer is optional and is not synthesized when omitted.\n- The direct list payload is compatible with iOS and Android clients; no device-specific carousel workaround is used.\n\n## ✨ What's New in 3.2.1\n\n### Identity & LID/Username Fix\n\n- Centralized identity layer in `lib/Utils/whatsapp-identity.{js,d.ts}`.\n- `fromMe` is no longer used for owner, sudo, admin, or self authorization.\n- Fixed the bug where `areJidsSameUser(undefined, undefined) === true` could grant false privileges.\n- Corrected LID fallback that previously replaced an unknown participant with `authState.creds.me.id`.\n- Added verified LID↔PN mappings with TTL, provenance, and rejection of ambiguous mappings.\n- Unmapped or ambiguous LIDs fail closed for privileged commands.\n\n### Native-Flow Interactive Buttons\n\n- New helpers in `lib/Utils/interactive.{js,d.ts}`:\n  - `btn.url`, `btn.reply`, `btn.copy`, `btn.call`, `btn.list`\n  - `sendNativeFlowButtons(sock, jid, options)`\n  - `sendCompatibleInteractive(sock, jid, options)` with plain-text fallback.\n- URL, phone number (E.164), and JSON validation; no `javascript:`/`data:`/`file:` URLs.\n- Quick-reply and list IDs are treated as untrusted input and validated against an allowlist.\n\n### Reliability & Anti-Abuse\n\n- `OutboundQueue` – per-chat queue with limited concurrency, backoff, and retry limits.\n- `MessageDeduplicator` – deduplication by `message.key.id` + chat + sender with TTL.\n- `CommandRateLimiter` – per-sender, per-chat, and global rate limits with cooldowns.\n- No aggressive reconnect loops; explicit backoff with a cap.\n\n### Message Generation, Quoting & LID\n\n- Explicit `contextInfo` on text and direct proto `conversation` inputs is promoted to `extendedTextMessage`.\n- `quoted` and `mentions` are preserved consistently for plain text, buttons, lists, interactive messages, and wrapped content.\n- Incoming LID to PN resolution runs before the single `messages.upsert` event, with a bounded timeout controlled by `lidResolutionTimeoutMs` (default `1500` ms).\n- A late LID mapping only warms the cache and never re-invokes the message handler for the same message.\n- Unknown LIDs remain opaque and are never promoted to the authenticated user.\n- The Signal repository now exposes persistent LID/PN mappings through `getLIDById`, `getPNById`, and `storeLidPnMapping`.\n\n### Rich HTML Responses\n\n- Added `buildUnifiedResponse`, `buildRichMessage`, `RichBuilder`, `sock.sendRichMessage`, and `sock.createAIRich`.\n- Rich responses use `Buffer` Base64 encoding and support `responseId`, trusted sources, custom primitives, verification metadata, and quoted messages.\n- `GenAIaeacdsnwHtmlPrimitive` is **Android only**. iOS, WhatsApp Web, and Desktop may ignore it or flatten it into a simple message. This is a WhatsApp client limitation and cannot be bypassed in Baileys.\n\n### Request Payment\n\n- Added validated `requestPayment` content with ISO 4217 currency validation, positive amount validation, JID normalization, optional note, and expiry.\n- `amount` is expressed in major currency units and mapped to the local proto field `amount1000`.\n- The maximum accepted amount is configurable with `maxPaymentAmount` and defaults to `1_000_000`.\n- `MessageBuilder.requestPayment()` is available for fluent message construction.\n\n### Business Number Check\n\n- Added `sock.numcheck(jid?)` and `sock.numCheck(jid?)`.\n- The result includes `banned`, optional ban timestamp, review submission state, review timestamp, and review status when WhatsApp returns those fields.\n- This is a protocol reachability heuristic. It is not an official WhatsApp certification and missing timestamps are returned as `undefined`.\n\n### Carousel Compatibility\n\n- Carousel cards wrap in `interactiveMessage.carouselMessage` by default.\n- Set `carouselWrap: false` to use the legacy non-carousel interactive payload.\n- Carousel-level footers are preserved in both modes.\n\n### Tooling & Docs\n\n- `test/identity.test.js`, `test/interactive.test.js`\n- `.env.example`, `SECURITY_IDENTITY.md`\n- `tsconfig.json`, `typedoc.json`, `jest.config.cjs`, `eslint.config.cjs`\n- `package.json` updated; `yarn.lock` created.\n- Decoder, receiver, serializer, JID utilities, quoting, and chat management updated to use the new identity layer.\n- `npm run verify:package` checks that published contents exclude tests, scripts, and environment files.\n- Rich HTML and request-payment declarations are exported from the public package types.\n\n---\n\n## 📦 Installation\n\n### Stable Version\n```bash\nyarn add @chatunity/baileys@4.4.0\n# or\nnpm install @chatunity/baileys@4.4.0\n```\n\n### Edge Version (Latest Features)\n```bash\nyarn add github:chatunitycenter/baileys\n```\n\n### Import\n```typescript\nimport makeWASocket from '@chatunity/baileys'\n```\n\n---\n\n## ⚡ Quick Start - The 7 Systems\n\n### 1. 🚫 Anti-Ban System\nPrevents WhatsApp bans through pattern recognition and adaptive pausing.\n\n```javascript\nconst { makeAntiBanSystem } = require('@chatunity/baileys')\n\nconst antiBan = makeAntiBanSystem(logger)\nantiBan.reportError(error, { context: 'message_send' })\nconst delay = antiBan.getAdaptiveDelay()\nconst stats = antiBan.getStats()\n```\n\n### 2. 💥 Crash Prevention System\nHandles crashes, memory leaks, and implements graceful shutdown.\n\n```javascript\nconst { makeCrashPreventionSystem } = require('@chatunity/baileys')\n\nconst cp = makeCrashPreventionSystem(logger)\ncp.registerRecoveryStrategy('high_memory', async () => { if(global.gc) global.gc() })\nconst result = await cp.protectedExecute(async () => await risky(), { timeout: 30000 })\ncp.onExit(async () => await socket.end())\n```\n\n### 3. 📝 Message Builder & Validator\nType-safe fluent API for all message types.\n\n```javascript\nconst { createMessageBuilder } = require('@chatunity/baileys')\n\nconst msg = createMessageBuilder()\n    .text('Hello')\n    .build()\n\nconst buttons = createMessageBuilder()\n    .buttons('Choose:', [\n        { buttonId: '1', buttonText: 'Option 1' },\n        { buttonId: '2', buttonText: 'Option 2' }\n    ])\n    .build()\n```\n\n### 4. ⚡ Advanced Rate Limiter\nIntelligent throttling with +20% more throughput.\n\n```javascript\nconst { makeAdvancedRateLimiter } = require('@chatunity/baileys')\n\nconst limiter = makeAdvancedRateLimiter({ tokensPerSecond: 1, enableAdaptive: true })\nawait limiter.add(async () => {\n    return await socket.sendMessage(jid, msg)\n}, { priority: 1, timeout: 30000 })\n```\n\n### 5. 📊 Metrics System\nReal-time monitoring and performance tracking.\n\n```javascript\nconst { makeMetricsSystem } = require('@chatunity/baileys')\n\nconst metrics = makeMetricsSystem(logger)\nconst timerId = metrics.startTimer('operation')\nmetrics.endTimer(timerId)\nmetrics.recordMessageSent()\nconst report = metrics.getReport()\n```\n\n### 6. 🛡️ Error Handler\nIntelligent error categorization and auto-recovery.\n\n```javascript\nconst { makeCentralizedErrorHandler } = require('@chatunity/baileys')\n\nconst eh = makeCentralizedErrorHandler(logger)\nconst result = await eh.handleError(error, { maxRetries: 3 })\nif(result.recovered) console.log('Fixed!')\n```\n\n### 7. 🔒 Security Layer\nInput validation, encryption, and IP rate limiting.\n\n```javascript\nconst { makeSecurityLayer } = require('@chatunity/baileys')\n\nconst security = makeSecurityLayer(logger)\nconst validation = security.validateInput(userInput)\nconst encrypted = security.encryptSensitiveData(sensitiveData)\n```\n\n---\n\n## 🎯 Complete Example (with Identity Layer)\n\n```typescript\nimport makeWASocket, { useMultiFileAuthState, serializeMessage } from '@chatunity/baileys'\nimport { makeAntiBanSystem, makeCrashPreventionSystem, makeAdvancedRateLimiter, makeMetricsSystem } from '@chatunity/baileys'\n\nasync function start() {\n    const { state, saveCreds } = await useMultiFileAuthState('./auth_info')\n    const sock = makeWASocket({\n        auth: state,\n        printQRInTerminal: true\n    })\n\n    // Enable safety systems\n    const antiBan = makeAntiBanSystem()\n    const cp = makeCrashPreventionSystem()\n    const limiter = makeAdvancedRateLimiter({ tokensPerSecond: 1 })\n    const metrics = makeMetricsSystem()\n\n    sock.ev.on('messages.upsert', async (m) => {\n        for (const msg of m.messages) {\n            const incoming = serializeMessage(msg, { socket: sock })\n\n            // NEVER use msg.key.fromMe for owner/sudo/admin checks\n            if (!incoming.isAuthenticatedSelf) {\n                try {\n                    await limiter.add(async () => {\n                        await sock.sendMessage(msg.key.remoteJid, {\n                            text: `Hello! You sent: ${msg.body}`\n                        })\n                        antiBan.reportSuccess()\n                        metrics.recordMessageSent()\n                    })\n                } catch (error) {\n                    antiBan.reportError(error)\n                    metrics.recordError(error.message)\n                }\n            }\n        }\n    })\n\n    sock.ev.on('creds.update', saveCreds)\n}\n\nstart()\n```\n\n---\n\n## 🔧 Configuration\n\nSee [CONFIG_EXAMPLES.md](./CONFIG_EXAMPLES.md) for detailed configuration examples.\n\n### Quick Setup\n\n```javascript\nconst config = {\n    antiBan: { maxConsecutiveErrors: 5 },\n    limiter: { tokensPerSecond: 1, enableAdaptive: true },\n    crashPrevention: { memoryThreshold: 512 * 1024 * 1024 },\n    security: { enableEncryption: true, maxMessageLength: 4096 }\n}\n```\n\n---\n\n## 📚 Additional Documentation\n\n- **[QUICKSTART.md](./QUICKSTART.md)** - 5-minute quick start guide\n- **[CONFIG_EXAMPLES.md](./CONFIG_EXAMPLES.md)** - Detailed configuration examples\n- **[SECURITY_IDENTITY.md](./SECURITY_IDENTITY.md)** - Identity layer, LID/username, `fromMe` fix, native-flow buttons, rollback, and manual test checklist\n\n---\n\n## 📝 Sending Messages\n\n### Text Message\n```ts\nawait sock.sendMessage(jid, { text: 'hello world' })\n```\n\n### Image Message\n```ts\nawait sock.sendMessage(jid, { \n    image: { url: './image.png' },\n    caption: 'hello world'\n})\n```\n\n### Button Message (Legacy)\n```ts\nawait sock.sendMessage(jid, {\n    text: 'Choose:',\n    footer: 'Select one',  \n    buttons: [{ \n        buttonId: 'id1', \n        buttonText: { displayText: 'Option 1' }\n    }]\n})\n```\n\n### List Message (Legacy)\n```ts\nawait sock.sendMessage(jid, {\n    text: 'Menu', \n    title: 'Menu title',\n    buttonText: 'View menu',\n    footer: 'Select',\n    sections: [{\n        title: 'Section 1',\n        rows: [{\n            title: 'Option 1', \n            rowId: 'option1'\n        }]\n    }]\n})\n```\n\nFor a group command reply visible only to the caller:\n\n```ts\nconst caller = message.key.participant || message.key.remoteJid\nawait sock.sendMessage(message.key.remoteJid, {\n    text: 'Private group response',\n}, {\n    ghostJid: caller\n})\n```\n\n### Carousel Message\n\n```ts\nawait sock.sendMessage(jid, {\n    text: 'Choose an option',\n    footer: 'Swipe or select',\n    cards: [{\n        body: 'First card',\n        footer: 'Card footer',\n        buttons: [{\n            name: 'quick_reply',\n            buttonParamsJson: JSON.stringify({ id: 'first' })\n        }]\n    }]\n})\n```\n\nThe default `carouselWrap: true` emits `interactiveMessage.carouselMessage`. Use `carouselWrap: false` for the legacy non-carousel interactive payload.\n\n### Poll Message\n```ts\nawait sock.sendMessage(jid, {\n    poll: {\n        name: 'Favorite?',\n        values: ['A', 'B', 'C'],\n        selectableCount: 1\n    }\n})\n```\n\n### Location Message\n```ts\nawait sock.sendMessage(jid, {\n    location: {\n        degreesLatitude: 24.121231,\n        degreesLongitude: 55.1121221\n    }\n})\n```\n\n---\n\n## 🎓 Connecting Your Account\n\n### QR Code Connection\n```typescript\nimport makeWASocket from '@chatunity/baileys'\n\nconst sock = makeWASocket({\n    printQRInTerminal: true\n})\n```\n\n### Pairing Code Connection\n```typescript\nconst sock = makeWASocket({ printQRInTerminal: false })\n\nif (!sock.authState.creds.registered) {\n    const code = await sock.requestPairingCode('1234567890')\n    console.log(`Pairing code: ${code}`)\n}\n```\n\n### Save & Restore Sessions\n```typescript\nimport { useMultiFileAuthState } from '@chatunity/baileys'\n\nconst { state, saveCreds } = await useMultiFileAuthState('./auth_info')\nconst sock = makeWASocket({ auth: state })\nsock.ev.on('creds.update', saveCreds)\n```\n\n---\n\n## 📊 WhatsApp IDs\n\n- **User (PN)**: `[country code][phone number]@s.whatsapp.net` (e.g., `19999999999@s.whatsapp.net`)\n- **User (LID)**: `xxxxxxxxxx@lid` (anonymized identifier, not always reversible to PN)\n- **Group**: `[timestamp]-[random]@g.us` (e.g., `123456789-123345@g.us`)\n- **Broadcast**: `[timestamp]@broadcast`\n- **Status**: `status@broadcast`\n\n> [!NOTE]  \n> Starting from 3.2.1, treat PN, LID, and username-based contacts as distinct identities. Use the identity helpers to decide `isAuthenticatedSelf` and `isOwner`. Never rely on `key.fromMe` for authorization.\n\n---\n\n## 🐛 Troubleshooting\n\n### High Memory Usage\nEnable Crash Prevention system - automatically triggers GC when needed.\n\n### Frequent delivery errors\nUse the outbound queue and conservative rate limits. No helper bypasses WhatsApp enforcement.\n\n### Connection Issues\nCheck network. Use `syncFullHistory: true` for better message sync.\n\n### Message Formatting\nUse Message Builder for type-safe message construction.\n\n### Users with usernames or LID appear as “self”\nUpdate to 3.2.1+ and use `serializeMessage`, `isAuthenticatedSelf`, and the allowlist helpers. See [SECURITY_IDENTITY.md](./SECURITY_IDENTITY.md).\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Feel free to submit issues or pull requests.\n\n---\n\n## 📄 License\n\n[MIT License](./LICENSE)\n\n## Security Identity Update\n\nThe package now separates the raw transport flag `key.fromMe` from verified\nsender identity. Never use `fromMe` for owner, sudo, admin, or self\nauthorization. Use `serializeMessage`, `isAuthenticatedSelf`, and the explicit\nallowlist helpers exported by the package. Group senders come from the\nparticipant; PN, LID, and privacy identifiers remain distinct. Unmapped or\nambiguous LIDs fail closed for privileged commands.\n\nSee [SECURITY_IDENTITY.md](./SECURITY_IDENTITY.md) for the `3.2.1` patch\ndetails, rollback, native-flow buttons, plain-text fallback, rate limiting, and\nmanual verification guidance.\n\n---\n\n**Version**: 4.4.0  \n**Status**: ✅ Production Ready (after live tests)  \n**Owner**: ChatUnity  \n**Last Updated**: 2026-10-11\n\nYou can check out and run the example available in [example.ts](Example/example.ts) to see practical usage of the library.  \nThe script demonstrates the most common use cases.  \nTo run it:\n\n1. ```cd path/to/Baileys```\n2. ```yarn```\n3. ```yarn example```\n\n## Installation\n\nUse the stable version:\nyarn add @chatunity/baileys\n\nUse the edge version (no guarantee of stability, but latest fixes + features)\n\n\nThen import in your code using:\n```ts \nimport makeWASocket from '@chatunity/baileys'\n```\n\n## Connecting Account\n\nWhatsApp provides a multi-device system that allows Baileys to authenticate as a second WhatsApp client via **QR code** or **Pairing Code** scanned from the app on your phone.\n\n> [!NOTE]\n> **[Here](#example-to-start) you'll find a simple event handling example**\n\n> [!TIP]\n> **You can view all supported socket configurations [here](https://baileys.whiskeysockets.io/types/SocketConfig.html) (Recommended)**\n\n### Connect with QR-CODE\n\n> [!TIP]\n> If you connect via **QR-CODE**, you can customize the browser name using the `Browser` constant. Several predefined configurations are available, viewable **[here](https://baileys.whiskeysockets.io/types/BrowsersMap.html)**.\n\n```ts\nimport makeWASocket from '@chatunity/baileys'\n\nconst sock = makeWASocket({\n    browser: Browsers.ubuntu('My App'),\n    printQRInTerminal: true\n})\n```\n\nIf the connection is successful, you will see a QR code printed on your terminal screen. Scan it with WhatsApp on your phone and you'll be logged in!\n\n### Connect with Pairing Code\n\n> [!IMPORTANT]\n> Pairing Code is not Mobile API; it's a method to connect WhatsApp Web without QR-CODE. You can only connect with one device, see [here](https://faq.whatsapp.com/1324084875126592/?cms_platform=web)\n\nThe phone number cannot have `+`, `()`, or `-`, only numbers. You must provide country code.\n\n```ts\nimport makeWASocket from '@chatunity/baileys'\n\nconst chatunity = makeWASocket({\n    printQRInTerminal: false // must be false\n})\n\nif (!chatunity.authState.creds.registered) {\n    const number = 'XXXXXXXXXXX'\n    const code = await chatunity.requestPairingCode(number)\n    console.log(code)\n}\n```\n\n### Receive Full History\n\n1. Set `syncFullHistory` to `true`\n2. Use a desktop browser configuration to receive more message history:\n\n```ts\nconst chatunity = makeWASocket({\n    browser: Browsers.macOS('Desktop'),\n    syncFullHistory: true\n})\n```\n\n## Socket Configuration\n\n### Cache Group Metadata\n\nIf you use Baileys for groups, we recommend setting `cachedGroupMetadata` in socket config:\n\n```ts\nconst groupCache = new NodeCache({stdTTL: 5 * 60, useClones: false})\n\nconst chatunity = makeWASocket({\n    cachedGroupMetadata: async (jid) => groupCache.get(jid)\n})\n\nchatunity.ev.on('groups.update', async ([event]) => {\n    const metadata = await chatunity.groupMetadata(event.id)\n    groupCache.set(event.id, metadata)\n})\n\nchatunity.ev.on('group-participants.update', async (event) => {\n    const metadata = await chatunity.groupMetadata(event.id)\n    groupCache.set(event.id, metadata)\n})\n```\n\n### Improve Retry System & Decrypt Poll Votes\n\nTo improve message sending, retrying on errors, and decrypt poll votes, set up a store with `getMessage` config:\n\n```ts\nconst chatunity = makeWASocket({\n    getMessage: async (key) => await getMessageFromStore(key)\n})\n```\n\n### Receive Notifications in WhatsApp App\n\nTo receive notifications in the WhatsApp app, set `markOnlineOnConnect` to `false`:\n\n```ts\nconst chatunity = makeWASocket({\n    markOnlineOnConnect: false\n})\n```\n\n## Saving & Restoring Sessions\n\nYou don't need to scan the QR code every time you connect. Load credentials to log back in:\n\n```ts\nimport makeWASocket, { useMultiFileAuthState } from '@chatunity/baileys'\n\nconst { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')\n\nconst chatunity = makeWASocket({ auth: state })\n\nchatunity.ev.on('creds.update', saveCreds)\n```\n\n> [!IMPORTANT]\n> `useMultiFileAuthState` is a utility function to help save the auth state in a folder. This serves as a good guide for implementing auth & key states for SQL/NoSQL databases, which is recommended for production systems.\n\n> [!NOTE]\n> When messages are received/sent, auth keys need updating. You must save updated keys. The `useMultiFileAuthState` function handles this automatically, but for other implementations you must be careful with key state management.\n\n### Alternative Auth Methods\n\n```ts\nimport makeWASocket, { useSingleFileAuthState, useMongoFileAuthState } from '@chatunity/baileys'\n\n// Single File Auth\nconst { state, saveState } = await useSingleFileAuthState('./auth_info_baileys.json') \nconst chatunity = makeWASocket({ auth: state, printQRInTerminal: true })\nchatunity.ev.on('creds.update', saveState)\n\n// MongoDB Auth\nimport { MongoClient } from \"mongodb\"\n\nconst connectAuth = async() => {\n    const client = new MongoClient('mongoURL')\n    await client.connect()\n    const collection = client.db(\"@itchatunitychann\").collection(\"sessions\")\n    return collection\n}\n\nconst Authentication = await connectAuth()\nconst { state, saveCreds } = await useMongoFileAuthState(Authentication)\nconst chatunity = makeWASocket({ auth: state, printQRInTerminal: true })\nchatunity.ev.on('creds.update', saveCreds)\n```\n\n## Handling Events\n\nBaileys uses the EventEmitter syntax for events with full TypeScript support.\n\n> [!IMPORTANT]\n> **See all available events [here](https://baileys.whiskeysockets.io/types/BaileysEventMap.html)**\n\n```ts\nconst chatunity = makeWASocket()\nchatunity.ev.on('messages.upsert', ({ messages }) => {\n    console.log('got messages', messages)\n})\n```\n\n### Example to Start\n\n```ts\nimport makeWASocket, { DisconnectReason, useMultiFileAuthState } from '@chatunity/baileys'\nimport { Boom } from '@hapi/boom'\n\nasync function connectToWhatsApp () {\n    const { state, saveCreds } = await useMultiFileAuthState('./auth_info_baileys')\n    const chatunity = makeWASocket({\n        auth: state,\n        printQRInTerminal: true\n    })\n    chatunity.ev.on('connection.update', (update) => {\n        const { connection, lastDisconnect } = update\n        if(connection === 'close') {\n            const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut\n            console.log('connection closed due to ', lastDisconnect.error, ', reconnecting ', shouldReconnect)\n            if(shouldReconnect) {\n                connectToWhatsApp()\n            }\n        } else if(connection === 'open') {\n            console.log('opened connection')\n        }\n    })\n    chatunity.ev.on('messages.upsert', event => {\n        for (const m of event.messages) {\n            console.log(JSON.stringify(m, undefined, 2))\n            console.log('replying to', m.key.remoteJid)\n            await chatunity.sendMessage(m.key.remoteJid!, { text: 'Hello World' })\n        }\n    })\n    chatunity.ev.on('creds.update', saveCreds)\n}\n\nconnectToWhatsApp()\n```\n\n> [!IMPORTANT]\n> In `messages.upsert`, use a loop like `for (const message of event.messages)` to handle all messages in the array.\n\n### Decrypt Poll Votes\n\nPoll votes are encrypted by default and handled in `messages.update`:\n\n```ts\nimport pino from \"pino\"\nimport { makeInMemoryStore, getAggregateVotesInPollMessage } from '@chatunity/baileys'\n\nconst logger = pino({ timestamp: () => `,\"time\":\"${new Date().toJSON()}\"` }).child({ class: \"@Itchatunitychann\" })\nlogger.level = \"fatal\"\nconst store = makeInMemoryStore({ logger })\n\nasync function getMessage(key){\n    if (store) {\n        const msg = await store.loadMessage(key.remoteJid, key.id)\n        return msg?.message\n    }\n    return { conversation: \"Itchatunityi Kawaiii\" }\n} \n\nchatunity.ev.on(\"messages.update\", async (chatUpdate) => {\n    for(const { key, update } of chatUpdate) {\n         if(update.pollUpdates && key.fromMe) {\n           const pollCreation = await getMessage(key)\n             if(pollCreation) {\n               const pollUpdate = await getAggregateVotesInPollMessage({\n                    message: pollCreation,\n                    pollUpdates: update.pollUpdates,\n                })\n               const toCmd = pollUpdate.filter(v => v.voters.length !== 0)?.name\n               if (toCmd == undefined) return\n               console.log(toCmd)\n            }\n        }\n    } \n})\n```\n\n### Decrypt Event Response\n\nEvent responses are encrypted by default and handled in `messages.update`:\n\n```ts\nimport { jidNormalizedUser, getAggregateResponsesInEventMessage } from '@chatunity/baileys'\n\nchatunity.ev.on(\"messages.update\", async ([chatUpdate]) => {\n    const eventResponses = chatUpdate.update?.eventResponses\n    const agregate = getAggregateResponsesInEventMessage({ eventResponses }, jidNormalizedUser(chatunity.user.lid)) \n    console.log(agregate) \n})\n```\n\n### Summary of Events on First Connection\n\n1. `connection.update` is fired requesting socket restart\n2. History messages are received in `messaging.history-set`\n\n## Implementing a Data Store\n\nBaileys does not include built-in storage for chats, contacts, or messages. However, a simple in-memory implementation is provided:\n\n> [!IMPORTANT]\n> We highly recommend building your own data store, as storing entire chat history in memory wastes RAM.\n\n```ts\nimport makeWASocket, { makeInMemoryStore } from '@chatunity/baileys'\n\nconst store = makeInMemoryStore({ })\nstore.readFromFile('./baileys_store.json')\n\nsetInterval(() => {\n    store.writeToFile('./baileys_store.json')\n}, 10_000)\n\nconst chatunity = makeWASocket({ })\nstore.bind(chatunity.ev)\n\nchatunity.ev.on('chats.upsert', () => {\n    console.log('got chats', store.chats.all())\n})\n\nchatunity.ev.on('contacts.upsert', () => {\n    console.log('got contacts', Object.values(store.contacts))\n})\n```\n\n## WhatsApp IDs Explained\n\n- `id` (also called `jid`) is the WhatsApp ID of the person or group you're messaging.\n    - Format for people (PN): ```[country code][phone number]@s.whatsapp.net```\n        - Example: ```+19999999999@s.whatsapp.net```\n    - Format for people (LID): ```xxxxxxxxxx@lid``` (privacy-preserving, may not be reversible to PN)\n    - Format for groups: ``` 123456789-123345@g.us ```\n    - Broadcast lists: `[timestamp of creation]@broadcast`\n    - Stories: `status@broadcast`\n\n## Utility Functions\n\n- `getContentType` - returns the content type for any message\n- `getDevice` - returns the device from a message\n- `makeCacheableSignalKeyStore` - speeds up auth store\n- `downloadContentFromMessage` - downloads content from any message\n- `serializeMessage` - returns a message with `transportFromMe`, `sender`, `isAuthenticatedSelf`, `isOwner`, etc.\n- `isAuthenticatedSelf` - checks if an identity matches the authenticated socket\n- `isAuthorizedOwner` - checks if an identity is in the owner/sudo allowlist\n- `resolveLidWithTimeout` - bounds asynchronous LID resolution without reprocessing a message\n- `buildUnifiedResponse` / `buildRichMessage` / `RichBuilder` - build Android Rich HTML payloads\n\n## Sending Messages\n\nSend all types of messages with a single function:\n- **[All message contents](https://baileys.whiskeysockets.io/types/AnyMessageContent.html)**\n- **[All options](https://baileys.whiskeysockets.io/types/MiscMessageGenerationOptions.html)**\n\n```ts\nawait chatunity.sendMessage(jid, content, options)\n```\n\n### Non-Media Messages\n\n#### Text Message\n```ts\nawait chatunity.sendMessage(jid, { text: 'hello world' })\n```\n\n#### Quote Message\n```ts\nawait chatunity.sendMessage(jid, { text: 'hello world' }, { quoted: message })\n```\n\nQuoted replies work for plain text without buttons. Mentions can be combined with a quote:\n\n```ts\nawait chatunity.sendMessage(jid, {\n    text: '@12345678901',\n    mentions: ['12345678901@s.whatsapp.net']\n}, { quoted: message })\n```\n\n#### Mention User\n```ts\nawait chatunity.sendMessage(jid, {\n    text: '@12345678901',\n    mentions: ['12345678901@s.whatsapp.net']\n})\n```\n\n#### Forward Messages\n```ts\nconst msg = getMessageFromStore()\nawait chatunity.sendMessage(jid, { forward: msg, force: true })\n```\n\n#### Location Message\n```ts\nawait chatunity.sendMessage(jid, {\n    location: {\n        degreesLatitude: 24.121231,\n        degreesLongitude: 55.1121221\n    }\n})\n```\n\n#### Live Location Message\n```ts\nawait chatunity.sendMessage(jid, {\n    location: {\n        degreesLatitude: 24.121231,\n        degreesLongitude: 55.1121221\n    }, \n    live: true\n})\n```\n\n#### Contact Message\n```ts\nconst vcard = 'BEGIN:VCARD\\n'\n            + 'VERSION:3.0\\n' \n            + 'FN:Jeff Singh\\n'\n            + 'ORG:Ashoka Uni\\n'\n            + 'TEL;type=CELL;type=VOICE;waid=911234567890:+91 12345 67890\\n'\n            + 'END:VCARD'\n\nawait chatunity.sendMessage(id, { \n    contacts: { \n        displayName: 'Itchatunitychann', \n        contacts: [{ vcard }] \n    }\n})\n```\n\n#### Reaction Message\n```ts\nawait chatunity.sendMessage(jid, {\n    react: {\n        text: '💖',\n        key: message.key\n    }\n})\n```\n\n#### Pin Message\n```ts\nawait chatunity.sendMessage(jid, {\n    pin: {\n        type: 1, // 2 to remove\n        time: 86400, // 24h in seconds\n        key: Key\n    }\n})\n```\n\n#### Keep Message\n```ts\nawait chatunity.sendMessage(jid, {\n    keep: {\n        key: Key,\n        type: 1\n    }\n})\n```\n\n#### Poll Message\n```ts\nawait chatunity.sendMessage(jid, {\n    poll: {\n        name: 'My Poll',\n        values: ['Option 1', 'Option 2'],\n        selectableCount: 1,\n        toAnnouncementGroup: false\n    }\n})\n```\n\n#### Rich HTML Message\n\n```ts\nawait sock.sendRichMessage(jid, '<h1>Hello</h1><p>Android rich response</p>', {\n    responseId: 'optional-response-id',\n    trustedSources: []\n})\n```\n\nFor multiple rich sections:\n\n```ts\nconst rich = sock.createAIRich({ trustedSources: [] })\n    .addHtml('<h1>First section</h1>')\n    .addPrimitive({\n        __typename: 'GenAIaeacdsnwHtmlPrimitive',\n        payload: '<p>Second section</p>',\n        trusted_sources: []\n    })\n\nawait rich.send(jid)\n```\n\nRich HTML is **Android only**. iOS, WhatsApp Web, and Desktop behavior is controlled by the WhatsApp client and cannot be fixed by changing Baileys.\n\n#### Poll Result Message\n```ts\nawait chatunity.sendMessage(jid, {\n    pollResult: {\n        name: 'Hi', \n        values: [['Option 1', 1000], ['Option 2', 2000]]\n    }\n})\n```\n\n#### Call Message\n```ts\nawait chatunity.sendMessage(jid, {\n    call: {\n        name: 'Hey',\n        type: 1 // 2 for video\n    }\n})\n```\n\n#### Event Message\n```ts\nawait chatunity.sendMessage(jid, {\n    event: {\n        isCanceled: false,\n        name: 'Holiday together!',\n        description: 'Who wants to come along?', \n        location: {\n            degreesLatitude: 24.121231,\n            degreesLongitude: 55.1121221,\n            name: 'Location name'\n        },\n        call: 'audio',\n        startTime: number, \n        endTime: number, \n        extraGuestsAllowed: true\n    }\n})\n```\n\n#### Order Message\n```ts\nawait chatunity.sendMessage(jid, {\n    order: {\n        orderId: '574xxx',\n        thumbnail: 'your_thumbnail', \n        itemCount: 'your_count',\n        status: 'INQUIRY',\n        surface: 'CATALOG',\n        message: 'your_caption',\n        orderTitle: \"your_title\",\n        sellerJid: 'your_jid',\n        token: 'your_token',\n        totalAmount1000: 'your_amount',\n        totalCurrencyCode: 'IDR'\n    }\n})\n```\n\n#### Product Message\n```ts\nawait chatunity.sendMessage(jid, {\n    product: {\n        productImage: { url: 'your_url' },\n        productId: 'your_id', \n        title: 'your_title',\n        description: 'your_description', \n        currencyCode: 'IDR', \n        priceAmount1000: 'your_amount', \n        url: 'your_url',\n        productImageCount: 'your_imageCount'\n    },\n    businessOwnerJid: 'your_jid' \n})\n```\n\n#### Payment Message\n```ts\nawait chatunity.sendMessage(jid, {\n    payment: {\n        note: 'Hi!',\n        currency: 'IDR',\n        amount: '10000',\n        expiry: 0\n    }\n})\n```\n\n#### Request Payment Message\n\n```ts\nawait sock.sendMessage(jid, {\n    requestPayment: {\n        currency: 'EUR',\n        amount: 12.50,\n        from: '123456789@s.whatsapp.net',\n        note: 'Payment required',\n        expiry: Math.floor(Date.now() / 1000) + 3600\n    }\n})\n```\n\n`currency` must be an ISO 4217 code, `amount` must be positive and finite, and `from` must be a valid JID. The authenticated socket identity remains the sender identity; `from` is the protocol `requestFrom` field. Configure the amount limit with `maxPaymentAmount`.\n\n#### Check Business Number Status\n\n```ts\nconst status = await sock.numcheck()\nconsole.log({\n    jid: status.jid,\n    banned: status.banned,\n    bannedAt: status.bannedAt,\n    reviewSubmitted: status.reviewSubmitted,\n    reviewSentAt: status.reviewSentAt,\n    reviewStatus: status.reviewStatus\n})\n```\n\n`numcheck` is an empirical reachability check based on the response exposed by WhatsApp. It is not an official ban certificate, and WhatsApp may omit ban or review timestamps.\n\n#### Payment Invite Message\n```ts\nawait chatunity.sendMessage(id, { \n    paymentInvite: {\n        type: 1,\n        expiry: 0 \n    }   \n})\n```\n\n#### Admin Invite Message\n```ts\nawait chatunity.sendMessage(jid, {\n    adminInvite: {\n        jid: '123xxx@newsletter',\n        name: 'newsletter_name', \n        caption: 'Please be my channel admin',\n        expiration: 86400\n    }\n})\n```\n\n#### Group Invite Message\n```ts\nawait chatunity.sendMessage(jid, {\n    groupInvite: {\n        jid: '123xxx@g.us',\n        name: 'group_name', \n        caption: 'Please Join My WhatsApp Group',\n        code: 'code_invite',\n        expiration: 86400\n    }\n})\n```\n\n#### Sticker Pack Message\n```ts\nawait chatunity.sendMessage(jid, {\n    stickerPack: {\n        name: 'Hiii', \n        publisher: 'By Itchatunitychann', \n        description: 'Hello', \n        cover: Buffer,\n        stickers: [{\n            sticker: { url: 'https://example.com/1234kjd.webp' }, \n            emojis: ['❤'],\n            isLottie: false,\n            isAnimated: false\n        }]\n    }\n})\n```\n\n#### Share Phone Number Message\n```ts\nawait chatunity.sendMessage(jid, { sharePhoneNumber: {} })\n```\n\n#### Request Phone Number Message\n```ts\nawait chatunity.sendMessage(jid, { requestPhoneNumber: {} })\n```\n\n#### Button Reply Message\n```ts\n// List\nawait chatunity.sendMessage(jid, {\n    buttonReply: {\n        name: 'Hi', \n        description: 'description', \n        rowId: 'ID'\n    }, \n    type: 'list'\n})\n\n// Plain\nawait chatunity.sendMessage(jid, {\n    buttonReply: {\n        displayText: 'Hi', \n        id: 'ID'\n    }, \n    type: 'plain'\n})\n\n// Template\nawait chatunity.sendMessage(jid, {\n    buttonReply: {\n        displayText: 'Hi', \n        id: 'ID', \n        index: 'number'\n    }, \n    type: 'template'\n})\n\n// Interactive\nawait chatunity.sendMessage(jid, {\n    buttonReply: {\n        body: 'Hi', \n        nativeFlows: {\n            name: 'menu_options', \n            paramsJson: JSON.stringify({ id: 'ID', description: 'description' }),\n            version: 1\n        }\n    }, \n    type: 'interactive'\n})\n```\n\n#### Buttons Message\n```ts\nawait chatunity.sendMessage(jid, {\n    text: 'This is a button message!',\n    footer: 'Hello World!',  \n    buttons: [{ \n        buttonId: 'Id1', \n        buttonText: { displayText: 'Button 1' }\n    }, { \n        buttonId: 'Id2', \n        buttonText: { displayText: 'Button 2' }\n    }]\n})\n```\n\n#### Buttons List Message\n```ts\nawait chatunity.sendMessage(jid, {\n    text: 'This is a list!', \n    footer: 'Hello World!', \n    title: 'Amazing list title', \n    buttonText: 'View list', \n    sections: [{\n        title: 'Section 1',\n        rows: [{\n            title: 'Option 1', \n            rowId: 'option1'\n        }, {\n            title: 'Option 2', \n            rowId: 'option2', \n            description: 'Description'\n        }]\n    }]\n})\n```\n\n#### Buttons Product List Message\n```ts\nawait chatunity.sendMessage(jid, {\n    text: 'This is a list!', \n    footer: 'Hello World!', \n    title: 'Product list', \n    buttonText: 'View list', \n    productList: [{\n        title: 'This is a title', \n        products: [{ productId: '1234' }, { productId: '5678' }]\n    }], \n    businessOwnerJid: '628xxx@s.whatsapp.net', \n    thumbnail: 'https://example.com/image.jpg'\n})\n```\n\n#### Buttons Cards Message\n```ts\nawait chatunity.sendMessage(jid, {\n    text: 'Body message',\n    title: 'Title message', \n    cards: [{\n        image: { url: 'https://example.com/image.jpg' },\n        title: 'Card title',\n        body: 'Card body',\n        footer: 'Card footer',\n        buttons: [{\n            name: 'quick_reply',\n            buttonParamsJson: JSON.stringify({\n                display_text: 'Button',\n                id: 'ID'\n            })\n        }]\n    }]\n})\n```\n\n#### Buttons Interactive Message (Native Flow)\n```ts\nawait chatunity.sendMessage(jid, {\n    text: 'Interactive message',\n    title: 'Title',\n    footer: 'Footer',\n    interactiveButtons: [\n        {\n            name: 'quick_reply',\n            buttonParamsJson: JSON.stringify({\n                display_text: 'Click Me!',\n                id: 'your_id'\n            })\n        },\n        {\n            name: 'cta_url',\n            buttonParamsJson: JSON.stringify({\n                display_text: 'Follow',\n                url: 'https://whatsapp.com/channel/0029Vag9VSI2ZjCocqa2lB1y'\n            })\n        },\n        {\n            name: 'cta_call',\n            buttonParamsJson: JSON.stringify({\n                display_text: 'Call',\n                phone_number: '628xxx'\n            })\n        }\n    ]\n})\n```\n\n> [!TIP]\n> For new projects, prefer the helpers in `lib/Utils/interactive` (`sendNativeFlowButtons`, `sendCompatibleInteractive`) which add validation, allowlists, and fallback.\n\n#### Buttons Interactive Message PIX\n```ts\nawait chatunity.sendMessage(jid, { \n    text: '',\n    interactiveButtons: [{ \n        name: 'payment_info', \n        buttonParamsJson: JSON.stringify({ \n            payment_settings: [{\n                type: \"pix_static_code\", \n                pix_static_code: { \n                    merchant_name: 'Your Name', \n                    key: 'example@email.com', \n                    key_type: 'EMAIL'\n                } \n            }] \n        }) \n    }] \n})\n```\n\n#### Buttons Interactive Message PAY\n```ts\nawait chatunity.sendMessage(jid, { \n    text: '',\n    interactiveButtons: [{ \n        name: 'review_and_pay', \n        buttonParamsJson: JSON.stringify({ \n            currency: 'IDR', \n            total_amount: { value: '999999999', offset: '100' }, \n            reference_id: '45XXXXX',\n            type: 'physical-goods',\n            order: {\n                status: 'completed', \n                items: [{\n                    name: 'Product', \n                    amount: { value: '999999999', offset: '100' }, \n                    quantity: '1'\n                }]\n            }\n        }) \n    }] \n})\n```\n\n#### Status Mentions Message\n```ts\nconst jids = ['123451679@g.us', '62689xxxx@s.whatsapp.net']\n\n// Text\nawait chatunity.sendStatusMentions(\n    {\n        text: 'Hello Everyone :3', \n        font: 2\n    }, \n    jids\n)\n\n// Image\nawait chatunity.sendStatusMentions(\n    { image: { url: 'https://example.com/image.jpg' } }, \n    jids\n)\n\n// Video\nawait chatunity.sendStatusMentions(\n    { video: { url: 'https://example.com/video.mp4' } }, \n    jids\n)\n```\n\n#### Shop Message\n```ts\nawait chatunity.sendMessage(jid, {      \n    text: 'Body',\n    title: 'Title', \n    footer: 'Footer',\n    shop: {\n        surface: 1,\n        id: 'https://example.com'\n    }, \n    viewOnce: true\n})\n```\n\n#### Collection Message\n```ts\nawait chatunity.sendMessage(jid, {      \n    text: 'Body',\n    title: 'Title', \n    footer: 'Footer',\n    collection: {\n        bizJid: 'jid', \n        id: 'https://example.com', \n        version: 1\n    }, \n    viewOnce: true\n})\n```\n\n### Media Messages\n\nSending media (video, stickers, images) is easier and more efficient.\n\n> [!NOTE]\n> You can pass `{ stream: Stream }`, `{ url: Url }`, or `Buffer` directly. See more [here](https://baileys.whiskeysockets.io/types/WAMediaUpload.html)\n\n> [!TIP]\n> Use Stream or Url to save memory\n\n#### GIF Message\n```ts\nawait chatunity.sendMessage(jid, { \n    video: fs.readFileSync('Media/gif.mp4'),\n    caption: 'hello world',\n    gifPlayback: true\n})\n```\n\n#### Video Message\n```ts\nawait chatunity.sendMessage(id, { \n    video: { url: './Media/video.mp4' },\n    caption: 'hello world'\n})\n```\n\n#### Video PTV Message\n```ts\nawait chatunity.sendMessage(id, { \n    video: { url: './Media/video.mp4' },\n    ptv: true\n})\n```\n\n#### Audio Message\nAudio needs to be converted to OGG format with ffmpeg:\n```bash\nffmpeg -i input.mp4 -avoid_negative_ts make_zero -ac 1 output.ogg\n```\n\n```ts\nawait chatunity.sendMessage(jid, {\n    audio: { url: './Media/audio.mp3' },\n    mimetype: 'audio/mp4'\n})\n```\n\n#### Image Message\n```ts\nawait chatunity.sendMessage(id, { \n    image: { url: './Media/image.png' },\n    caption: 'hello world'\n})\n```\n\n#### Album Message\n```ts\nawait chatunity.sendMessage(id, { \n    album: [{\n        image: { url: 'https://example.com/image.jpg' }, \n        caption: 'Caption'\n    }, {\n        video: { url: 'https://example.com/video.mp4' }, \n        caption: 'Caption'\n    }]\n})\n```\n\n#### View Once Message\n```ts\nawait chatunity.sendMessage(id, { \n    image: { url: './Media/image.png' },\n    viewOnce: true,\n    caption: 'hello world'\n})\n```\n\n### Link Previews\n\nBy default, WhatsApp does not generate link previews when sent from web. Baileys provides this functionality.\n\nTo enable link previews, add `link-preview-js` to your project:\n```bash\nyarn add link-preview-js\n```\n\nThen send a link:\n```ts\nawait chatunity.sendMessage(jid, {\n    text: 'Hi, this was sent using https://github.com/whiskeysockets/baileys'\n})\n```\n\n### AI Icon Feature\n```ts\nawait chatunity.sendMessage(jid, { text: 'Hi' }, { ai: true })\n\n// With relay\nawait chatunity.relayMessage(jid, { extendedTextMessage: { text: 'Hi' } }, { AI: true })\n```\n\n## Modifying Messages\n\n### Delete Messages (for everyone)\n\n```ts\nconst msg = await chatunity.sendMessage(jid, { text: 'hello world' })\nawait chatunity.sendMessage(jid, { delete: msg.key })\n```\n\n### Editing Messages\n\n```ts\nawait chatunity.sendMessage(jid, { edit: msg.key, text: 'edited message' })\n```\n\n## Working with Media\n\n### Thumbnail in Media Messages\n\nThumbnails can be generated automatically for images & stickers if you add `jimp` or `sharp`:\n```bash\nyarn add jimp\n# or\nyarn add sharp\n```\n\nFor videos, install `ffmpeg` on your system.\n\n### Downloading Media Messages\n\n```ts\nimport { createWriteStream } from 'fs'\nimport { downloadMediaMessage, getContentType } from '@chatunity/baileys'\n\nchatunity.ev.on('messages.upsert', async ({ messages }) => {\n    for (const m of messages) {\n        if (!m.message) return\n        const messageType = getContentType(m)\n\n        if (messageType === 'imageMessage') {\n            const stream = await downloadMediaMessage(m, 'stream', {}, { \n                logger,\n                reuploadRequest: chatunity.updateMediaMessage\n            })\n            stream.pipe(createWriteStream('./my-download.jpeg'))\n        }\n    }\n})\n```\n\n### Re-upload Media Message to WhatsApp\n\n```ts\nconst downloadedContent = await downloadMediaMessage(...)\nconst uploadedUrl = await chatunity.uploadMedia(downloadedContent)\n```\n\n# Table of Contents\n\n- [Connecting Account](#connecting-account)\n    - [Connect with QR-CODE](#connect-with-qr-code)\n    - [Connect with Pairing Code](#connect-with-pairing-code)\n    - [Receive Full History](#receive-full-history)\n- [Socket Configuration](#socket-configuration)\n    - [Cache Group Metadata](#cache-group-metadata)\n    - [Improve Retry System & Decrypt Poll Votes](#improve-retry-system--decrypt-poll-votes)\n    - [Receive Notifications in WhatsApp App](#receive-notifications-in-whatsapp-app)\n- [Saving & Restoring Sessions](#saving--restoring-sessions)\n- [Handling Events](#handling-events)\n    - [Example to Start](#example-to-start)\n    - [Decrypt Poll Votes](#decrypt-poll-votes)\n    - [Decrypt Event Response](#decrypt-event-response) \n    - [Summary of Events on First Connection](#summary-of-events-on-first-connection)\n- [Implementing a Data Store](#implementing-a-data-store)\n- [WhatsApp IDs Explained](#whatsapp-ids-explained)\n- [Utility Functions](#utility-functions)\n- [Sending Messages](#sending-messages)\n    - [Non-Media Messages](#non-media-messages)\n    - [Media Messages](#media-messages)\n    - [Link Previews](#link-previews)\n- [Modifying Messages](#modifying-messages)\n    - [Delete Messages](#delete-messages-for-everyone)\n    - [Edit Messages](#editing-messages)\n- [Working with Media](#working-with-media)\n    - [Thumbnails](#thumbnail-in-media-messages)\n    - [Downloading Media](#downloading-media-messages)\n    - [Re-uploading Media](#re-upload-media-message-to-whatsapp)\n- [Chat Management](#chat-management)\n    - [Read States](#reading-messages)\n    - [Presence](#update-presence)\n    - [Modifying Chats](#modifying-chats)\n- [User Queries](#user-queries)\n- [Profile Management](#change-profile)\n- [Groups](#groups)\n- [Privacy](#privacy)\n- [Broadcast Lists & Stories](#broadcast-lists--stories)\n- [Advanced Usage](#advanced-usage)\n","readmeFilename":"README.MD","homepage":"https://www.npmjs.com/package/@chatunity/baileys","keywords":["baileys","chatunity","wabot","whatsapp","js-whatsapp","whatsapp-api","whatsapp-web","whatsapp-bot","automation","multi-device","chatunity"],"repository":{"url":"https://www.npmjs.com/package/@chatunity/baileys"},"author":{"name":"chatunity"},"license":"MIT"}