ishumdz-bail 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +807 -395
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,300 +1,179 @@
1
- <div align="center">
2
1
 
3
2
  ```
4
- ╔═══════════════════════════════════════════════════════════════════╗
5
- ║ ║
6
- ║ ██╗ ██╗██████╗ █████╗ ███████╗████████╗ ║
7
- ║ ██║ ██║██╔══██╗██╔══██╗██╔════╝╚══██╔══╝ ║
8
- ║ ███████║██████╔╝███████║███████╗ ██║ ║
9
- ║ ██╔══██║██╔══██╗██╔══██║╚════██║ ██║ ║
10
- ║ ██║ ██║██████╔╝██║ ██║███████║ ██║ ║
11
- ║ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ║
12
- ║ ║
13
- ║ ██████╗ ██╗ ██╗██╗███████╗ ║
14
- ║ ██╔══██╗██║ ██║██║╚══███╔╝ ║
15
- ║ ██║ ██║██║ ██║██║ ███╔╝ ║
16
- ║ ██║ ██║██║ ██║██║ ███╔╝ ║
17
- ║ ██████╔╝╚██████╔╝██║███████╗ ║
18
- ║ ╚═════╝ ╚═════╝ ╚═╝╚══════╝ ║
19
- ║ ║
20
- ║ WhatsApp Web API Fork for Bots ║
21
- ║ By Lovely ❤️ ║
22
- ║ ║
23
- ╚═══════════════════════════════════════════════════════════════════╝
24
- ```
25
-
26
- <img src="https://i.postimg.cc/9Q6q2Pv6/IMG-20260925-WA4965.jpg" alt="ishumdz-bail" width="700" />
3
+ ╔═══════════════════════════════════════════════════════════════════════════╗
4
+ ║ 📱 MAIN FEATURES ║
5
+ ╠═══════════════════════════════════════════════════════════════════════════╣
6
+ ║ ║
7
+ ║ ┌─────────────────────────────────────────────────────────────────────┐ ║
8
+ ║ │ 🎮 GAMES │ 📞 VOIP CALLER │ ⚡ PRO METHODS │ ║
9
+ ║ │ ├─ Blackjack │ ├─ Auto Answer │ ├─ sendPoll │ ║
10
+ ║ │ ├─ Slots │ ├─ Audio Playback │ ├─ sendPollVote │ ║
11
+ ║ │ ├─ Dice │ └─ VoipClient │ ├─ editMessage │ ║
12
+ ║ │ ├─ Coin Flip │ │ ├─ deleteMessage │ ║
13
+ ║ │ ├─ Roulette │ 📊 POLLS │ ├─ pinMessage │ ║
14
+ ║ │ ├─ Mines │ ├─ Create Poll │ ├─ starMessage │ ║
15
+ ║ │ ├─ Trivia │ ├─ Vote Poll │ ├─ reactMessage │ ║
16
+ ║ │ └─ RPS │ └─ Get Results │ ├─ sendPresence │ ║
17
+ ║ └─────────────────────────────────────────────────────────────────────┘ ║
18
+ ║ ║
19
+ ║ ┌─────────────────────────────────────────────────────────────────────┐ ║
20
+ ║ │ 📢 NEWSLETTER │ 🟢 STATUS │ 💬 CHAT │ ║
21
+ ║ │ ├─ channelVote │ ├─ sendText │ ├─ editMessage │ ║
22
+ ║ │ ├─ newsletterReact │ ├─ sendMedia │ ├─ deleteMessage │ ║
23
+ ║ │ ├─ getMessages │ ├─ readStatus │ ├─ pinMessage │ ║
24
+ ║ │ ├─ searchChannels │ └─ reactStatus │ ├─ unpinMessage │ ║
25
+ ║ │ └─ listChannels │ │ ├─ starMessage │ ║
26
+ ║ └─────────────────────────────────────────────────────────────────────┘ ║
27
+ ║ ║
28
+ ║ ┌─────────────────────────────────────────────────────────────────────┐ ║
29
+ ║ │ 👥 GROUPS │ 👤 PROFILE │ 📰 MEDIA │ ║
30
+ ║ │ ├─ Get Invite Info │ ├─ checkNumber │ ├─ Newsletter Paths │ ║
31
+ ║ │ ├─ Join via Invite │ ├─ setBio │ ├─ Image Upload │ ║
32
+ ║ │ ├─ Set Announcement │ ├─ updateName │ ├─ Video Upload │ ║
33
+ ║ │ ├─ Set Locked │ ├─ setProfilePic │ ├─ Audio Upload │ ║
34
+ ║ │ ├─ Request List │ ├─ removeProfilePic │ ├─ Document Upload │ ║
35
+ ║ │ ├─ Approve │ └─ rejectCall │ └─ Sticker Upload │ ║
36
+ ║ │ └─ Reject │ │ │ ║
37
+ ║ └─────────────────────────────────────────────────────────────────────┘ ║
38
+ ║ ║
39
+ ║ ✅ No Browser Required ✅ Multi-Device ✅ WebSocket Based ║
40
+ ║ ✅ Active Maintenance ✅ MIT License ✅ Full API Coverage ║
41
+ ║ ║
42
+ ╚═══════════════════════════════════════════════════════════════════════════╝
43
+ ```
44
+
45
+ <div align="center">
46
+ <img src="https://capsule-render.vercel.app/api?type=waving&height=220&color=0:ff6b6b,40:f06595,100:845ef7&text=ishumdz-bail&fontAlignY=40&fontSize=44&fontColor=ffffff&desc=Stable%20WhatsApp%20Web%20API%20Fork%20for%20Production%20Bots&descAlignY=60&descSize=16" alt="Header Banner" />
27
47
 
28
48
  <br/>
29
49
 
30
- [![npm](https://img.shields.io/badge/npm-ishumdz--bail-25D366?style=for-the-badge&logo=npm&logoColor=white)](https://www.npmjs.com/package/ishumdz-bail)
31
- [![GitHub](https://img.shields.io/badge/GitHub-lovelyofficial/ishumdz--bail-FF4500?style=for-the-badge&logo=github&logoColor=white)](https://github.com/lovelyofficial/ishumdz-bail)
32
- [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)](https://nodejs.org)
33
- [![License](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](LICENSE)
34
- [![WhatsApp](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://whatsapp.com)
50
+ <!-- Rounded + border image -->
51
+ <a href="https://ishanx-pro.site.je">
52
+ <kbd>
53
+ <img src="https://i.postimg.cc/9Q6q2Pv6/IMG-20260925-WA4965.jpg" alt="WhatsApp Baileys 2026" width="720" />
54
+ </kbd>
55
+ </a>
56
+
57
+ <br/><br/>
58
+
59
+
60
+ # 🧑‍💻 ishumdz-bail
61
+
62
+ <p>
63
+ <img src="https://img.shields.io/badge/Node.js-%3E%3D20-339933?style=for-the-badge&logo=nodedotjs&logoColor=white" />
64
+ <img src="https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white" />
65
+ <img src="https://img.shields.io/badge/WebSocket-010101?style=for-the-badge&logo=socketdotio&logoColor=white" />
66
+ <img src="https://img.shields.io/badge/Open%20Source-FF4500?style=for-the-badge&logo=github&logoColor=white" />
67
+ <img src="https://img.shields.io/badge/license-MIT-blue?style=for-the-badge" />
68
+ </p>
69
+
70
+ <p>
71
+ <img src="https://img.shields.io/npm/v/ishumdz-bail?style=flat-square&color=25D366&label=npm" />
72
+ <img src="https://img.shields.io/badge/maintained%20by-Lovely-black?style=flat-square" />
73
+ </p>
35
74
 
36
75
  **Open-source WhatsApp automation library — no browser required.**
37
76
  Built on WebSocket for speed, stability, and full multi-device support.
38
77
 
39
- </div>
78
+ <br/>
40
79
 
41
- ---
80
+ [Installation](#-getting-started) • [Features](#-main-features) • [Stability](#-stability--disconnect-handling) • [Website](https://ishanx-pro.site.je) • [WhatsApp Channel](https://shyracore.indevs.in)
42
81
 
43
- ## 📋 Table of Contents
44
-
45
- - [✨ What is ishumdz-bail?](#-what-is-ishumdz-bail)
46
- - [🚀 Installation](#-installation)
47
- - [⚡ Quick Start](#-quick-start)
48
- - [🎯 Features Overview](#-features-overview)
49
- - [🎮 Games](#-games)
50
- - [📞 VoIP Caller](#-voip-caller)
51
- - [⚡ Pro Methods](#-pro-methods)
52
- - [📊 Polls](#-polls)
53
- - [📢 Newsletter/Channels](#-newsletterchannels)
54
- - [🟢 Status/Stories](#-statusstories)
55
- - [💬 Chat Actions](#-chat-actions)
56
- - [👥 Group Management](#-group-management)
57
- - [👤 Profile Management](#-profile-management)
58
- - [📰 Newsletter Media](#-newsletter-media)
59
- - [🔌 API Reference](#-api-reference)
60
- - [📝 Examples](#-examples)
82
+ </div>
61
83
 
62
84
  ---
63
85
 
64
86
  ## ✨ What is ishumdz-bail?
65
87
 
66
- **ishumdz-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.
67
-
68
- **Why choose ishumdz-bail?**
88
+ **ishumdz-bail** (`ishumdz-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.
69
89
 
