{"_id":"@mr-supun-fernando/supunmd-bail","name":"@mr-supun-fernando/supunmd-bail","dist-tags":{"latest":"3.0.3"},"versions":{"3.0.3":{"name":"@mr-supun-fernando/supunmd-bail","version":"3.0.3","description":"WhatsApp API Modification By Supun Fernando","keywords":["whatsapp","baileys","whatsapp-web","whatsapp-chat","whatsapp-group","whatsapp-bot","automation","whatsapp-api","baileys-mod","supun-md","supun-fernando","dtz","dark-shadow-modz","ds-modz","wa-bot"],"homepage":"https://www.npmjs.com/mr-supun-fernando","repository":{"url":"https://www.npmjs.com/package/@mr-supun-fernando/supunmd-bail"},"license":"MIT","author":{"name":"Supun-Fernando"},"main":"lib/index.js","types":"lib/index.d.ts","scripts":{"build:all":"tsc && typedoc","build:docs":"typedoc","build:tsc":"tsc","changelog:last":"conventional-changelog -p angular -r 2","changelog:preview":"conventional-changelog -p angular -u","gen:protobuf":"sh WAProto/GenerateStatics.sh","lint":"eslint src --ext .js,.ts,.jsx,.tsx","lint:fix":"eslint src --fix --ext .js,.ts,.jsx,.tsx","prepack":"","prepare":"","preinstall":"node ./engine-requirements.js","release":"release-it","test":"jest"},"dependencies":{"@cacheable/node-cache":"^1.4.0","@hapi/boom":"^9.1.3","async-mutex":"^0.5.0","libsignal":"github:tenka-san/libsignal-node","lru-cache":"^11.1.0","music-metadata":"^11.12.3","p-queue":"^9.0.0","pino":"^9.6","protobufjs":"^7.5.6","whatsapp-rust-bridge":"0.5.4","ws":"^8.13.0","chalk":"^4.1.2","cache-manager":"^7.2.8"},"devDependencies":{"@eslint/eslintrc":"^3.3.1","@eslint/js":"^9.31.0","@types/jest":"^30.0.0","@types/node":"^20.9.0","@types/ws":"^8.0.0","@typescript-eslint/eslint-plugin":"^8","@typescript-eslint/parser":"^8","@whiskeysockets/eslint-config":"^1.0.0","conventional-changelog":"^7.1.1","conventional-changelog-angular":"^8.0.0","esbuild-register":"^3.6.0","eslint":"^9","eslint-config-prettier":"^10.1.2","eslint-plugin-prettier":"^5.4.0","jest":"^30.0.5","jimp":"^1.6.1","jiti":"^2.4.2","json":"^11.0.0","link-preview-js":"^3.0.0","lru-cache":"^11.1.0","open":"^8.4.2","pino-pretty":"^13.1.1","prettier":"^3.5.3","protobufjs-cli":"^1.1.3","release-it":"^20.0.1","ts-jest":"^29.4.0","tsc-esm-fix":"^3.1.2","tsx":"^4.20.3","typedoc":"^0.27.9","typedoc-plugin-markdown":"4.4.2","typescript":"^5.8.2"},"peerDependencies":{"audio-decode":"^2.1.3","jimp":"^1.6.1","link-preview-js":"^3.0.0","sharp":"*"},"resolutions":{"ajv@npm:^6.12.4":"^6.14.0","basic-ftp":"^5.2.4","brace-expansion@npm:^1.1.7":"^1.1.13","brace-expansion@npm:^2.0.1":"^2.0.3","flatted":"^3.4.2","glob@npm:^10.2.2":"^10.5.0","glob@npm:^10.3.10":"^10.5.0","glob@npm:^10.5.0":"^10.5.0","handlebars":"^4.7.9","ip-address":"^10.1.1","js-yaml@npm:^3.13.1":"^3.14.2","js-yaml@npm:^4.1.0":"^4.1.1","markdown-it":"^14.1.1","minimatch@npm:^3.0.4":"^3.1.5","minimatch@npm:^3.1.2":"^3.1.5","minimatch@npm:^5.0.1":"^5.1.8","minimatch@npm:^9.0.4":"^9.0.9","minimatch@npm:^9.0.5":"^9.0.9","picomatch@npm:^2.0.4":"^2.3.2","picomatch@npm:^2.3.1":"^2.3.2","picomatch@npm:^4.0.0":"^4.0.4","picomatch@npm:^4.0.2":"^4.0.4","socks":"^2.8.8","tar":"^7.5.11","tmp":"^0.2.5","underscore":"^1.13.8","yaml@npm:^2.6.1":"^2.8.4"},"peerDependenciesMeta":{"audio-decode":{"optional":true},"jimp":{"optional":true},"link-preview-js":{"optional":true}},"packageManager":"yarn@4.9.2","engines":{"node":">=20.0.0"},"contributors":[{"name":"WhiskeySockets","url":"original Baileys authors"}],"_id":"@mr-supun-fernando/supunmd-bail@3.0.3","_nodeVersion":"26.4.0","_npmVersion":"11.19.1","dist":{"integrity":"sha512-EUICfLmvIC+NhaA+vDyv4sYJN2BS3qJTwYOUkx2AgkBRCu9IEnq/pnyaTqPGrOgvk9htIBuL+kFx9yoBR3iANA==","shasum":"272dea75a155531af96778250d44a421f9ef1b57","tarball":"https://registry.npmjs.org/@mr-supun-fernando/supunmd-bail/-/supunmd-bail-3.0.3.tgz","fileCount":117,"unpackedSize":17409725,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCAZgPhgwMWyX8tAZ/fbu3Il/fP6P7Ls7X7Vu/L4B+JDQIgBHm1ujs1nyx2G0bQ5hyg+mYERtE6y+BkXUH0BqisDoQ="}]},"_npmUser":{"name":"mr-supun-fernando","email":"supunfernando179@gmail.com"},"directories":{},"maintainers":[{"name":"mr-supun-fernando","email":"supunfernando179@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/supunmd-bail_3.0.3_1790051188314_0.6544408882121902"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-22T04:26:28.086Z","3.0.3":"2026-09-22T04:26:28.540Z","modified":"2026-09-22T04:26:28.738Z"},"maintainers":[{"name":"mr-supun-fernando","email":"supunfernando179@gmail.com"}],"description":"WhatsApp API Modification By Supun Fernando","homepage":"https://www.npmjs.com/mr-supun-fernando","keywords":["whatsapp","baileys","whatsapp-web","whatsapp-chat","whatsapp-group","whatsapp-bot","automation","whatsapp-api","baileys-mod","supun-md","supun-fernando","dtz","dark-shadow-modz","ds-modz","wa-bot"],"repository":{"url":"https://www.npmjs.com/package/@mr-supun-fernando/supunmd-bail"},"contributors":[{"name":"WhiskeySockets","url":"original Baileys authors"}],"author":{"name":"Supun-Fernando"},"license":"MIT","readme":"<div align=\"center\">\n<img src=\"https://capsule-render.vercel.app/api?type=waving&height=220&color=0:ff6b6b,40:f06595,100:845ef7&text=@mr-supun-fernando/supunmd-bail&fontAlignY=40&fontSize=44&fontColor=ffffff&desc=Stable%20WhatsApp%20Web%20API%20Fork%20for%20Production%20Bots&descAlignY=60&descSize=16\" alt=\"Header Banner\" />\n\n<br/>\n\n<!-- Rounded + border image -->\n<a href=\"https://supunofc.site\">\n  <kbd>\n    <img src=\"https://i.ibb.co/KjfHTDhN/file-00000000a86881f8801b23682cb9bf66.png\" alt=\"WhatsApp Baileys 2026\" width=\"720\" />\n  </kbd>\n</a>\n\n<br/><br/>\n\n\n# 🧑‍💻 supunmd-bail 🇱🇰\n\n<p>\n  <img src=\"https://img.shields.io/badge/Node.js-%3E%3D20-339933?style=for-the-badge&logo=nodedotjs&logoColor=white\" />\n  <img src=\"https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white\" />\n  <img src=\"https://img.shields.io/badge/WebSocket-010101?style=for-the-badge&logo=socketdotio&logoColor=white\" />\n  <img src=\"https://img.shields.io/badge/Open%20Source-FF4500?style=for-the-badge&logo=github&logoColor=white\" />\n  <img src=\"https://img.shields.io/badge/license-MIT-blue?style=for-the-badge\" />\n</p>\n\n<p>\n  <img src=\"https://img.shields.io/npm/v/@mr-supun-fernando/supunmd-bail?style=flat-square&color=25D366&label=npm\" />\n  <img src=\"https://img.shields.io/badge/maintained%20by-Supun%20Fernando-black?style=flat-square\" />\n</p>\n\n**Open-source WhatsApp automation library — no browser required.**\nBuilt on WebSocket for speed, stability, and full multi-device support.\n\n<br/>\n\n[Installation](#-getting-started) • [Features](#-main-features) • [Stability](#-stability--disconnect-handling) • [Website](https://supunofc.site) • [WhatsApp Channel](https://whatsapp.com/channel/0029Vb55cv41nozBTTIw1y07) • [YouTube](https://www.youtube.com/@darkshadow_zap)\n\n</div>\n\n---\n\n## ✨ What is supunmd-bail?\n\n**supunmd-bail** (`@mr-supun-fernando/supunmd-bail`) is a powerful, open-source WhatsApp Web library built on top of the Baileys protocol stack — extended with features not found in any other public fork. It connects directly to WhatsApp's multi-device WebSocket protocol. No Selenium, no Puppeteer, no browser overhead.\n\n> ⚡ **Node.js ≥ 20 required.**\n\n---\n\n## 🚀 Getting Started\n\n```bash\nnpm install @mr-supun-fernando/supunmd-bail\n```\n\n```javascript\nimport { makeWASocket, useMultiFileAuthState } from '@mr-supun-fernando/supunmd-bail'\n\nconst { state, saveCreds } = await useMultiFileAuthState('auth_info')\nconst sock = makeWASocket({\n    auth: state,\n    syncFullHistory: false,  // skip history sync — bot works immediately\n    aiLabel: true,           // stamp messages with AI bot marker (default: true)\n})\n\nsock.ev.on('creds.update', saveCreds)\n```\n\n---\n\n## 🧩 Main Features\n\n| Feature | Description |\n|---|---|\n| 💬 **Rich Response (GenAI Bubble)** | Send Meta AI-style messages: markdown, code blocks, tables, LaTeX, maps, inline images, HTML — rendered natively as GenAI bubble in WA client |\n| 🚫 **4-Factor Ban Checker** | Detect ban status via 4 independent signals: live registry, public send-page, identity-key probe, device-count signature |\n| 🆔 **Username Socket (w:mex)** | Full WA username API: check availability, set, delete, pin, find by username, fetch recommendations — via WhatsApp's internal Pando/MEX GraphQL protocol |\n| 🏘️ **Communities Socket** | Full community management: create, link/unlink groups, manage participants, invite codes, ephemeral toggle, approval mode |\n| 🔕 **noSelfSync** | Skip syncing outgoing messages to your own other devices — reduces noise and bandwidth. Includes silent-drop guard (throws 421 instead of pretending the send succeeded) |\n| ⚙️ **Rust-powered Crypto** | `md5`, `hkdf`, LT-Hash anti-tampering offloaded to `whatsapp-rust-bridge` native module for raw speed |\n| 🗂️ **LID Mapping Store** | Persistent LID ↔ phone-number bi-directional cache with LRU eviction and in-flight dedup — prevents duplicate USync lookups |\n| 🔐 **Pre-Key Manager** | Concurrency-safe Signal pre-key operations via per-key-type PQueue — no race conditions on key updates/deletions |\n| 🔄 **Classify Disconnect** | Maps every WA disconnect code to `{ category, shouldReconnect, backoffMs }` — properly handles code 515 (restartRequired) as recoverable, not fatal |\n| ⏱️ **Rate Limiter** | Anti-spam pacing calculator: enforces per-minute/hour/day caps, burst allowance, new-chat delays, identical-message dedup |\n| 🖼️ **Album Message** | Send multiple images/videos as a single WA album/grid, with per-item or top-level caption and `gifPlayback` support |\n| 🤖 **AI Label Config** | `aiLabel: true/false` in socket config — controls whether outgoing messages carry the `biz_bot` attribute that WA uses to render the AI icon |\n| 🔎 **USync Username Protocol** | Username resolution baked into USync queries — resolve WA usernames alongside contacts in a single round-trip |\n| 📥 **Offline Node Processor** | Batch-processes pending stanzas received while offline, preventing message loss on reconnect |\n| 🔑 **Identity Change Handler** | Dedicated handler for Signal identity key changes — prevents session corruption when a contact re-registers |\n\n---\n\n## 💬 Rich Response (GenAI Bubble)\n\nSend messages that render as Meta AI-style bubbles inside WhatsApp. Supports multiple primitives in a single message:\n\n```javascript\n// Markdown text\nawait sock.sendMessage(jid, {\n    richResponse: {\n        text: '**Hello** from *supunmd-bail*',\n        responseId: 'optional-uuid'\n    }\n})\n\n// Code block\nawait sock.sendMessage(jid, {\n    richResponse: {\n        code: 'console.log(\"hello\")',\n        language: 'javascript'\n    }\n})\n\n// Table\nawait sock.sendMessage(jid, {\n    richResponse: {\n        table: {\n            rows: [\n                ['Name', 'Age'],\n                ['Alice', '25'],\n                ['Bob', '30']\n            ]\n        }\n    }\n})\n\n// HTML (raw HTML rendered in client)\nawait sock.sendMessage(jid, {\n    richResponse: {\n        text: 'fallback',\n        html: '<b>bold</b> <a href=\"https://example.com\">link</a>'\n    }\n})\n\n// LaTeX\nawait sock.sendMessage(jid, {\n    richResponse: {\n        latex: 'E = mc^2'\n    }\n})\n\n// Map / location\nawait sock.sendMessage(jid, {\n    richResponse: {\n        map: {\n            latitude: -6.2,\n            longitude: 106.8,\n            zoom: 15,\n            title: 'Jakarta',\n            annotations: []\n        }\n    }\n})\n\n// Inline image\nawait sock.sendMessage(jid, {\n    richResponse: {\n        imageUrl: 'https://example.com/photo.jpg'\n    }\n})\n```\n\n**Shortcut methods** (all accept `quoted` and `options`):\n\n```javascript\nawait sock.sendTable(jid, 'Title', ['H1','H2'], [['A','B']], quoted)\nawait sock.sendList(jid, 'Title', ['item1','item2'], quoted)\nawait sock.sendCodeBlock(jid, 'print(\"hello\")', quoted, { language: 'python' })\nawait sock.sendLatex(jid, quoted, { latex: 'x^2 + y^2 = z^2' })\nawait sock.sendRichMessage(jid, submessages, quoted)\n```\n\n---\n\n## 🖼️ Album Message\n\nSend multiple images/videos grouped into a single WA album:\n\n```javascript\nawait sock.sendMessage(jid, {\n    album: [\n        { image: { url: 'https://example.com/a.jpg' } },\n        { image: { url: 'https://example.com/b.jpg' }, caption: 'caption foto kedua' },\n        { video: { url: 'https://example.com/c.mp4' }, gifPlayback: false }\n    ],\n    caption: 'caption ini otomatis ke item pertama'\n})\n```\n\n---\n\n## 🚫 Ban Checker\n\n4-factor ban detection against WhatsApp's own servers — no third-party API:\n\n```javascript\nconst result = await sock.checkBanStatus('628123456789')\n// or: sock.checkBanStatus('628123456789@s.whatsapp.net')\n\nconsole.log(result)\n// {\n//   status: 'ACTIVE' | 'PROFILE_HIDDEN' | 'LIKELY_ACTIVE' | 'BANNED' | 'OFF_WHATSAPP' | 'UNKNOWN',\n//   emoji: '🟢' | '🟡' | '🔴' | '❓',\n//   confidence: 0..1,\n//   deviceCount: number | null,\n//   registryExists: boolean | null,\n//   pageVisible: boolean | null,\n//   profileName: string | null\n// }\n```\n\n**Four factors checked:**\n- **Factor A** — Live registry (`sock.onWhatsApp`)\n- **Factor B** — Public send-page title/image probe (`api.whatsapp.com`)\n- **Factor C** — Identity-key device probe via USync (strongest: banned numbers have their keys destroyed)\n- **Factor D** — Device-count signature (2+ = ACTIVE, 1 generic = likely BANNED, 0 = BANNED/OFF_WA)\n\n---\n\n## 🆔 Username Socket (w:mex)\n\nFull WA `@username` API via WhatsApp's internal Pando/MEX GraphQL protocol, query IDs sourced from Java decompile of WA 2.26.17.2:\n\n```javascript\n// Check availability\nconst res = await sock.checkUsername('myusername')\n// { available: true, username } or { available: false, suggestions: [...] }\n\n// Set username\nawait sock.setUsername('myusername')\n\n// Delete username\nawait sock.deleteUsername()\n\n// Get your own username\nconst mine = await sock.getMyUsername()\n\n// Pin/unpin username\nawait sock.setUsernamePin(true)\n\n// Find user by username\nconst user = await sock.findUserByUsername('someuser', pin)\n\n// Fetch usernames of your contacts in batch\nconst usernames = await sock.fetchContactUsernames('94xxxx@s.whatsapp.net', '628yyy@s.whatsapp.net')\n\n// Get username suggestions\nconst suggestions = await sock.getUsernameRecommendations()\n```\n\n---\n\n## 🏘️ Communities Socket\n\n```javascript\n// Create community\nconst community = await sock.communityCreate('Community Name', 'Description')\n\n// Create group inside community\nawait sock.communityCreateGroup('Group Name', [jid1, jid2], communityJid)\n\n// Link/unlink existing group\nawait sock.communityLinkGroup(groupJid, communityJid)\nawait sock.communityUnlinkGroup(groupJid, communityJid)\n\n// Fetch linked groups\nconst groups = await sock.communityFetchLinkedGroups(communityJid)\n\n// Manage participants\nawait sock.communityParticipantsUpdate(communityJid, [jid1], 'add')   // 'add' | 'remove' | 'promote' | 'demote'\n\n// Invite code\nconst code = await sock.communityInviteCode(communityJid)\nawait sock.communityRevokeInvite(communityJid)\nawait sock.communityAcceptInvite(code)\n\n// Settings\nawait sock.communityToggleEphemeral(communityJid, 86400)   // seconds\nawait sock.communityMemberAddMode(communityJid, 'admin_add')\nawait sock.communityJoinApprovalMode(communityJid, 'on')\nawait sock.communityUpdateSubject(communityJid, 'New Name')\nawait sock.communityUpdateDescription(communityJid, 'New Desc')\nawait sock.communityLeave(communityJid)\n```\n\n---\n\n## 🔕 noSelfSync\n\nSkip syncing outgoing messages to your own linked devices. Useful for high-volume bots where sync traffic is unnecessary:\n\n```javascript\nawait sock.sendMessage(jid, { text: 'hello' }, { noSelfSync: true })\n\n// Also supported in all shortcut methods:\nawait sock.sendTable(jid, title, headers, rows, quoted, { noSelfSync: true })\nawait sock.sendCodeBlock(jid, code, quoted, { noSelfSync: true })\n```\n\n> **Safe by design:** if `noSelfSync` would accidentally drop all recipients (e.g. messaging yourself), the guard kicks in and delivers normally. If the other party has zero resolved devices, it throws `Boom 421` instead of silently pretending the message was sent.\n\n---\n\n## 🔄 Stability & Disconnect Handling\n\nsupunmd-bail ships `classifyDisconnect()` — maps every WA status code into an actionable result:\n\n```javascript\nimport { classifyDisconnect } from '@mr-supun-fernando/supunmd-bail'\n\nsock.ev.on('connection.update', ({ connection, lastDisconnect }) => {\n    if (connection === 'close') {\n        const code = lastDisconnect?.error?.output?.statusCode\n        const info = classifyDisconnect(code)\n\n        console.log(info)\n        // {\n        //   category: 'fatal' | 'recoverable' | 'rate-limited' | 'unknown',\n        //   shouldReconnect: boolean,\n        //   backoffMs: number,    // ms to wait before reconnecting\n        //   message: string,\n        //   code: number\n        // }\n\n        if (info.shouldReconnect) {\n            setTimeout(() => reconnect(), info.backoffMs)\n        }\n    }\n})\n```\n\n**Code map:**\n\n| Code | Category | Reconnect | Backoff |\n|---|---|---|---|\n| 401, 440 | fatal | ❌ | — |\n| 515 | recoverable | ✅ | 0 ms (immediate) |\n| 405 | fatal | ❌ | — |\n| 408 | recoverable | ✅ | 30 s |\n| 503 | recoverable | ✅ | 5 min |\n| 429 | rate-limited | ✅ | 60 s |\n| 500 | recoverable | ✅ | 5 s |\n| 503 | recoverable | ✅ | 10 s |\n| Graceful close | recoverable | ✅ | 2 s |\n| Unknown | unknown | ✅ | 15 s |\n\n> **Important:** Code 515 (`restartRequired`) is WhatsApp's normal post-pairing signal. supunmd-bail correctly treats it as recoverable with 0 ms backoff — other forks incorrectly mark it as fatal, causing bots to stop after first pair.\n\n---\n\n## ⏱️ Rate Limiter\n\nAnti-ban pacing calculator — wire into your send path before each `sendMessage`:\n\n```javascript\nimport { RateLimiter } from '@mr-supun-fernando/supunmd-bail'\n\nconst limiter = new RateLimiter({\n    maxPerMinute: 8,\n    maxPerHour: 200,\n    maxPerDay: 1500,\n    minDelayMs: 1500,\n    maxDelayMs: 5000,\n    newChatDelayMs: 3000,\n    maxIdenticalMessages: 3,\n    burstAllowance: 3\n})\n\nasync function safeSend(jid, content) {\n    const delay = await limiter.getDelay(jid, content)\n    if (delay === -1) throw new Error('Rate limit exceeded — blocked')\n    if (delay > 0) await new Promise(r => setTimeout(r, delay))\n    await sock.sendMessage(jid, content)\n    limiter.record(jid, content)\n}\n```\n\n---\n\n## 📦 Supported Message Types\n\nEvery WhatsApp message type is covered:\n\n- Text, image, video, audio, document, sticker, GIF/video note (PTV)\n- Location & live location\n- Contact / vCard\n- Poll (create, vote, add option, poll result)\n- Button, list, template, interactive (native flow)\n- Album (multiple media in one message)\n- Event & event invite\n- Group invite, group status, group mention\n- Spoiler (blurred) messages\n- Reaction & edited message\n- View-once media\n- Status/story mention & reply\n- Newsletter / channel messages\n- Payment & payment invite\n- All WhatsApp Business types: product, catalog, order, invoice, business profile\n\n<details>\n<summary><b>Example: Album</b></summary>\n\n```javascript\nawait sock.sendMessage(jid, {\n    album: [\n        { image: { url: 'https://example.com/1.jpg' } },\n        { video: { url: 'https://example.com/2.mp4' } }\n    ],\n    caption: 'Album caption'\n})\n```\n</details>\n\n<details>\n<summary><b>Example: Poll</b></summary>\n\n```javascript\nawait sock.sendMessage(jid, {\n    poll: {\n        name: 'Poll Title',\n        values: ['Option A', 'Option B'],\n        selectableCount: 1\n    }\n})\n```\n</details>\n\n<details>\n<summary><b>Example: Spoiler</b></summary>\n\n```javascript\nawait sock.sendMessage(jid, {\n    text: 'Spoiler content',\n    spoiler: true\n})\n```\n</details>\n\n<details>\n<summary><b>Example: Event</b></summary>\n\n```javascript\nawait sock.sendMessage(jid, {\n    eventMessage: {\n        name: 'Meeting',\n        description: 'Weekly sync',\n        location: { degreesLatitude: -6.2, degreesLongitude: 106.8 },\n        startTime: Math.floor(Date.now() / 1000) + 3600\n    }\n})\n```\n</details>\n\n---\n\n## 🛠️ Additional Methods\n\n```javascript\n// Parse incoming extended/special messages\nsock.ev.on('messages.upsert', ({ messages }) => {\n    const extended = sock.parseExtendedMessageContent(messages[0].message)\n    if (extended) console.log(extended.type, extended.data)\n})\n\n// Business profile\nconst profile = await sock.getBusinessProfile(jid)\nawait sock.updateBusinessProfile({ description: 'Open 9-5', email: 'hi@example.com', category: 'Retail' })\n\n// Get newsletter/channel JID from URL\nawait sock.newsletterId('https://whatsapp.com/channel/...')\n\n// Refresh media URL for expired messages\nawait sock.updateMediaMessage(message)\n```\n\n---\n\n## 🌐 Community & Support\n\n<div align=\"center\">\n\n<table>\n<tr>\n<td align=\"center\">\n<a href=\"https://supunofc.site\">\n🌐<br/><b>Website</b><br/>supunofc.site\n</a>\n</td>\n<td align=\"center\">\n<a href=\"https://whatsapp.com/channel/0029Vb55cv41nozBTTIw1y07\">\n💬<br/><b>WhatsApp Channel</b><br/>Join here\n</a>\n</td>\n<td align=\"center\">\n<a href=\"https://www.youtube.com/@darkshadow_zap\">\n▶️<br/><b>YouTube</b><br/>@darkshadow_zap\n</a>\n</td>\n</tr>\n</table>\n\n**Developer:** Supun Fernando\n\n</div>\n\n---\n\n<div align=\"center\">\n\n### ⭐ If this project helped you, consider giving it a star!\n\nMade with ❤️ by **Supun Fernando**\n\n</div>\n\n---\n\n## 📄 License\n\nMIT","readmeFilename":"README.md","_rev":"1-e94f55ee4d694d00f37eeae415fde604"}