ishumdz-bail 1.0.10 → 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 +875 -217
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,4 +1,3 @@
1
- <div align="center">
2
1
 
3
2
  ```
4
3
  ╔═══════════════════════════════════════════════════════════════════════════╗
@@ -43,336 +42,995 @@
43
42
  ╚═══════════════════════════════════════════════════════════════════════════╝
44
43
  ```
45
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" />
47
+
46
48
  <br/>
47
49
 
48
- ```
49
- ██╗ ██╗██████╗ █████╗ ███████╗████████╗
50
- ██║ ██║██╔══██╗██╔══██╗██╔════╝╚══██╔══╝
51
- ███████║██████╔╝███████║███████╗ ██║
52
- ██╔══██║██╔══██╗██╔══██║╚════██║ ██║
53
- ██║ ██║██████╔╝██║ ██║███████║ ██║
54
- ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝
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>
55
56
 
56
- WhatsApp Web API Fork
57
- By Lovely ❤️
58
- ```
57
+ <br/><br/>
59
58
 
60
- <img src="https://i.postimg.cc/9Q6q2Pv6/IMG-20260925-WA4965.jpg" alt="ishumdz-bail" width="700" />
61
59
 
62
- <br/>
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>
63
69
 
64
- [![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)
65
- [![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)
66
- [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)](https://nodejs.org)
67
- [![License](https://img.shields.io/badge/License-MIT-blue?style=for-the-badge)](LICENSE)
68
- [![WhatsApp](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://whatsapp.com)
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>
69
74
 
70
75
  **Open-source WhatsApp automation library — no browser required.**
71
76
  Built on WebSocket for speed, stability, and full multi-device support.
72
77
 
78
+ <br/>
79
+
80
+ [Installation](#-getting-started) • [Features](#-main-features) • [Stability](#-stability--disconnect-handling) • [Website](https://ishanx-pro.site.je) • [WhatsApp Channel](https://shyracore.indevs.in)
81
+
73
82
  </div>
74
83
 
75
84
  ---
76
85
 
77
- ## 🚀 Installation
86
+ ## ✨ What is ishumdz-bail?
87
+
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.
89
+
90
+ > ⚡ **Node.js ≥ 20 required.**
91
+
92
+ ---
93
+
94
+ ## 🚀 Getting Started
78
95
 
79
96
  ```bash
80
97
  npm install ishumdz-bail
81
98
  ```
82
99
 
100
+ ```javascript
101
+ import { makeWASocket, useMultiFileAuthState } from 'ishumdz-bail'
102
+
103
+ const { state, saveCreds } = await useMultiFileAuthState('auth_info')
104
+ const sock = makeWASocket({
105
+ auth: state,
106
+ syncFullHistory: false, // skip history sync — bot works immediately
107
+ aiLabel: true, // stamp messages with AI bot marker (default: true)
108
+ })
109
+
110
+ sock.ev.on('creds.update', saveCreds)
111
+ ```
112
+
83
113
  ---
84
114
 
85
- ## ⚡ Quick Start
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 |
140
+
141
+ ---
142
+
143
+ ## 📞 VoIP Caller (Call Answer + Audio)
144
+
145
+ Answer incoming WhatsApp calls and play audio automatically:
86
146
 
87
147
  ```javascript
88
- const { makeWASocket, useMultiFileAuthState, attachProMethods } = require('ishumdz-bail');
148
+ const { makeWASocket, enableCallAutoAnswer } = require('ishumdz-bail');
149
+
150
+ const sock = makeWASocket({ auth: state });
89
151
 
90
- const { state, saveCreds } = await useMultiFileAuthState('auth_info');
152
+ // Enable auto-answer with audio playback
153
+ sock.enableCallAutoAnswer({
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
162
+ });
163
+ ```
91
164
 
92
- const sock = makeWASocket({
93
- auth: state,
94
- syncFullHistory: false,
95
- aiLabel: true,
165
+ **Manual call handling:**
166
+ ```javascript
167
+ sock.ev.on('call', async ([call]) => {
168
+ if (call.status === 'offer') {
169
+ // Reject call
170
+ await sock.rejectCall(call.id, call.from);
171
+
172
+ // Or accept with VoIP client
173
+ const voipClient = getActiveVoipClient();
174
+ if (voipClient) {
175
+ const activeCall = voipClient.activeCall;
176
+ activeCall.accept('./audio.wav');
177
+ }
178
+ }
96
179
  });
180
+ ```
97
181
 
98
- attachProMethods(sock);
182
+ ---
99
183
 
100
- sock.ev.on('creds.update', saveCreds);
184
+ ## ⚡ Pro Methods
101
185
 
102
- sock.ev.on('connection.update', ({ connection }) => {
103
- if (connection === 'open') {
104
- console.log('✅ Connected!');
105
- }
186
+ 34 convenience methods attached to socket via `attachProMethods()`:
187
+
188
+ ```javascript
189
+ const { makeWASocket, attachProMethods } = require('ishumdz-bail');
190
+
191
+ const sock = makeWASocket({ auth: state });
192
+ attachProMethods(sock); // Attach all Pro methods
193
+ ```
194
+
195
+ ### 📊 Polls Pro
196
+
197
+ ```javascript
198
+ // Create a poll
199
+ await sock.sendPoll(jid, {
200
+ name: 'What is your favorite color?',
201
+ values: ['Red', 'Blue', 'Green', 'Yellow'],
202
+ selectableCount: 1
203
+ });
204
+
205
+ // Vote on a poll
206
+ await sock.sendPollVote(jid, pollMessage, ['Red']);
207
+
208
+ // Get poll results
209
+ const votes = sock.getAggregatePollVotes(pollMessage);
210
+ ```
211
+
212
+ ### 📢 Newsletter/Channel Pro
213
+
214
+ ```javascript
215
+ // Smart channel poll vote (auto-resolves links, IDs)
216
+ await sock.channelVote('https://whatsapp.com/channel/xxx/123', 1);
217
+
218
+ // React to channel post
219
+ await sock.newsletterReact(channelJid, serverId, '👍');
220
+
221
+ // Get channel messages (decoded)
222
+ const messages = await sock.newsletterGetMessages(channelJid, 50);
223
+
224
+ // Search channels
225
+ const results = await sock.newsletterSearch('technology');
226
+
227
+ // List followed channels
228
+ const channels = await sock.newsletterList();
229
+ ```
230
+
231
+ ### 🟢 Status/Stories Pro
232
+
233
+ ```javascript
234
+ // Send text status
235
+ await sock.sendStatusText('Hello World!', {
236
+ backgroundColor: '#25D366',
237
+ font: 1
106
238
  });
239
+
240
+ // Send media status
241
+ await sock.sendStatusMedia('./photo.jpg', {
242
+ type: 'image',
243
+ caption: 'My status!'
244
+ });
245
+
246
+ // React to status
247
+ await sock.reactStatus(statusKey, '❤️');
248
+ ```
249
+
250
+ ### 💬 Chat Pro
251
+
252
+ ```javascript
253
+ // Edit a message
254
+ await sock.editMessage(jid, messageKey, 'Updated text!');
255
+
256
+ // Delete a message
257
+ await sock.deleteMessage(jid, messageKey);
258
+
259
+ // Pin a message (24h, 7d, or 30d)
260
+ await sock.pinMessage(jid, messageKey, 86400); // 24 hours
261
+
262
+ // Star/unstar a message
263
+ await sock.starMessage(jid, messageKey, true);
264
+
265
+ // React to a message
266
+ await sock.reactMessage(jid, messageKey, '😂');
267
+
268
+ // Send presence (typing indicator)
269
+ await sock.sendPresence(jid, 'composing');
270
+
271
+ // Quick reply with quote
272
+ await sock.reply(jid, 'This is a reply!', quotedMessage);
273
+ ```
274
+
275
+ ### 👥 Groups Pro
276
+
277
+ ```javascript
278
+ // Get group info from invite link
279
+ const info = await sock.groupGetInviteInfo('https://chat.whatsapp.com/xxx');
280
+
281
+ // Join group via invite
282
+ await sock.groupJoinViaInvite('https://chat.whatsapp.com/xxx');
283
+
284
+ // Set announcement mode (admin only)
285
+ await sock.groupSetAnnouncement(groupJid, true);
286
+
287
+ // Set locked mode (admin only)
288
+ await sock.groupSetLocked(groupJid, true);
289
+
290
+ // Manage join requests
291
+ const requests = await sock.groupRequestParticipantsList(groupJid);
292
+ await sock.groupApproveParticipants(groupJid, [participant1, participant2]);
293
+ await sock.groupRejectParticipants(groupJid, [participant3]);
294
+ ```
295
+
296
+ ### 👤 Profile Pro
297
+
298
+ ```javascript
299
+ // Check if number exists on WhatsApp
300
+ const result = await sock.checkNumber('1234567890');
301
+ console.log(result.exists); // true/false
302
+
303
+ // Update bio
304
+ await sock.setBio('Hello, I am a bot!');
305
+
306
+ // Update display name
307
+ await sock.updateProfileName('My Bot');
308
+
309
+ // Set profile picture
310
+ await sock.setProfilePicture(jid, './avatar.jpg');
311
+
312
+ // Remove profile picture
313
+ await sock.removeProfilePicture(jid);
107
314
  ```
108
315
 
109
316
  ---
110
317
 
111
- ## 🎮 Games
318
+ ## 🎮 Built-in Games
319
+
320
+ 8 fun games for your WhatsApp bot:
112
321
 
113
322
  ```javascript
114
323
  const { blackjack, slotMachine, diceGame, coinFlip, roulette, rps, trivia, createMines } = require('ishumdz-bail');
115
324
 
116
- // 🃏 Blackjack
117
- const bj = blackjack('start', [], [], 100);
118
- // bj.playerHand, bj.dealerHand, bj.status
325
+ // Blackjack
326
+ const game = blackjack('start', [], [], 100); // Start with 100 bet
327
+ // game.playerHand, game.dealerHand, game.status
119
328
 
120
- // 🎰 Slots
329
+ // Slots
121
330
  const slots = slotMachine(100);
122
331
  // slots.reels, slots.payout
123
332
 
124
- // 🎲 Dice
125
- const dice = diceGame(100, 'high');
333
+ // Dice
334
+ const dice = diceGame(100, 'high'); // Bet on high (7-12)
126
335
  // dice.total, dice.dice1, dice.dice2
127
336
 
128
- // 🪙 Coin Flip
337
+ // Coin Flip
129
338
  const flip = coinFlip(100, 'heads');
130
339
  // flip.result, flip.payout
131
340
 
132
- // 🎡 Roulette
341
+ // Roulette
133
342
  const spin = roulette(100, 'red');
134
- // spin.number, spin.color
343
+ // spin.number, spin.color, spin.payout
135
344
 
136
- // ✊ Rock Paper Scissors
345
+ // Rock Paper Scissors
137
346
  const game = rps('rock');
138
347
  // game.playerChoice, game.botChoice, game.result
139
348
 
140
- // 🧠 Trivia
141
- const q = trivia(100);
142
- // q.question, q.options, q.answer
349
+ // Trivia
350
+ const question = trivia(100);
351
+ // question.question, question.options, question.answer
143
352
 
144
- // 💣 Mines
145
- const mines = createMines(5, 5, 5);
146
- const tile = revealTile(mines, 0, 0);
147
- const cashout = cashoutMines(mines, 100);
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
148
359
  ```
149
360
 
150
- ---
361
+ ## 💬 Rich Response (GenAI Bubble)
151
362
 
152
- ## 📞 VoIP Caller
363
+ Send messages that render as Meta AI-style bubbles inside WhatsApp. Supports multiple primitives in a single message:
153
364
 
154
365
  ```javascript
155
- const { makeWASocket, enableCallAutoAnswer, getActiveVoipClient } = require('ishumdz-bail');
366
+ // Markdown text
367
+ await sock.sendMessage(jid, {
368
+ richResponse: {
369
+ text: '**Hello** from *ishumdz-bail*',
370
+ responseId: 'optional-uuid'
371
+ }
372
+ })
156
373
 
157
- const sock = makeWASocket({ auth: state });
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
+ })
158
394
 
159
- // Auto-answer calls with audio
160
- sock.enableCallAutoAnswer({
161
- audio: './welcome.wav',
162
- autoAnswer: true,
163
- answerDelayMs: 200,
164
- durationMs: 60000,
165
- loop: true
166
- });
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
+ })
167
402
 
168
- // Manual call handling
169
- sock.ev.on('call', async ([call]) => {
170
- if (call.status === 'offer') {
171
- await sock.rejectCall(call.id, call.from);
403
+ // LaTeX
404
+ await sock.sendMessage(jid, {
405
+ richResponse: {
406
+ latex: 'E = mc^2'
172
407
  }
173
- });
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)
174
439
  ```
175
440
 
176
441
  ---
177
442
 
178
- ## ⚡ Pro Methods
443
+ ## 🖼️ Album Message
444
+
445
+ Send multiple images/videos grouped into a single WA album:
179
446
 
180
447
  ```javascript
181
- const { makeWASocket, attachProMethods } = require('ishumdz-bail');
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
+ ```
182
457
 
183
- const sock = makeWASocket({ auth: state });
184
- attachProMethods(sock); // Attach all 34 Pro methods
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)
469
+ // {
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
477
+ // }
478
+ ```
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()
185
517
  ```
186
518
 
187
- ### 📊 Polls
519
+ ---
520
+
521
+ ## 🏘️ Communities Socket
188
522
 
189
523
  ```javascript
190
- await sock.sendPoll(jid, { name: 'Vote?', values: ['Yes', 'No'] });
191
- await sock.sendPollVote(jid, pollMsg, ['Yes']);
192
- const votes = sock.getAggregatePollVotes(pollMsg);
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)
193
552
  ```
194
553
 
195
- ### 📢 Newsletter/Channels
554
+ ---
555
+
556
+ ## 🔕 noSelfSync
557
+
558
+ Skip syncing outgoing messages to your own linked devices. Useful for high-volume bots where sync traffic is unnecessary:
196
559
 
197
560
  ```javascript
198
- await sock.channelVote('https://whatsapp.com/channel/xxx', 1);
199
- await sock.newsletterReact(jid, serverId, '👍');
200
- const msgs = await sock.newsletterGetMessages(jid, 50);
201
- const results = await sock.newsletterSearch('tech');
202
- const channels = await sock.newsletterList();
561
+ await sock.sendMessage(jid, { text: 'hello' }, { noSelfSync: true })
562
+
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 })
203
566
  ```
204
567
 
205
- ### 🟢 Status/Stories
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:
206
575
 
207
576
  ```javascript
208
- await sock.sendStatusText('Hello!', { backgroundColor: '#25D366' });
209
- await sock.sendStatusMedia('./photo.jpg', { type: 'image' });
210
- await sock.reactStatus(key, '❤️');
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)
595
+ }
596
+ }
597
+ })
211
598
  ```
212
599
 
213
- ### 💬 Chat
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`:
214
622
 
215
623
  ```javascript
216
- await sock.editMessage(jid, key, 'Updated!');
217
- await sock.deleteMessage(jid, key);
218
- await sock.pinMessage(jid, key, 86400);
219
- await sock.starMessage(jid, key, true);
220
- await sock.reactMessage(jid, key, '😂');
221
- await sock.sendPresence(jid, 'composing');
222
- await sock.reply(jid, 'Reply!', quotedMsg);
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)
643
+ }
223
644
  ```
224
645
 
225
- ### 👥 Groups
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>
226
670
 
227
671
  ```javascript
228
- const info = await sock.groupGetInviteInfo('https://chat.whatsapp.com/xxx');
229
- await sock.groupJoinViaInvite('https://chat.whatsapp.com/xxx');
230
- await sock.groupSetAnnouncement(jid, true);
231
- await sock.groupSetLocked(jid, true);
232
- const requests = await sock.groupRequestParticipantsList(jid);
233
- await sock.groupApproveParticipants(jid, [user1]);
234
- await sock.groupRejectParticipants(jid, [user2]);
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
+ })
235
679
  ```
680
+ </details>
236
681
 
237
- ### 👤 Profile
682
+ <details>
683
+ <summary><b>Example: Poll</b></summary>
238
684
 
239
685
  ```javascript
240
- const check = await sock.checkNumber('1234567890');
241
- await sock.setBio('My bot');
242
- await sock.updateProfileName('Bot Name');
243
- await sock.setProfilePicture(jid, './avatar.jpg');
244
- await sock.removeProfilePicture(jid);
245
- await sock.rejectCall(callId, callFrom);
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
+ })
246
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>
247
721
 
248
722
  ---
249
723
 
250
- ## 📰 Newsletter Media Paths
724
+ ## 🛠️ Additional Methods
251
725
 
252
726
  ```javascript
253
- const { NEWSLETTER_MEDIA_PATH_MAP } = require('ishumdz-bail');
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
+ })
254
732
 
255
- // All paths for channel uploads
256
- console.log(NEWSLETTER_MEDIA_PATH_MAP);
257
- // {
258
- // image: '/newsletter/newsletter-image',
259
- // video: '/newsletter/newsletter-video',
260
- // document: '/newsletter/newsletter-document',
261
- // audio: '/newsletter/newsletter-audio',
262
- // sticker: '/newsletter/newsletter-image',
263
- // gif: '/newsletter/newsletter-gif',
264
- // ptt: '/newsletter/newsletter-ptt',
265
- // ptv: '/newsletter/newsletter-ptv'
266
- // }
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)
267
742
  ```
268
743
 
269
744
  ---
270
745
 
271
- ## 📋 All Features List
272
-
273
- ```
274
- ┌─────────────────────────────────────────────────────────────────────────────┐
275
- │ COMPLETE FEATURE LIST │
276
- ├─────────────────────────────────────────────────────────────────────────────┤
277
- │ │
278
- │ 🎮 GAMES (8 functions) │
279
- │ ├── blackjack(action, playerHand, dealerHand, bet) │
280
- │ ├── slotMachine(bet) │
281
- │ ├── diceGame(bet, prediction) │
282
- │ ├── coinFlip(bet, choice) │
283
- │ ├── roulette(bet, choice) │
284
- │ ├── rps(choice) │
285
- │ ├── trivia(bet) │
286
- │ ├── createMines(rows, cols, mineCount) │
287
- │ ├── revealTile(game, row, col) │
288
- │ └── cashoutMines(game, bet) │
289
- │ │
290
- │ 📞 VOIP (3 functions) │
291
- │ ├── VoipClient │
292
- │ ├── ActiveCall │
293
- │ ├── AudioFeeder │
294
- │ ├── VideoFeeder │
295
- │ ├── enableCallAutoAnswer(sock, options) │
296
- │ └── getActiveVoipClient() │
297
- │ │
298
- │ ⚡ PRO METHODS (34 functions) │
299
- │ ├── sendPoll(jid, pollData) │
300
- │ ├── sendPollVote(jid, pollKey, options) │
301
- │ ├── getAggregatePollVotes(pollMsg) │
302
- │ ├── channelVote(target, option) │
303
- │ ├── newsletterVoteMessage(jid, serverId, option) │
304
- │ ├── newsletterReact(jid, serverId, reaction) │
305
- │ ├── newsletterGetMessages(jid, count) │
306
- │ ├── newsletterSearch(query) │
307
- │ ├── newsletterList() │
308
- │ ├── sendStatusText(text, options) │
309
- │ ├── sendStatusMedia(media, options) │
310
- │ ├── readStatus(key) │
311
- │ ├── reactStatus(key, emoji) │
312
- │ ├── editMessage(jid, key, text) │
313
- │ ├── deleteMessage(jid, key) │
314
- │ ├── pinMessage(jid, key, duration) │
315
- │ ├── unpinMessage(jid, key) │
316
- │ ├── starMessage(jid, key, star) │
317
- │ ├── reactMessage(jid, key, emoji) │
318
- │ ├── sendPresence(jid, presence) │
319
- │ ├── reply(jid, text, quoted) │
320
- │ ├── checkNumber(phone) │
321
- │ ├── setBio(text) │
322
- │ ├── updateProfileName(name) │
323
- │ ├── setProfilePicture(jid, content) │
324
- │ ├── removeProfilePicture(jid) │
325
- │ ├── rejectCall(callId, callFrom) │
326
- │ ├── groupGetInviteInfo(code) │
327
- │ ├── groupJoinViaInvite(code) │
328
- │ ├── groupSetAnnouncement(jid, bool) │
329
- │ ├── groupSetLocked(jid, bool) │
330
- │ ├── groupRequestParticipantsList(jid) │
331
- │ ├── groupApproveParticipants(jid, participants) │
332
- │ ├── groupRejectParticipants(jid, participants) │
333
- │ └── attachProMethods(sock) │
334
- │ │
335
- │ 📰 NEWSLETTER (8 functions) │
336
- │ ├── NEWSLETTER_MEDIA_PATH_MAP │
337
- │ ├── newsletterFetchMessages(jid, count, since, after) │
338
- │ ├── newsletterMetadata(type, query) │
339
- │ ├── newsletterReactMessage(jid, serverId, reaction) │
340
- │ ├── newsletterUpdate(jid, settings) │
341
- │ ├── newsletterCreate(name, description) │
342
- │ ├── newsletterDelete(jid) │
343
- │ └── newsletterFollow(jid) │
344
- │ │
345
- │ 📊 POLL VOTING (1 function) │
346
- │ └── getAggregateVotesInPollMessage(pollMsg) │
347
- │ │
348
- │ 🎯 CORE (10+ functions) │
349
- │ ├── makeWASocket(config) │
350
- │ ├── useMultiFileAuthState(dir) │
351
- │ ├── makeCacheableSignalKeyStore(state, logger) │
352
- │ ├── DisconnectReason │
353
- │ ├── delay(ms) │
354
- │ ├── proto │
355
- │ ├── encodeBinaryNode(frame) │
356
- │ ├── decodeBinaryNode(buffer) │
357
- │ ├── jidDecode(jid) │
358
- │ └── jidEncode(user, server) │
359
- │ │
360
- └─────────────────────────────────────────────────────────────────────────────┘
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
798
+
799
+ ```javascript
800
+ const rou = roulette(100, 'red') // red, black, odd, even, low, high
801
+ await sock.sendMessage(jid, { text: rou.message })
802
+ ```
803
+
804
+ ### ✊ Rock Paper Scissors
805
+
806
+ ```javascript
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 })
820
+
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 || ''
843
+
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
+ }
849
+
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
+ }
855
+
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
+ })
361
863
  ```
362
864
 
363
865
  ---
364
866
 
365
- ## 📄 License
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
+ ```
366
882
 
367
- MIT License
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
+ }
950
+ }
951
+ }
952
+ })
953
+ ```
954
+
955
+ ### 📱 Poll Bot Command Example
956
+
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
+ })
995
+ ```
368
996
 
369
997
  ---
370
998
 
999
+ ## 🌐 Community & Support
1000
+
371
1001
  <div align="center">
372
1002
 
373
- **Made with ❤️ by Lovely**
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
374
1019
 
375
- [![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)
376
- [![GitHub](https://img.shields.io/badge/GitHub-lovelyofficial-FF4500?style=for-the-badge&logo=github&logoColor=white)](https://github.com/lovelyofficial/ishumdz-bail)
1020
+ </div>
1021
+
1022
+ ---
1023
+
1024
+ <div align="center">
1025
+
1026
+ ### ⭐ If this project helped you, consider giving it a star!
1027
+
1028
+ Made with ❤️ by **Lovely**
377
1029
 
378
1030
  </div>
1031
+
1032
+ ---
1033
+
1034
+ ## 📄 License
1035
+
1036
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ishumdz-bail",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "WhatsApp API Modification By Lovely",
5
5
  "keywords": [
6
6
  "whatsapp",