70
- ```
71
- ┌─────────────────────────────────────────────────────────────────┐
72
- │ ✅ No Browser Required │ ✅ Multi-Device Support │
73
- │ ✅ WebSocket Based │ ✅ Full API Coverage │
74
- │ ✅ Built-in Games (8) │ ✅ VoIP Call Answer │
75
- │ ✅ Pro Methods (34) │ ✅ Newsletter/Channel Support │
76
- │ ✅ Active Maintenance │ ✅ MIT Licensed │
77
- └─────────────────────────────────────────────────────────────────┘
78
- ```
90
+ > ⚡ **Node.js ≥ 20 required.**
79
91
 
80
92
  ---
81
93
 
82
- ## 🚀 Installation
94
+ ## 🚀 Getting Started
83
95
 
84
96
  ```bash
85
97
  npm install ishumdz-bail
86
98
  ```
87
99
 
88
- **Requirements:**
89
- - Node.js ≥ 20
90
- - npm or yarn
91
-
92
- ---
93
-
94
- ## ⚡ Quick Start
95
-
96
100
  ```javascript
97
- const { makeWASocket, useMultiFileAuthState, attachProMethods } = require('ishumdz-bail');
98
-
99
- const { state, saveCreds } = await useMultiFileAuthState('auth_info');
101
+ import { makeWASocket, useMultiFileAuthState } from 'ishumdz-bail'
100
102
 
103
+ const { state, saveCreds } = await useMultiFileAuthState('auth_info')
101
104
  const sock = makeWASocket({
102
105
  auth: state,
103
- syncFullHistory: false,
104
- aiLabel: true,
105
- autoAnswer: false,
106
- });
107
-
108
- sock.ev.on('creds.update', saveCreds);
109
-
110
- sock.ev.on('connection.update', ({ connection }) => {
111
- if (connection === 'open') {
112
- console.log('✅ Connected to WhatsApp!');
113
-
114
- // Attach Pro methods
115
- attachProMethods(sock);
116
- }
117
- });
118
- ```
106
+ syncFullHistory: false, // skip history sync — bot works immediately
107
+ aiLabel: true, // stamp messages with AI bot marker (default: true)
108
+ })
119
109
 
120
- ---
121
-
122
- ## 🎯 Features Overview
123
-
124
- ```
125
- ┌─────────────────────────────────────────────────────────────────────────┐
126
- │ ISHUMDZ-BAIL FEATURES │
127
- ├─────────────────────────────────────────────────────────────────────────┤
128
- │ │
129
- │ 🎮 GAMES (8) │ 📞 VOIP (3) │ ⚡ PRO METHODS (34) │
130
- │ ├─ Blackjack │ ├─ VoipClient │ ├─ sendPoll │
131
- │ ├─ Slots │ ├─ ActiveCall │ ├─ sendPollVote │
132
- │ ├─ Dice │ └─ AudioFeeder │ ├─ editMessage │
133
- │ ├─ Coin Flip │ │ ├─ deleteMessage │
134
- │ ├─ Roulette │ 📊 POLLS (3) │ ├─ pinMessage │
135
- │ ├─ Mines │ ├─ sendPoll │ ├─ reactMessage │
136
- │ ├─ Trivia │ ├─ sendPollVote │ ├─ sendStatusText │
137
- │ └─ Rock Paper │ └─ getAggregate │ ├─ checkNumber │
138
- │ Scissors │ Votes │ └─ ... and more! │
139
- │ │
140
- │ 📢 NEWSLETTER (6) │ 🟢 STATUS (4) │ 💬 CHAT (8) │
141
- │ ├─ channelVote │ ├─ sendStatusText │ ├─ editMessage │
142
- │ ├─ newsletterReact │ ├─ sendStatusMedia │ ├─ deleteMessage │
143
- │ ├─ newsletterGet │ ├─ readStatus │ ├─ pinMessage │
144
- │ │ Messages │ └─ reactStatus │ ├─ unpinMessage │
145
- │ ├─ newsletterSearch │ │ ├─ starMessage │
146
- │ └─ newsletterList │ 👥 GROUPS (7) │ ├─ sendPresence │
147
- │ │ ├─ groupGetInvite │ └─ reply │
148
- │ 👤 PROFILE (6) │ ├─ groupJoinVia │ │
149
- │ ├─ checkNumber │ │ Invite │ │
150
- │ ├─ setBio │ ├─ groupSet │ │
151
- │ ├─ updateProfileName │ │ Announcement │ │
152
- │ ├─ setProfilePicture │ ├─ groupSetLocked │ │
153
- │ ├─ removeProfile │ ├─ groupRequest │ │
154
- │ │ Picture │ │ Participants │ │
155
- │ └─ rejectCall │ ├─ groupApprove │ │
156
- │ │ │ Participants │ │
157
- │ │ └─ groupReject │ │
158
- │ │ Participants │ │
159
- │ │
160
- └─────────────────────────────────────────────────────────────────────────┘
110
+ sock.ev.on('creds.update', saveCreds)
161
111
  ```
162
112
 
163
113
  ---
164
114
 
165
- ## 🎮 Games
166
-
167
- 8 built-in games for your WhatsApp bot:
168
-
169
- ```javascript
170
- const { blackjack, slotMachine, diceGame, coinFlip, roulette, rps, trivia, createMines } = require('ishumdz-bail');
171
- ```
172
-
173
- ### 🃏 Blackjack
174
-
175
- ```javascript
176
- // Start a game
177
- const game = blackjack('start', [], [], 100);
178
- console.log(game.playerHand); // [{suit:'♠️',value:'A'}, {suit:'♥️',value:'K'}]
179
- console.log(game.dealerHand); // [{suit:'♦️',value:'5'}, {suit:'♣️',value:'?'}]
180
- console.log(game.status); // 'playing'
181
-
182
- // Hit (draw card)
183
- const hit = blackjack('hit', game.playerHand, game.dealerHand, 100);
184
-
185
- // Stand (end turn)
186
- const stand = blackjack('stand', game.playerHand, game.dealerHand, 100);
187
- console.log(stand.status); // 'win', 'lose', or 'push'
188
- ```
189
-
190
- ### 🎰 Slots
191
-
192
- ```javascript
193
- const slots = slotMachine(100);
194
- console.log(slots.reels); // ['🍒', '🍋', '🍊']
195
- console.log(slots.payout); // 0-500 (multiplier)
196
- ```
197
-
198
- ### 🎲 Dice
199
-
200
- ```javascript
201
- const dice = diceGame(100, 'high'); // 'high', 'low', or specific number
202
- console.log(dice.dice1); // 1-6
203
- console.log(dice.dice2); // 1-6
204
- console.log(dice.total); // 2-12
205
- console.log(dice.win); // true/false
206
- ```
207
-
208
- ### 🪙 Coin Flip
209
-
210
- ```javascript
211
- const flip = coinFlip(100, 'heads'); // 'heads' or 'tails'
212
- console.log(flip.result); // 'heads' or 'tails'
213
- console.log(flip.payout); // 0 or 200
214
- ```
215
-
216
- ### 🎡 Roulette
217
-
218
- ```javascript
219
- const spin = roulette(100, 'red'); // 'red', 'black', 'green', or number
220
- console.log(spin.number); // 0-36
221
- console.log(spin.color); // 'red', 'black', or 'green'
222
- console.log(spin.payout); // 0-3600
223
- ```
224
-
225
- ### ✊ Rock Paper Scissors
226
-
227
- ```javascript
228
- const game = rps('rock'); // 'rock', 'paper', or 'scissors'
229
- console.log(game.playerChoice); // 'rock'
230
- console.log(game.botChoice); // 'paper'
231
- console.log(game.result); // 'win', 'lose', or 'draw'
232
- ```
233
-
234
- ### 🧠 Trivia
235
-
236
- ```javascript
237
- const question = trivia(100);
238
- console.log(question.question); // 'What is the capital of France?'
239
- console.log(question.options); // ['A) Paris', 'B) London', ...]
240
- console.log(question.answer); // 'A'
241
- ```
242
-
243
- ### 💣 Mines
244
-
245
- ```javascript
246
- // Create a 5x5 grid with 5 mines
247
- const game = createMines(5, 5, 5);
248
- console.log(game.totalSafe); // 20
249
-
250
- // Reveal a tile
251
- const tile = revealTile(game, 0, 0);
252
- console.log(tile.safe); // true (diamond) or false (mine)
253
- console.log(tile.mine); // true or false
254
-
255
- // Cash out
256
- const cashout = cashoutMines(game, 100);
257
- console.log(cashout.payout); // based on revealed tiles
258
- ```
115
+ ## 🧩 Main Features
116
+
117
+ | Feature | Description |
118
+ |---|---|
119
+ | 💬 **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 |
120
+ | 🚫 **4-Factor Ban Checker** | Detect ban status via 4 independent signals: live registry, public send-page, identity-key probe, device-count signature |
121
+ | 🆔 **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 |
122
+ | 🏘️ **Communities Socket** | Full community management: create, link/unlink groups, manage participants, invite codes, ephemeral toggle, approval mode |
123
+ | 🔕 **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) |
124
+ | ⚙️ **Rust-powered Crypto** | `md5`, `hkdf`, LT-Hash anti-tampering offloaded to `whatsapp-rust-bridge` native module for raw speed |
125
+ | 🗂️ **LID Mapping Store** | Persistent LID ↔ phone-number bi-directional cache with LRU eviction and in-flight dedup — prevents duplicate USync lookups |
126
+ | 🔐 **Pre-Key Manager** | Concurrency-safe Signal pre-key operations via per-key-type PQueue — no race conditions on key updates/deletions |
127
+ | 🔄 **Classify Disconnect** | Maps every WA disconnect code to `{ category, shouldReconnect, backoffMs }` — properly handles code 515 (restartRequired) as recoverable, not fatal |
128
+ | ⏱️ **Rate Limiter** | Anti-spam pacing calculator: enforces per-minute/hour/day caps, burst allowance, new-chat delays, identical-message dedup |
129
+ | 🖼️ **Album Message** | Send multiple images/videos as a single WA album/grid, with per-item or top-level caption and `gifPlayback` support |
130
+ | 🤖 **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 |
131
+ | 🔎 **USync Username Protocol** | Username resolution baked into USync queries — resolve WA usernames alongside contacts in a single round-trip |
132
+ | 📥 **Offline Node Processor** | Batch-processes pending stanzas received while offline, preventing message loss on reconnect |
133
+ | 🔑 **Identity Change Handler** | Dedicated handler for Signal identity key changes — prevents session corruption when a contact re-registers |
134
+ | 📣 **Newsletter/Channel Media Upload** | Full support for uploading images, videos, audio, stickers to channels using correct `/newsletter/newsletter-*` paths |
135
+ | 😀 **Newsletter Reactions** | React to channel messages with emojis, track votes, and manage newsletter engagement |
136
+ | 📊 **Poll Voting** | Create polls, track encrypted votes, display results, and support multiple selection polls |
137
+ | 🎮 **Built-in Games** | 8 games: Blackjack, Slots, Dice, Coin Flip, Roulette, Mines, Trivia, Rock Paper Scissors |
138
+ | 📞 **VoIP Caller** | Answer incoming calls with audio playback using WASM VoIP engine |
139
+ | ⚡ **Pro Methods** | 34 convenience methods: Polls, Newsletter, Status, Chat, Groups, Profile |
259
140
 
260
141
  ---
261
142
 
262
- ## 📞 VoIP Caller
143
+ ## 📞 VoIP Caller (Call Answer + Audio)
263
144
 
264
- Answer incoming WhatsApp calls with audio playback:
145
+ Answer incoming WhatsApp calls and play audio automatically:
265
146
 
266
147
  ```javascript
267
- const { makeWASocket, enableCallAutoAnswer, getActiveVoipClient } = require('ishumdz-bail');
148
+ const { makeWASocket, enableCallAutoAnswer } = require('ishumdz-bail');
268
149
 
269
150
  const sock = makeWASocket({ auth: state });
270
151
 
271
- // Enable auto-answer
152
+ // Enable auto-answer with audio playback
272
153
  sock.enableCallAutoAnswer({
273
- audio: './welcome.wav', // Audio file (MP3/WAV)
274
- autoAnswer: true, // Auto-answer calls
275
- answerDelayMs: 200, // Delay before answer
276
- durationMs: 60000, // Max duration (60s)
277
- loop: true, // Loop audio
278
- onCall: (call) => {}, // Incoming call callback
279
- onAnswer: (call) => {}, // Answered callback
280
- onEnd: (call, reason) => {} // Ended callback
154
+ audio: './welcome.wav', // Audio file to play (MP3/WAV)
155
+ autoAnswer: true, // Auto-answer incoming calls
156
+ answerDelayMs: 200, // Delay before answering
157
+ durationMs: 60000, // Max call duration (60s)
158
+ loop: true, // Loop audio
159
+ onCall: (call) => {}, // Callback on incoming call
160
+ onAnswer: (call) => {}, // Callback when answered
161
+ onEnd: (call, reason) => {} // Callback when ended
281
162
  });
282
163
  ```
283
164
 
284
- ### Manual Call Handling
285
-
165
+ **Manual call handling:**
286
166
  ```javascript
287
167
  sock.ev.on('call', async ([call]) => {
288
168
  if (call.status === 'offer') {
289
- console.log(`📞 Incoming ${call.isVideo ? 'video' : 'voice'} call from ${call.from}`);
290
-
291
169
  // Reject call
292
170
  await sock.rejectCall(call.id, call.from);
293
171
 
294
172
  // Or accept with VoIP client
295
173
  const voipClient = getActiveVoipClient();
296
- if (voipClient?.activeCall) {
297
- voipClient.activeCall.accept('./audio.wav');
174
+ if (voipClient) {
175
+ const activeCall = voipClient.activeCall;
176
+ activeCall.accept('./audio.wav');
298
177
  }
299
178
  }
300
179
  });
@@ -304,7 +183,7 @@ sock.ev.on('call', async ([call]) => {
304
183
 
305
184
  ## ⚡ Pro Methods
306
185
 
307
- 34 convenience methods for easier development:
186
+ 34 convenience methods attached to socket via `attachProMethods()`:
308
187
 
309
188
  ```javascript
310
189
  const { makeWASocket, attachProMethods } = require('ishumdz-bail');
@@ -313,9 +192,7 @@ const sock = makeWASocket({ auth: state });
313
192
  attachProMethods(sock); // Attach all Pro methods
314
193
  ```
315
194
 
316
- ---
317
-
318
- ## 📊 Polls
195
+ ### 📊 Polls Pro
319
196
 
320
197
  ```javascript
321
198
  // Create a poll
@@ -332,12 +209,10 @@ await sock.sendPollVote(jid, pollMessage, ['Red']);
332
209
  const votes = sock.getAggregatePollVotes(pollMessage);
333
210
  ```
334
211
 
335
- ---
336
-
337
- ## 📢 Newsletter/Channels
212
+ ### 📢 Newsletter/Channel Pro
338
213
 
339
214
  ```javascript
340
- // Smart channel poll vote (auto-resolves links)
215
+ // Smart channel poll vote (auto-resolves links, IDs)
341
216
  await sock.channelVote('https://whatsapp.com/channel/xxx/123', 1);
342
217
 
343
218
  // React to channel post
@@ -353,9 +228,7 @@ const results = await sock.newsletterSearch('technology');
353
228
  const channels = await sock.newsletterList();
354
229
  ```
355
230
 
356
- ---
357
-
358
- ## 🟢 Status/Stories
231
+ ### 🟢 Status/Stories Pro
359
232
 
360
233
  ```javascript
361
234
  // Send text status
@@ -374,9 +247,7 @@ await sock.sendStatusMedia('./photo.jpg', {
374
247
  await sock.reactStatus(statusKey, '❤️');
375
248
  ```
376
249
 
377
- ---
378
-
379
- ## 💬 Chat Actions
250
+ ### 💬 Chat Pro
380
251
 
381
252
  ```javascript
382
253
  // Edit a message
@@ -385,11 +256,8 @@ await sock.editMessage(jid, messageKey, 'Updated text!');
385
256
  // Delete a message
386
257
  await sock.deleteMessage(jid, messageKey);
387
258
 
388
- // Pin a message (86400 = 24h, 604800 = 7d, 2592000 = 30d)
389
- await sock.pinMessage(jid, messageKey, 86400);
390
-
391
- // Unpin a message
392
- await sock.unpinMessage(jid, messageKey);
259
+ // Pin a message (24h, 7d, or 30d)
260
+ await sock.pinMessage(jid, messageKey, 86400); // 24 hours
393
261
 
394
262
  // Star/unstar a message
395
263
  await sock.starMessage(jid, messageKey, true);
@@ -404,9 +272,7 @@ await sock.sendPresence(jid, 'composing');
404
272
  await sock.reply(jid, 'This is a reply!', quotedMessage);
405
273
  ```
406
274
 
407
- ---
408
-
409
- ## 👥 Group Management
275
+ ### 👥 Groups Pro
410
276
 
411
277
  ```javascript
412
278
  // Get group info from invite link
@@ -427,9 +293,7 @@ await sock.groupApproveParticipants(groupJid, [participant1, participant2]);
427
293
  await sock.groupRejectParticipants(groupJid, [participant3]);
428
294
  ```
429
295
 
430
- ---
431
-
432
- ## 👤 Profile Management
296
+ ### 👤 Profile Pro
433
297
 
434
298
  ```javascript
435
299
  // Check if number exists on WhatsApp
@@ -451,174 +315,722 @@ await sock.removeProfilePicture(jid);
451
315
 
452
316
  ---
453
317
 
454
- ## 📰 Newsletter Media
318
+ ## 🎮 Built-in Games
455
319
 
456
- Upload media to channels with correct paths:
320
+ 8 fun games for your WhatsApp bot:
457
321
 
458
322
  ```javascript
459
- const { NEWSLETTER_MEDIA_PATH_MAP } = require('ishumdz-bail');
323
+ const { blackjack, slotMachine, diceGame, coinFlip, roulette, rps, trivia, createMines } = require('ishumdz-bail');
324
+
325
+ // Blackjack
326
+ const game = blackjack('start', [], [], 100); // Start with 100 bet
327
+ // game.playerHand, game.dealerHand, game.status
328
+
329
+ // Slots
330
+ const slots = slotMachine(100);
331
+ // slots.reels, slots.payout
332
+
333
+ // Dice
334
+ const dice = diceGame(100, 'high'); // Bet on high (7-12)
335
+ // dice.total, dice.dice1, dice.dice2
336
+
337
+ // Coin Flip
338
+ const flip = coinFlip(100, 'heads');
339
+ // flip.result, flip.payout
340
+
341
+ // Roulette
342
+ const spin = roulette(100, 'red');
343
+ // spin.number, spin.color, spin.payout
344
+
345
+ // Rock Paper Scissors
346
+ const game = rps('rock');
347
+ // game.playerChoice, game.botChoice, game.result
460
348
 
461
- console.log(NEWSLETTER_MEDIA_PATH_MAP);
349
+ // Trivia
350
+ const question = trivia(100);
351
+ // question.question, question.options, question.answer
352
+
353
+ // Mines
354
+ const mines = createMines(5, 5, 5); // 5x5 grid, 5 mines
355
+ const tile = revealTile(mines, 0, 0); // Reveal tile at (0,0)
356
+ // tile.safe, tile.mine
357
+ const cashout = cashoutMines(mines, 100); // Cash out
358
+ // cashout.payout
359
+ ```
360
+
361
+ ## 💬 Rich Response (GenAI Bubble)
362
+
363
+ Send messages that render as Meta AI-style bubbles inside WhatsApp. Supports multiple primitives in a single message:
364
+
365
+ ```javascript
366
+ // Markdown text
367
+ await sock.sendMessage(jid, {
368
+ richResponse: {
369
+ text: '**Hello** from *ishumdz-bail*',
370
+ responseId: 'optional-uuid'
371
+ }
372
+ })
373
+
374
+ // Code block
375
+ await sock.sendMessage(jid, {
376
+ richResponse: {
377
+ code: 'console.log("hello")',
378
+ language: 'javascript'
379
+ }
380
+ })
381
+
382
+ // Table
383
+ await sock.sendMessage(jid, {
384
+ richResponse: {
385
+ table: {
386
+ rows: [
387
+ ['Name', 'Age'],
388
+ ['Alice', '25'],
389
+ ['Bob', '30']
390
+ ]
391
+ }
392
+ }
393
+ })
394
+
395
+ // HTML (raw HTML rendered in client)
396
+ await sock.sendMessage(jid, {
397
+ richResponse: {
398
+ text: 'fallback',
399
+ html: '<b>bold</b> <a href="https://example.com">link</a>'
400
+ }
401
+ })
402
+
403
+ // LaTeX
404
+ await sock.sendMessage(jid, {
405
+ richResponse: {
406
+ latex: 'E = mc^2'
407
+ }
408
+ })
409
+
410
+ // Map / location
411
+ await sock.sendMessage(jid, {
412
+ richResponse: {
413
+ map: {
414
+ latitude: -6.2,
415
+ longitude: 106.8,
416
+ zoom: 15,
417
+ title: 'Jakarta',
418
+ annotations: []
419
+ }
420
+ }
421
+ })
422
+
423
+ // Inline image
424
+ await sock.sendMessage(jid, {
425
+ richResponse: {
426
+ imageUrl: 'https://example.com/photo.jpg'
427
+ }
428
+ })
429
+ ```
430
+
431
+ **Shortcut methods** (all accept `quoted` and `options`):
432
+
433
+ ```javascript
434
+ await sock.sendTable(jid, 'Title', ['H1','H2'], [['A','B']], quoted)
435
+ await sock.sendList(jid, 'Title', ['item1','item2'], quoted)
436
+ await sock.sendCodeBlock(jid, 'print("hello")', quoted, { language: 'python' })
437
+ await sock.sendLatex(jid, quoted, { latex: 'x^2 + y^2 = z^2' })
438
+ await sock.sendRichMessage(jid, submessages, quoted)
439
+ ```
440
+
441
+ ---
442
+
443
+ ## 🖼️ Album Message
444
+
445
+ Send multiple images/videos grouped into a single WA album:
446
+
447
+ ```javascript
448
+ await sock.sendMessage(jid, {
449
+ album: [
450
+ { image: { url: 'https://example.com/a.jpg' } },
451
+ { image: { url: 'https://example.com/b.jpg' }, caption: 'caption foto kedua' },
452
+ { video: { url: 'https://example.com/c.mp4' }, gifPlayback: false }
453
+ ],
454
+ caption: 'caption ini otomatis ke item pertama'
455
+ })
456
+ ```
457
+
458
+ ---
459
+
460
+ ## 🚫 Ban Checker
461
+
462
+ 4-factor ban detection against WhatsApp's own servers — no third-party API:
463
+
464
+ ```javascript
465
+ const result = await sock.checkBanStatus('628123456789')
466
+ // or: sock.checkBanStatus('628123456789@s.whatsapp.net')
467
+
468
+ console.log(result)
462
469
  // {
463
- // image: '/newsletter/newsletter-image',
464
- // video: '/newsletter/newsletter-video',
465
- // document: '/newsletter/newsletter-document',
466
- // audio: '/newsletter/newsletter-audio',
467
- // sticker: '/newsletter/newsletter-image',
468
- // gif: '/newsletter/newsletter-gif',
469
- // ptt: '/newsletter/newsletter-ptt',
470
- // ptv: '/newsletter/newsletter-ptv'
470
+ // status: 'ACTIVE' | 'PROFILE_HIDDEN' | 'LIKELY_ACTIVE' | 'BANNED' | 'OFF_WHATSAPP' | 'UNKNOWN',
471
+ // emoji: '🟢' | '🟡' | '🔴' | '❓',
472
+ // confidence: 0..1,
473
+ // deviceCount: number | null,
474
+ // registryExists: boolean | null,
475
+ // pageVisible: boolean | null,
476
+ // profileName: string | null
471
477
  // }
472
478
  ```
473
479
 
480
+ **Four factors checked:**
481
+ - **Factor A** — Live registry (`sock.onWhatsApp`)
482
+ - **Factor B** — Public send-page title/image probe (`api.whatsapp.com`)
483
+ - **Factor C** — Identity-key device probe via USync (strongest: banned numbers have their keys destroyed)
484
+ - **Factor D** — Device-count signature (2+ = ACTIVE, 1 generic = likely BANNED, 0 = BANNED/OFF_WA)
485
+
486
+ ---
487
+
488
+ ## 🆔 Username Socket (w:mex)
489
+
490
+ Full WA `@username` API via WhatsApp's internal Pando/MEX GraphQL protocol, query IDs sourced from Java decompile of WA 2.26.17.2:
491
+
492
+ ```javascript
493
+ // Check availability
494
+ const res = await sock.checkUsername('myusername')
495
+ // { available: true, username } or { available: false, suggestions: [...] }
496
+
497
+ // Set username
498
+ await sock.setUsername('myusername')
499
+
500
+ // Delete username
501
+ await sock.deleteUsername()
502
+
503
+ // Get your own username
504
+ const mine = await sock.getMyUsername()
505
+
506
+ // Pin/unpin username
507
+ await sock.setUsernamePin(true)
508
+
509
+ // Find user by username
510
+ const user = await sock.findUserByUsername('someuser', pin)
511
+
512
+ // Fetch usernames of your contacts in batch
513
+ const usernames = await sock.fetchContactUsernames('94xxxx@s.whatsapp.net', '628yyy@s.whatsapp.net')
514
+
515
+ // Get username suggestions
516
+ const suggestions = await sock.getUsernameRecommendations()
517
+ ```
518
+
474
519
  ---
475
520
 
476
- ## 🔌 API Reference
477
-
478
- ### Core Functions
479
-
480
- | Function | Description |
481
- |----------|-------------|
482
- | `makeWASocket(config)` | Create WhatsApp socket |
483
- | `useMultiFileAuthState(dir)` | Multi-file auth state |
484
- | `attachProMethods(sock)` | Attach Pro methods |
485
- | `enableCallAutoAnswer(sock, opts)` | Enable VoIP auto-answer |
486
- | `getActiveVoipClient()` | Get active VoIP client |
487
- | `delay(ms)` | Delay execution |
488
-
489
- ### Games
490
-
491
- | Function | Description |
492
- |----------|-------------|
493
- | `blackjack(action, player, dealer, bet)` | Play blackjack |
494
- | `slotMachine(bet)` | Play slots |
495
- | `diceGame(bet, prediction)` | Play dice |
496
- | `coinFlip(bet, choice)` | Flip coin |
497
- | `roulette(bet, choice)` | Play roulette |
498
- | `rps(choice)` | Rock Paper Scissors |
499
- | `trivia(bet)` | Play trivia |
500
- | `createMines(rows, cols, mines)` | Create mines game |
501
- | `revealTile(game, row, col)` | Reveal tile |
502
- | `cashoutMines(game, bet)` | Cash out |
503
-
504
- ### Pro Methods
505
-
506
- | Function | Description |
507
- |----------|-------------|
508
- | `sendPoll(jid, data)` | Create poll |
509
- | `sendPollVote(jid, key, options)` | Vote on poll |
510
- | `editMessage(jid, key, text)` | Edit message |
511
- | `deleteMessage(jid, key)` | Delete message |
512
- | `pinMessage(jid, key, duration)` | Pin message |
513
- | `unpinMessage(jid, key)` | Unpin message |
514
- | `starMessage(jid, key, star)` | Star message |
515
- | `reactMessage(jid, key, emoji)` | React to message |
516
- | `sendPresence(jid, presence)` | Send presence |
517
- | `reply(jid, text, quoted)` | Reply with quote |
518
- | `checkNumber(phone)` | Check WhatsApp number |
519
- | `setBio(text)` | Update bio |
520
- | `updateProfileName(name)` | Update name |
521
- | `setProfilePicture(jid, content)` | Set profile pic |
522
- | `removeProfilePicture(jid)` | Remove profile pic |
523
- | `sendStatusText(text, options)` | Send text status |
524
- | `sendStatusMedia(media, options)` | Send media status |
525
- | `readStatus(key)` | Mark status as read |
526
- | `reactStatus(key, emoji)` | React to status |
527
- | `channelVote(target, option)` | Smart channel vote |
528
- | `newsletterReact(jid, id, reaction)` | React to channel |
529
- | `newsletterGetMessages(jid, count)` | Get channel messages |
530
- | `newsletterSearch(query)` | Search channels |
531
- | `newsletterList()` | List followed channels |
532
- | `groupGetInviteInfo(code)` | Get group info |
533
- | `groupJoinViaInvite(code)` | Join via invite |
534
- | `groupSetAnnouncement(jid, bool)` | Admin-only messages |
535
- | `groupSetLocked(jid, bool)` | Admin-only edit |
536
- | `groupRequestParticipantsList(jid)` | Pending requests |
537
- | `groupApproveParticipants(jid, list)` | Approve requests |
538
- | `groupRejectParticipants(jid, list)` | Reject requests |
539
- | `rejectCall(callId, from)` | Reject call |
521
+ ## 🏘️ Communities Socket
522
+
523
+ ```javascript
524
+ // Create community
525
+ const community = await sock.communityCreate('Community Name', 'Description')
526
+
527
+ // Create group inside community
528
+ await sock.communityCreateGroup('Group Name', [jid1, jid2], communityJid)
529
+
530
+ // Link/unlink existing group
531
+ await sock.communityLinkGroup(groupJid, communityJid)
532
+ await sock.communityUnlinkGroup(groupJid, communityJid)
533
+
534
+ // Fetch linked groups
535
+ const groups = await sock.communityFetchLinkedGroups(communityJid)
536
+
537
+ // Manage participants
538
+ await sock.communityParticipantsUpdate(communityJid, [jid1], 'add') // 'add' | 'remove' | 'promote' | 'demote'
539
+
540
+ // Invite code
541
+ const code = await sock.communityInviteCode(communityJid)
542
+ await sock.communityRevokeInvite(communityJid)
543
+ await sock.communityAcceptInvite(code)
544
+
545
+ // Settings
546
+ await sock.communityToggleEphemeral(communityJid, 86400) // seconds
547
+ await sock.communityMemberAddMode(communityJid, 'admin_add')
548
+ await sock.communityJoinApprovalMode(communityJid, 'on')
549
+ await sock.communityUpdateSubject(communityJid, 'New Name')
550
+ await sock.communityUpdateDescription(communityJid, 'New Desc')
551
+ await sock.communityLeave(communityJid)
552
+ ```
540
553
 
541
554
  ---
542
555
 
543
- ## 📝 Examples
556
+ ## 🔕 noSelfSync
544
557
 
545
- ### Basic Bot
558
+ Skip syncing outgoing messages to your own linked devices. Useful for high-volume bots where sync traffic is unnecessary:
546
559
 
547
560
  ```javascript
548
- const { makeWASocket, useMultiFileAuthState, attachProMethods } = require('ishumdz-bail');
561
+ await sock.sendMessage(jid, { text: 'hello' }, { noSelfSync: true })
549
562
 
550
- async function startBot() {
551
- const { state, saveCreds } = await useMultiFileAuthState('auth');
552
-
553
- const sock = makeWASocket({
554
- auth: state,
555
- printQRInTerminal: true
556
- });
557
-
558
- attachProMethods(sock);
559
-
560
- sock.ev.on('creds.update', saveCreds);
561
-
562
- sock.ev.on('messages.upsert', async ({ messages }) => {
563
- const msg = messages[0];
564
- if (!msg.key.fromMe && msg.message?.conversation) {
565
- const text = msg.message.conversation.toLowerCase();
566
-
567
- if (text === '!ping') {
568
- await sock.reply(msg.key.remoteJid, 'Pong! 🏓', msg);
569
- }
570
-
571
- if (text === '!slots') {
572
- const slots = slotMachine(100);
573
- await sock.reply(msg.key.remoteJid,
574
- `🎰 Slots: ${slots.reels.join(' | ')}\nPayout: ${slots.payout}`, msg);
575
- }
563
+ // Also supported in all shortcut methods:
564
+ await sock.sendTable(jid, title, headers, rows, quoted, { noSelfSync: true })
565
+ await sock.sendCodeBlock(jid, code, quoted, { noSelfSync: true })
566
+ ```
567
+
568
+ > **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.
569
+
570
+ ---
571
+
572
+ ## 🔄 Stability & Disconnect Handling
573
+
574
+ ishumdz-bail ships `classifyDisconnect()` — maps every WA status code into an actionable result:
575
+
576
+ ```javascript
577
+ import { classifyDisconnect } from 'ishumdz-bail'
578
+
579
+ sock.ev.on('connection.update', ({ connection, lastDisconnect }) => {
580
+ if (connection === 'close') {
581
+ const code = lastDisconnect?.error?.output?.statusCode
582
+ const info = classifyDisconnect(code)
583
+
584
+ console.log(info)
585
+ // {
586
+ // category: 'fatal' | 'recoverable' | 'rate-limited' | 'unknown',
587
+ // shouldReconnect: boolean,
588
+ // backoffMs: number, // ms to wait before reconnecting
589
+ // message: string,
590
+ // code: number
591
+ // }
592
+
593
+ if (info.shouldReconnect) {
594
+ setTimeout(() => reconnect(), info.backoffMs)
576
595
  }
577
- });
596
+ }
597
+ })
598
+ ```
599
+
600
+ **Code map:**
601
+
602
+ | Code | Category | Reconnect | Backoff |
603
+ |---|---|---|---|
604
+ | 401, 440 | fatal | ❌ | — |
605
+ | 515 | recoverable | ✅ | 0 ms (immediate) |
606
+ | 405 | fatal | ❌ | — |
607
+ | 408 | recoverable | ✅ | 30 s |
608
+ | 503 | recoverable | ✅ | 5 min |
609
+ | 429 | rate-limited | ✅ | 60 s |
610
+ | 500 | recoverable | ✅ | 5 s |
611
+ | 503 | recoverable | ✅ | 10 s |
612
+ | Graceful close | recoverable | ✅ | 2 s |
613
+ | Unknown | unknown | ✅ | 15 s |
614
+
615
+ > **Important:** Code 515 (`restartRequired`) is WhatsApp's normal post-pairing signal. ishumdz-bail correctly treats it as recoverable with 0 ms backoff — other forks incorrectly mark it as fatal, causing bots to stop after first pair.
616
+
617
+ ---
618
+
619
+ ## ⏱️ Rate Limiter
620
+
621
+ Anti-ban pacing calculator — wire into your send path before each `sendMessage`:
622
+
623
+ ```javascript
624
+ import { RateLimiter } from 'ishumdz-bail'
625
+
626
+ const limiter = new RateLimiter({
627
+ maxPerMinute: 8,
628
+ maxPerHour: 200,
629
+ maxPerDay: 1500,
630
+ minDelayMs: 1500,
631
+ maxDelayMs: 5000,
632
+ newChatDelayMs: 3000,
633
+ maxIdenticalMessages: 3,
634
+ burstAllowance: 3
635
+ })
636
+
637
+ async function safeSend(jid, content) {
638
+ const delay = await limiter.getDelay(jid, content)
639
+ if (delay === -1) throw new Error('Rate limit exceeded — blocked')
640
+ if (delay > 0) await new Promise(r => setTimeout(r, delay))
641
+ await sock.sendMessage(jid, content)
642
+ limiter.record(jid, content)
578
643
  }
644
+ ```
645
+
646
+ ---
647
+
648
+ ## 📦 Supported Message Types
649
+
650
+ Every WhatsApp message type is covered:
651
+
652
+ - Text, image, video, audio, document, sticker, GIF/video note (PTV)
653
+ - Location & live location
654
+ - Contact / vCard
655
+ - Poll (create, vote, add option, poll result)
656
+ - Button, list, template, interactive (native flow)
657
+ - Album (multiple media in one message)
658
+ - Event & event invite
659
+ - Group invite, group status, group mention
660
+ - Spoiler (blurred) messages
661
+ - Reaction & edited message
662
+ - View-once media
663
+ - Status/story mention & reply
664
+ - Newsletter / channel messages
665
+ - Payment & payment invite
666
+ - All WhatsApp Business types: product, catalog, order, invoice, business profile
667
+
668
+ <details>
669
+ <summary><b>Example: Album</b></summary>
670
+
671
+ ```javascript
672
+ await sock.sendMessage(jid, {
673
+ album: [
674
+ { image: { url: 'https://example.com/1.jpg' } },
675
+ { video: { url: 'https://example.com/2.mp4' } }
676
+ ],
677
+ caption: 'Album caption'
678
+ })
679
+ ```
680
+ </details>
681
+
682
+ <details>
683
+ <summary><b>Example: Poll</b></summary>
684
+
685
+ ```javascript
686
+ await sock.sendMessage(jid, {
687
+ poll: {
688
+ name: 'Poll Title',
689
+ values: ['Option A', 'Option B'],
690
+ selectableCount: 1
691
+ }
692
+ })
693
+ ```
694
+ </details>
695
+
696
+ <details>
697
+ <summary><b>Example: Spoiler</b></summary>
698
+
699
+ ```javascript
700
+ await sock.sendMessage(jid, {
701
+ text: 'Spoiler content',
702
+ spoiler: true
703
+ })
704
+ ```
705
+ </details>
706
+
707
+ <details>
708
+ <summary><b>Example: Event</b></summary>
709
+
710
+ ```javascript
711
+ await sock.sendMessage(jid, {
712
+ eventMessage: {
713
+ name: 'Meeting',
714
+ description: 'Weekly sync',
715
+ location: { degreesLatitude: -6.2, degreesLongitude: 106.8 },
716
+ startTime: Math.floor(Date.now() / 1000) + 3600
717
+ }
718
+ })
719
+ ```
720
+ </details>
721
+
722
+ ---
723
+
724
+ ## 🛠️ Additional Methods
725
+
726
+ ```javascript
727
+ // Parse incoming extended/special messages
728
+ sock.ev.on('messages.upsert', ({ messages }) => {
729
+ const extended = sock.parseExtendedMessageContent(messages[0].message)
730
+ if (extended) console.log(extended.type, extended.data)
731
+ })
732
+
733
+ // Business profile
734
+ const profile = await sock.getBusinessProfile(jid)
735
+ await sock.updateBusinessProfile({ description: 'Open 9-5', email: 'hi@example.com', category: 'Retail' })
736
+
737
+ // Get newsletter/channel JID from URL
738
+ await sock.newsletterId('https://whatsapp.com/channel/...')
739
+
740
+ // Refresh media URL for expired messages
741
+ await sock.updateMediaMessage(message)
742
+ ```
743
+
744
+ ---
745
+
746
+ ## 🎮 Games
747
+
748
+ Built-in games for your WhatsApp bot! Import from `ishumdz-bail`:
749
+
750
+ ```javascript
751
+ import {
752
+ blackjack, slotMachine, diceGame,
753
+ coinFlip, roulette, rps, trivia,
754
+ createMines, revealTile, cashoutMines
755
+ } from 'ishumdz-bail'
756
+ ```
757
+
758
+ ### 🃏 Blackjack
759
+
760
+ ```javascript
761
+ // Start game
762
+ const game = blackjack('start', [], [], 1000)
763
+ await sock.sendMessage(jid, { text: game.message })
764
+
765
+ // Hit (after start)
766
+ const hit = blackjack('hit', game.playerHand, game.dealerHand, 1000)
767
+
768
+ // Stand
769
+ const stand = blackjack('stand', game)
770
+
771
+ // Double
772
+ const dbl = blackjack('double', game)
773
+ ```
774
+
775
+ ### 🎰 Slot Machine
776
+
777
+ ```javascript
778
+ const slot = slotMachine(100)
779
+ await sock.sendMessage(jid, { text: slot.message })
780
+ // 🎰 [🍒] [🍋] [💎] - NO MATCH
781
+ ```
782
+
783
+ ### 🎲 Dice
784
+
785
+ ```javascript
786
+ const dice = diceGame(100, 'high') // high, low, or seven
787
+ await sock.sendMessage(jid, { text: dice.message })
788
+ ```
789
+
790
+ ### 🪙 Coin Flip
791
+
792
+ ```javascript
793
+ const coin = coinFlip(100, 'heads') // heads or tails
794
+ await sock.sendMessage(jid, { text: coin.message })
795
+ ```
796
+
797
+ ### 🎰 Roulette
579
798
 
580
- startBot();
799
+ ```javascript
800
+ const rou = roulette(100, 'red') // red, black, odd, even, low, high
801
+ await sock.sendMessage(jid, { text: rou.message })
581
802
  ```
582
803
 
583
- ### Call Auto-Answer Bot
804
+ ### ✊ Rock Paper Scissors
584
805
 
585
806
  ```javascript
586
- const { makeWASocket, useMultiFileAuthState, enableCallAutoAnswer } = require('ishumdz-bail');
807
+ const r = rps('rock') // rock, paper, scissors
808
+ await sock.sendMessage(jid, { text: r.message })
809
+ ```
810
+
811
+ ### 💣 Mines
812
+
813
+ ```javascript
814
+ // Create game
815
+ const game = createMines(5, 5, 5) // rows, cols, mines
816
+
817
+ // Reveal tile
818
+ const result = revealTile(game, 0, 0) // row, col
819
+ await sock.sendMessage(jid, { text: result.message })
587
820
 
588
- async function startCallBot() {
589
- const { state, saveCreds } = await useMultiFileAuthState('auth');
821
+ // Cashout
822
+ const cashout = cashoutMines(game, 100)
823
+ await sock.sendMessage(jid, { text: cashout.message })
824
+ ```
825
+
826
+ ### 🧠 Trivia
827
+
828
+ ```javascript
829
+ const quiz = trivia(100)
830
+ await sock.sendMessage(jid, { text: quiz.message })
831
+
832
+ // Check answer (A, B, C, or D)
833
+ const answer = checkTriviaAnswer('B', quiz.answer, 100)
834
+ await sock.sendMessage(jid, { text: answer.message })
835
+ ```
836
+
837
+ ### 📱 Bot Command Example
838
+
839
+ ```javascript
840
+ sock.ev.on('messages.upsert', async ({ messages }) => {
841
+ const msg = messages[0]
842
+ const text = msg.message?.conversation || ''
590
843
 
591
- const sock = makeWASocket({ auth: state });
844
+ if (text === '.rps rock' || text === '.rps paper' || text === '.rps scissors') {
845
+ const choice = text.split(' ')[1]
846
+ const result = rps(choice)
847
+ await sock.sendMessage(msg.key.remoteJid, { text: result.message })
848
+ }
592
849
 
593
- sock.ev.on('creds.update', saveCreds);
850
+ if (text.startsWith('.slot')) {
851
+ const bet = parseInt(text.split(' ')[1]) || 100
852
+ const result = slotMachine(bet)
853
+ await sock.sendMessage(msg.key.remoteJid, { text: result.message })
854
+ }
594
855
 
595
- sock.ev.on('connection.update', ({ connection }) => {
596
- if (connection === 'open') {
597
- sock.enableCallAutoAnswer({
598
- audio: './welcome.wav',
599
- autoAnswer: true
600
- });
601
- console.log('📞 Call bot ready!');
856
+ if (text.startsWith('.coinflip')) {
857
+ const choice = text.split(' ')[1] || 'heads'
858
+ const bet = parseInt(text.split(' ')[2]) || 100
859
+ const result = coinFlip(bet, choice)
860
+ await sock.sendMessage(msg.key.remoteJid, { text: result.message })
861
+ }
862
+ })
863
+ ```
864
+
865
+ ---
866
+
867
+ ## 📊 Poll Voting
868
+
869
+ Create polls, track votes, and display results.
870
+
871
+ ### 🗳️ Create Poll
872
+
873
+ ```javascript
874
+ await sock.sendMessage(jid, {
875
+ poll: {
876
+ name: 'Best programming language?',
877
+ values: ['JavaScript', 'Python', 'Java', 'Go', 'Rust'],
878
+ selectableCount: 1
879
+ }
880
+ })
881
+ ```
882
+
883
+ ### 📊 Poll with Multiple Selections
884
+
885
+ ```javascript
886
+ await sock.sendMessage(jid, {
887
+ poll: {
888
+ name: 'Which features do you want?',
889
+ values: ['Games', 'AI', 'Stickers', 'Download'],
890
+ selectableCount: 3 // Users can select up to 3 options
891
+ }
892
+ })
893
+ ```
894
+
895
+ ### 📢 Announcement Group Poll (Admin Only Voting)
896
+
897
+ ```javascript
898
+ await sock.sendMessage(groupJid, {
899
+ poll: {
900
+ name: 'Admin Poll',
901
+ values: ['Option 1', 'Option 2'],
902
+ selectableCount: 1,
903
+ toAnnouncementGroup: true
904
+ }
905
+ })
906
+ ```
907
+
908
+ ### 🏆 Poll Result (Fake Results)
909
+
910
+ ```javascript
911
+ await sock.sendMessage(jid, {
912
+ pollResult: {
913
+ name: 'Best framework?',
914
+ votes: [['React', 150], ['Vue', 120], ['Angular', 80]]
915
+ }
916
+ })
917
+ ```
918
+
919
+ ### 📈 Track Poll Votes
920
+
921
+ ```javascript
922
+ import { getAggregateVotesInPollMessage } from 'ishumdz-bail'
923
+
924
+ // Store messages
925
+ const messageStore = new Map()
926
+
927
+ sock.ev.on('messages.upsert', async ({ messages }) => {
928
+ for (const msg of messages) {
929
+ const id = msg.key.remoteJid + ':' + msg.key.id
930
+ messageStore.set(id, msg)
931
+ }
932
+ })
933
+
934
+ // Listen for poll votes
935
+ sock.ev.on('messages.update', async (events) => {
936
+ for (const { key, update } of events) {
937
+ if (update.pollUpdates) {
938
+ const id = key.remoteJid + ':' + key.id
939
+ const pollCreation = messageStore.get(id)
940
+
941
+ if (pollCreation) {
942
+ const votes = getAggregateVotesInPollMessage({
943
+ message: pollCreation,
944
+ pollUpdates: update.pollUpdates
945
+ })
946
+
947
+ console.log('Poll votes:', votes)
948
+ // [{ name: 'Option 1', voters: ['123@s.whatsapp.net'] }, ...]
949
+ }
602
950
  }
603
- });
604
- }
951
+ }
952
+ })
953
+ ```
954
+
955
+ ### 📱 Poll Bot Command Example
605
956
 
606
- startCallBot();
957
+ ```javascript
958
+ sock.ev.on('messages.upsert', async ({ messages }) => {
959
+ const msg = messages[0]
960
+ const text = msg.message?.conversation || ''
961
+
962
+ // .poll Question | Option1 | Option2 | Option3
963
+ if (text.startsWith('.poll')) {
964
+ const args = text.slice(5).split('|').map(s => s.trim())
965
+ const question = args[0]
966
+ const options = args.slice(1)
967
+
968
+ if (question && options.length >= 2) {
969
+ await sock.sendMessage(msg.key.remoteJid, {
970
+ poll: {
971
+ name: question,
972
+ values: options,
973
+ selectableCount: 1
974
+ }
975
+ })
976
+ }
977
+ }
978
+
979
+ // .pollresult React | 150 | Vue | 120
980
+ if (text.startsWith('.pollresult')) {
981
+ const args = text.slice(12).split('|').map(s => s.trim())
982
+ const votes = []
983
+ for (let i = 0; i < args.length; i += 2) {
984
+ votes.push([args[i], parseInt(args[i + 1]) || 0])
985
+ }
986
+
987
+ await sock.sendMessage(msg.key.remoteJid, {
988
+ pollResult: {
989
+ name: 'Poll Results',
990
+ votes
991
+ }
992
+ })
993
+ }
994
+ })
607
995
  ```
608
996
 
609
997
  ---
610
998
 
611
- ## 📄 License
999
+ ## 🌐 Community & Support
1000
+
1001
+ <div align="center">
612
1002
 
613
- MIT License - See [LICENSE](LICENSE) for details.
1003
+ <table>
1004
+ <tr>
1005
+ <td align="center">
1006
+ <a href="https://ishanx-pro.site.je">
1007
+ 🌐<br/><b>Website</b><br/>ishanx-pro.site.je
1008
+ </a>
1009
+ </td>
1010
+ <td align="center">
1011
+ <a href="https://shyracore.indevs.in">
1012
+ 💬<br/><b>WhatsApp Channel</b><br/>shyracore.indevs.in
1013
+ </a>
1014
+ </td>
1015
+ </tr>
1016
+ </table>
1017
+
1018
+ **Developer:** Lovely
1019
+
1020
+ </div>
614
1021
 
615
1022
  ---
616
1023
 
617
1024
  <div align="center">
618
1025
 
619
- **Made with ❤️ by Lovely**
1026
+ ### ⭐ If this project helped you, consider giving it a star!
620
1027
 
621
- [![npm](https://img.shields.io/badge/npm-ishumdz--bail-25D366?style=for-the-badge&logo=npm&logoColor=white)](https://www.npmjs.com/package/ishumdz-bail)
622
- [![GitHub](https://img.shields.io/badge/GitHub-lovelyofficial-FF4500?style=for-the-badge&logo=github&logoColor=white)](https://github.com/lovelyofficial/ishumdz-bail)
1028
+ Made with ❤️ by **Lovely**
623
1029
 
624
1030
  </div>
1031
+
1032
+ ---
1033
+
1034
+ ## 📄 License
1035
+
1036
+ MIT