@lzif/zaileys 1.0.0

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.
package/README.MD ADDED
@@ -0,0 +1,1230 @@
1
+ <div align="center">
2
+
3
+ <img alt="Zaileys - Simplified WhatsApp Node.js TypeScript/JavaScript API" src="https://github.com/zeative/zeative/blob/main/libraries/zaileys/zaileys-clean.png?raw=true" width="140">
4
+
5
+ <h1 align="center">Zaileys - Simplified WhatsApp Node.js <br /> TypeScript/JavaScript API</h1>
6
+
7
+ <br>
8
+
9
+ <div align="center">
10
+ <a href="https://www.npmjs.com/package/zaileys"><img src="https://img.shields.io/npm/v/zaileys.svg" alt="NPM Version"></a>
11
+ <a href="https://www.npmjs.com/package/zaileys"><img src="https://img.shields.io/npm/dw/zaileys?label=npm&color=%23CB3837" alt="NPM Downloads"></a>
12
+ <a href="https://github.com/zeative/zaileys/releases"><img src="https://img.shields.io/npm/dt/zaileys" alt="NPM Downloads"></a>
13
+ <a href="https://github.com/zeative/zaileys"><img src="https://img.shields.io/github/languages/code-size/zeative/zaileys" alt="GitHub Code Size"></a>
14
+ <a href="https://github.com/zeative/zaileys"><img src="https://img.shields.io/badge/TypeScript-5.0%2B-blue?style=flat-square&logo=typescript" alt="TypeScript"></a>
15
+ </div>
16
+
17
+ <div align="center">
18
+ <a href="https://github.com/zeative/zaileys"><img src="https://img.shields.io/github/license/zeative/zaileys" alt="GitHub License"></a>
19
+ <a href="https://discord.gg/KBHhTTVUc5"><img alt="Discord" src="https://img.shields.io/discord/1105833273415962654?logo=discord&label=discord&link=https%3A%2F%2Fgithub.com%2Fzeative%2Fzaileys"></a>
20
+ <a href="https://github.com/zeative/zaileys"><img src="https://img.shields.io/github/stars/zeative/zaileys" alt="GitHub Stars"></a>
21
+ <a href="https://github.com/zeative/zaileys"><img src="https://img.shields.io/github/forks/zeative/zaileys" alt="GitHub Forks"></a>
22
+ <a href="https://github.com/zeative/zaileys"><img src="https://img.shields.io/github/watchers/zeative/zaileys" alt="GitHub Watchers"></a>
23
+ <a href="https://deepwiki.com/zeative/zaileys"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
24
+ </div>
25
+
26
+ <br>
27
+
28
+ <div align="center">
29
+ <p>
30
+ <b>Zaileys</b> is a powerful, type-safe wrapper around <a href="https://github.com/WhiskeySockets/Baileys">Baileys</a>, designed to simplify the development of WhatsApp bots. It provides a robust architecture with built-in state management, middleware support, and easy-to-use event handlers, making it perfect for building scalable and maintainable WhatsApp applications.
31
+ </p>
32
+ </div>
33
+
34
+ <div align="center">
35
+
36
+ [๐Ÿš€ Overview](#-overview) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
37
+ [๐Ÿชถ Features](#-features) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
38
+ [๐Ÿ“ฆ Installation](#-installation) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
39
+ [๐Ÿ Starter Kit](#-starter-kit) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
40
+ [โšก Quick Start](#-quick-start) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
41
+ [๐Ÿงฉ Plugins](#-plugins) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
42
+ [๐Ÿ“จ Sending Messages](#-sending-messages) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
43
+ [๐Ÿ‘ฅ Group Management](#-group-management) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
44
+ [๐Ÿ“ฐ Newsletter Management](#-newsletter-channel) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
45
+ [๐ŸŒ Community Management](#-community-management) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
46
+ [๐Ÿ”’ Privacy](#-privacy-settings) &nbsp;&nbsp;โ€ข&nbsp;&nbsp;
47
+ [๐Ÿค Contributing](#-contributing)
48
+
49
+ <br>
50
+
51
+ <a href="https://discord.gg/KBHhTTVUc5"><img alt="Discord" src="https://discord.com/api/guilds/1105833273415962654/widget.png?style=banner2"></a>
52
+
53
+ </div>
54
+
55
+ </div>
56
+
57
+ <br>
58
+
59
+ ---
60
+
61
+ ## ๐Ÿš€ Overview
62
+
63
+ > Zaileys solves the complexity of managing raw WhatsApp socket connections by providing a high-level, opinionated API. It is built for developers who need to create bots, customer support agents, or automated notification systems without getting bogged down in protocol details.
64
+
65
+ Targeting **Node.js** and **TypeScript** developers, Zaileys integrates essential features like rate limiting, session management, and input validation out of the box.
66
+
67
+ ## ๐Ÿชถ Features
68
+
69
+ - โœ… **Type-Safe** - Full TypeScript + Zod validation with autocomplete
70
+ - โœ… **Middleware** - Intercept and process events globally
71
+ - โœ… **Plugin System** - Drop-in file-based plugins with on/off controls
72
+ - โœ… **State Management** - Built-in [JetDB](https://github.com/zeative/jetdb) for data persistence with **auto chunking**
73
+ - โœ… **Rate Limiting** - Anti-spam protection out of the box
74
+ - โœ… **Multi-Device** - QR code or Pairing Code authentication
75
+ - โœ… **Built-in FFmpeg** - No external dependencies for media processing
76
+ - โœ… **Interactive Buttons** - Simple buttons, URL, copy code, call buttons, and lists
77
+ - โœ… **Context Injection** - Universal data injection accessible anywhere in ctx
78
+ - โœ… **Fire and Forget** - Background task processing for lightning-fast responses
79
+ - โœ… **Auto-Healing** - Intelligent connection monitoring and session repair
80
+ - โœ… **Auto Clean Up** - Periodic database maintenance to save space
81
+
82
+ ## ๐ŸŽจ Concepts & Architecture
83
+
84
+ **Client** - Your bot's brain. Manages connections, events, and the entire lifecycle.
85
+
86
+ **Context** - Rich event objects with all the data and helpers you need.
87
+
88
+ **Middleware** - Pre-process events for logging, auth, spam filtering, or custom logic.
89
+
90
+ **Plugins** - Drop files in `plugins/` directory. Auto-loaded, zero config.
91
+
92
+ **Store** - JSON database (`JetDB`) that auto-syncs chats, contacts, and messages.
93
+
94
+ ## ๐Ÿ“ฆ Installation
95
+
96
+ Install `zaileys` using your preferred package manager:
97
+
98
+ ```bash
99
+ npm install zaileys
100
+ # or
101
+ pnpm add zaileys
102
+ # or
103
+ yarn add zaileys
104
+ ```
105
+
106
+ > **Note**: Requires Node.js v20+ and TypeScript for best experience.
107
+
108
+ > **FFmpeg**: No need to install FFmpeg separately! It's already bundled with Zaileys for seamless media processing (audio, video, stickers). You can disabled it if you want at `Client Configuration`.
109
+
110
+ ## ๐Ÿ Starter Kit
111
+
112
+ Prefer a ready-to-run setup? We provide an official **Starter Kit** that includes a fully configured environment, example commands, and best practices.
113
+
114
+ ๐Ÿ‘‰ [**Zaileys Example**](https://github.com/zeative/starter-zaileys)
115
+
116
+ ## โšก Quick Start
117
+
118
+ Here is a minimal example to get your bot running with QR code authentication:
119
+
120
+ ```typescript
121
+ import { Client } from 'zaileys';
122
+ // or
123
+ const { Client } = require('zaileys');
124
+
125
+ const wa = new Client({
126
+ // dynamic session you can change
127
+ session: 'zaileys', // default
128
+
129
+ // qr code
130
+ authType: 'qr',
131
+
132
+ // pairing code
133
+ authType: 'pairing',
134
+ phoneNumber: 6280000000,
135
+
136
+ // for detailed logs
137
+ // fancyLogs: true,
138
+
139
+ // if you want to disable built-in ffmpeg
140
+ // disableFFmpeg: true,
141
+
142
+ // plugin configuration
143
+ pluginsDir: 'plugins', // default
144
+ pluginsHmr: true, // default: true (auto reload plugins on change)
145
+
146
+ sticker: {
147
+ authorName: 'your name',
148
+ packageName: 'package name',
149
+ quality: 80,
150
+ shape: 'circle', // output sticker must be circle
151
+ },
152
+ });
153
+
154
+ wa.on('messages', async (ctx) => {
155
+ if (ctx.text == 'ping') {
156
+ await wa.send(ctx.roomId, 'Pong! ๐Ÿ“');
157
+ }
158
+ });
159
+ ```
160
+
161
+ <details>
162
+ <summary>โœจ Structure of <b>ctx</b> on event listener <code>messages</code></summary>
163
+
164
+ ```jsonc
165
+ {
166
+ "uniqueId": "Z4D3FCXXXXXXXXXXXXX",
167
+ "channelId": "Z4D3FCXXXXXXXXXXXXX",
168
+
169
+ "chatId": "ACAE07XXXXXXXXXXXXX",
170
+ "chatType": "text",
171
+
172
+ "receiverId": "628xxxxxxxx@s.whatsapp.net",
173
+ "receiverName": "Zaileys",
174
+
175
+ "roomId": "120xxxxxxxx@g.us",
176
+ "roomName": "Group Test",
177
+ "senderLid": "272xxxxxxxx@lid",
178
+
179
+ "senderId": "628xxxxxxxx@s.whatsapp.net",
180
+ "senderName": "kejaa",
181
+ "senderDevice": "android",
182
+
183
+ "timestamp": 1766045633000,
184
+ "text": "World Hello! https://github.com/zeative/zaileys",
185
+
186
+ "mentions": ["@628xxxxxxxx", "@123xxxxxxxx"],
187
+ "links": ["https://github.com/zeative/zaileys"],
188
+
189
+ "isBot": false,
190
+ "isFromMe": false,
191
+ "isPrefix": false,
192
+ "isTagMe": false,
193
+
194
+ "isStatusMention": false,
195
+ "isGroupStatusMention": false,
196
+ "isHideTags": true,
197
+
198
+ "isSpam": false,
199
+ "isGroup": true,
200
+ "isNewsletter": false,
201
+ "isQuestion": false,
202
+ "isStory": false,
203
+
204
+ "isViewOnce": false,
205
+ "isEdited": false,
206
+ "isDeleted": false,
207
+ "isPinned": false,
208
+ "isUnPinned": false,
209
+
210
+ "isBroadcast": false,
211
+ "isEphemeral": false,
212
+ "isForwarded": false,
213
+
214
+ "citation": {
215
+ "authors": [AsyncFunction (anonymous)],
216
+ "banned": [AsyncFunction (anonymous)]
217
+ },
218
+
219
+ "media": {
220
+ // ...
221
+ // buffer promise
222
+ // stream promise
223
+ },
224
+
225
+ "message": [Function (anonymous)],
226
+ "replied": {} // MessagesContext
227
+ }
228
+
229
+ ````
230
+ </details>
231
+
232
+ ## ๐Ÿ› ๏ธ Configuration
233
+
234
+ The `Client` constructor accepts a configuration object. Below are the valid options based on the library's type definitions.
235
+
236
+ ### General Options
237
+
238
+ These options apply to both authentication methods:
239
+
240
+ | Option | Type | Default | Description |
241
+ | :---------------- | :-------- | :---------- | :-------------------------------------- |
242
+ | `session` | `string` | `'zaileys'` | Name of the session folder. |
243
+ | `prefix` | `string` | `undefined` | Command prefix (e.g., `'/'`). |
244
+ | `showLogs` | `boolean` | `true` | Enable internal logging. |
245
+ | `fancyLogs` | `boolean` | `false` | Enable detailed, fancy log output. |
246
+ | `ignoreMe` | `boolean` | `true` | Ignore messages sent by the bot itself. |
247
+ | `syncFullHistory` | `boolean` | `true` | Sync full chat history on startup. |
248
+ | `pluginsDir` | `string` | `'plugins'` | Directory where plugins are located. |
249
+ | `pluginsHmr` | `boolean` | `true` | Enable Hot Module Replacement for plugins. |
250
+ | `cleanupDays` | `number` | `7` | Days to keep messages before auto-deletion. |
251
+ | `autoCleanUp` | `object` | `undefined` | Configuration for periodic database cleanup. |
252
+ | `disableFFmpeg` | `boolean` | `false` | Disable built-in FFmpeg installers. |
253
+
254
+ ### Automation Options
255
+
256
+ | Option | Type | Default | Description |
257
+ | :--------------- | :-------- | :------ | :--------------------------------------------------------- |
258
+ | `autoRead` | `boolean` | `true` | Automatically mark messages as read. |
259
+ | `autoOnline` | `boolean` | `true` | Automatically set presence to online. |
260
+ | `autoPresence` | `boolean` | `true` | Automatically send presence updates (composing/recording). |
261
+ | `autoMentions` | `boolean` | `true` | Automatically handle mentions. |
262
+ | `autoRejectCall` | `boolean` | `true` | Automatically reject incoming calls. |
263
+
264
+ ### Advanced Configuration
265
+
266
+ | Option | Type | Description |
267
+ | :---------- | :------- | :------------------------------------------------------------------------------ |
268
+ | `limiter` | `object` | Rate limiting configuration. Default: `maxMessages: 20, durationMs: 10_000`. |
269
+ | `fakeReply` | `object` | Configuration for fake reply provider. |
270
+ | `sticker` | `object` | Default metadata for sticker creation (`packageName`, `authorName`, `quality`, `shape`). |
271
+ | `citation` | `object` | Custom citation sources. |
272
+
273
+ ## ๐Ÿ’ก Advanced Usage
274
+
275
+ ### Middleware & Spam Protection
276
+
277
+ You can use middleware to filter messages or add custom logic before your handlers run.
278
+
279
+ ```typescript
280
+ wa.use(async (ctx, next) => {
281
+ if (ctx.messages.isSpam) {
282
+ console.warn(`Spam detected from ${ctx.messages.senderName}`);
283
+ return;
284
+ }
285
+
286
+ await next();
287
+ });
288
+ ````
289
+
290
+ ### ๐Ÿงฉ Plugins
291
+
292
+ Zaileys features a built-in file-based plugin system with **Hot Module Replacement (HMR)** support. By default, it looks for plugins in the `plugins` directory of your project root and automatically reloads them when you make changes.
293
+
294
+ **0. Configuration:**
295
+ You can customize the plugin directory and HMR behavior in the `Client` constructor:
296
+
297
+ ```typescript
298
+ const wa = new Client({
299
+ pluginsDir: 'my-plugins', // Custom plugins directory
300
+ pluginsHmr: true, // Enable/disable HMR (default: true)
301
+ });
302
+ ```
303
+
304
+ **1. Create a plugin file** (e.g., `plugins/hello.ts`):
305
+
306
+ also nested file `plugins/nested1/nested2/hello.ts`
307
+
308
+ ```typescript
309
+ import { definePlugins } from 'zaileys';
310
+
311
+ export default definePlugins(
312
+ async (wa, ctx) => {
313
+ await wa.send(ctx.messages.roomId, 'Hello from plugin!');
314
+ },
315
+ {
316
+ matcher: ['/hello', '!hello'], // Trigger commands
317
+ metadata: {
318
+ description: 'A simple hello world plugin',
319
+ },
320
+ },
321
+ );
322
+ ```
323
+
324
+ **2. Extract plugin information** (optional):
325
+
326
+ ```typescript
327
+ const pluginsInfo = wa.plugins.getPluginsInfo();
328
+
329
+ /* Example output
330
+ [
331
+ {
332
+ matcher: ['/hello', '!hello'],
333
+ metadata: {
334
+ description: 'A simple hello world plugin',
335
+ },
336
+ }
337
+ ]
338
+ */
339
+ ```
340
+
341
+ This returns an array of all loaded plugins with their `matcher` and `metadata`, useful for generating help menus or listing available commands.
342
+
343
+ **3. Plugin Controls:**
344
+
345
+ ```typescript
346
+ // Disable all plugins
347
+ wa.plugins.disableAll();
348
+
349
+ // Enable all plugins
350
+ wa.plugins.enableAll();
351
+
352
+ // Disable specific plugin by matcher
353
+ wa.plugins.disable('/hello');
354
+
355
+ // Enable specific plugin
356
+ wa.plugins.enable('/hello');
357
+
358
+ // Disable all plugins in a folder (e.g., plugins/admin/)
359
+ wa.plugins.disableByParent('admin');
360
+
361
+ // Enable all plugins in a folder
362
+ wa.plugins.enableByParent('admin');
363
+
364
+ // Check if plugins are globally enabled
365
+ wa.plugins.isEnabled(); // true/false
366
+ ```
367
+
368
+ ### ๐Ÿ” Citation (Custom Authorization)
369
+
370
+ Citation allows you to define custom authorization logic by creating named checkers that verify if a user is in a specific list (e.g., premium users, banned users).
371
+
372
+ **1. Configure citation sources** in the client options:
373
+
374
+ ```typescript
375
+ const wa = new Client({
376
+ authType: 'qr',
377
+ citation: {
378
+ premium: async () => {
379
+ // const numbers = await fetch...
380
+ return [6280000000, 12388888888];
381
+ },
382
+ banned: async () => {
383
+ return [6285555555555];
384
+ },
385
+ },
386
+ });
387
+ ```
388
+
389
+ **2. Use citation in your message handlers**:
390
+
391
+ ```typescript
392
+ wa.on('messages', async (ctx) => {
393
+ const isBanned = await ctx.citation.banned();
394
+ const isPremium = await ctx.citation.premium();
395
+
396
+ if (isBanned) return;
397
+
398
+ if (isPremium) {
399
+ await wa.send(ctx.roomId, 'Premium feature unlocked!');
400
+ }
401
+ });
402
+ ```
403
+
404
+ Each citation function returns `true` if the sender matches any ID in the returned list, `false` otherwise.
405
+
406
+ **How it works:**
407
+
408
+ Citation functions return an array of phone numbers, group id and lid Internally, Zaileys compares the sender's ID against this list by checking:
409
+
410
+ - `roomId` - The chat/group ID
411
+ - `senderId` - The sender's WhatsApp ID
412
+ - `senderLid` - The sender's LID
413
+
414
+ If any of these match a number in your returned array, the citation check returns `true`. This makes it flexible for both individual chats and group scenarios.
415
+
416
+ ### ๐Ÿ”Œ Context Injection
417
+
418
+ Context Injection allows you to inject custom data that is accessible in every message context.
419
+
420
+ **1. Inject data:**
421
+
422
+ ```typescript
423
+ // Inject data anywhere in your app
424
+ wa.inject('user', { name: 'Kejaa', role: 'admin' });
425
+ wa.inject('config', { debug: true, version: '1.0.0' });
426
+ ```
427
+
428
+ **2. Access injected data in handlers:**
429
+
430
+ ```typescript
431
+ wa.on('messages', async (ctx) => {
432
+ console.log(ctx.injection.user); // { name: 'John', role: 'admin' }
433
+ console.log(ctx.injection.config); // { debug: true, version: '1.0.0' }
434
+ });
435
+ ```
436
+
437
+ **3. Manage injections:**
438
+
439
+ ```typescript
440
+ // Get injection value
441
+ const user = wa.getInjection('user');
442
+
443
+ // Remove specific injection
444
+ wa.removeInjection('user');
445
+
446
+ // Clear all injections
447
+ wa.clearInjections();
448
+ ```
449
+
450
+ This is perfect for sharing database connections, user sessions, or configuration across all handlers.
451
+
452
+ ### ๐Ÿ›ก๏ธ Auto-Healing
453
+
454
+ Zaileys includes an intelligent `HealthManager` that monitors your connection and automatically repairs corrupted sessions.
455
+
456
+ - **Bad MAC Repair**: Automatically detects "Bad MAC" errors and repairs the affected session keys without requiring a full logout.
457
+ - **Log Suppression**: Silences noisy stack traces and internal error messages from `libsignal-node` to keep your terminal clean.
458
+ - **Zero Config**: Enabled by default and works silently in the background.
459
+
460
+ ### ๐Ÿงน Auto Clean Up
461
+
462
+ Keep your database lean and performant by enabling automatic cleanup of old messages.
463
+
464
+ ```typescript
465
+ const wa = new Client({
466
+ autoCleanUp: {
467
+ enabled: true,
468
+ intervalMs: 60 * 60 * 1000, // Run every 1 hour
469
+ maxAgeMs: 24 * 60 * 60 * 1000, // Delete messages older than 24 hours
470
+ scopes: ['messages'], // Database scopes to clean
471
+ },
472
+ });
473
+ ```
474
+
475
+ The `CleanUpManager` runs in the background and ensures your storage usage stays within limits.
476
+
477
+ ## ๐Ÿ“ซ Sending Messages
478
+
479
+ > **Quick Jump:** [Text](#send-text) ยท [Reply](#reply-to-message) ยท [Forward](#forward-message) ยท [Media](#send-media) ยท [Banner](#send-with-banner) ยท [Location](#send-location) ยท [Contact](#send-contact) ยท [Poll](#send-poll) ยท [Reaction](#send-reaction) ยท [Presence](#update-presence) ยท [Mentions](#mentions) ยท [Edit & Delete](#edit--delete-messages) ยท [Buttons](#interactive-buttons) ยท [Member Label](#member-label)
480
+
481
+ ### Send Text
482
+
483
+ Send a simple text message to any chat.
484
+
485
+ ```typescript
486
+ await wa.send(ctx.roomId, 'Hello World!');
487
+
488
+ await wa.send(ctx.roomId, {
489
+ text: 'Hello with options!',
490
+ });
491
+ ```
492
+
493
+ ### Reply to Message
494
+
495
+ Reply to a specific message using the `replied` option.
496
+
497
+ ```typescript
498
+ await wa.send(ctx.roomId, {
499
+ text: 'This is a reply!',
500
+ replied: ctx.message(),
501
+ });
502
+ ```
503
+
504
+ ### Forward Message
505
+
506
+ Forward message to any chat.
507
+
508
+ ```typescript
509
+ await wa.forward(ctx.roomId, {
510
+ text: 'Forwarded message',
511
+ isForwardedMany: true,
512
+ });
513
+ ```
514
+
515
+ ### Send Media
516
+
517
+ Send images, videos, audio, stickers, or documents. Media can be a URL, Buffer, or base64 string.
518
+
519
+ **Image:**
520
+
521
+ ```typescript
522
+ await wa.send(ctx.roomId, {
523
+ image: 'https://example.com/image.jpg',
524
+ caption: 'Check this out!',
525
+ });
526
+
527
+ await wa.send(ctx.roomId, {
528
+ image: fs.readFileSync('./image.jpg'),
529
+ caption: 'Image from buffer',
530
+ isViewOnce: true,
531
+ });
532
+ ```
533
+
534
+ **Video:**
535
+
536
+ ```typescript
537
+ await wa.send(ctx.roomId, {
538
+ video: 'https://example.com/video.mp4',
539
+ caption: 'Cool video!',
540
+ ptv: true,
541
+ });
542
+ ```
543
+
544
+ **Audio:**
545
+
546
+ ```typescript
547
+ await wa.send(ctx.roomId, {
548
+ audio: 'https://example.com/audio.mp3',
549
+ ptt: true,
550
+ });
551
+ ```
552
+
553
+ **Sticker:**
554
+
555
+ ```typescript
556
+ // support gif and video
557
+ await wa.send(ctx.roomId, {
558
+ sticker: 'https://example.com/sticker.mp4',
559
+ shape: 'circle', // default: 'default' | 'circle' | 'rounded' | 'oval'
560
+ });
561
+ ```
562
+
563
+ **Document:**
564
+
565
+ ```typescript
566
+ await wa.send(ctx.roomId, {
567
+ document: 'https://example.com/file.pdf',
568
+ fileName: 'document.pdf',
569
+ caption: 'Here is the file',
570
+ });
571
+ ```
572
+
573
+ ### Send with Banner
574
+
575
+ Send messages with an external ad reply banner (link preview).
576
+
577
+ ```typescript
578
+ await wa.send(ctx.roomId, {
579
+ text: 'Banner message!',
580
+ banner: {
581
+ thumbnailUrl: 'https://github.com/zeative.png',
582
+ sourceUrl: 'https://jaa.web.id',
583
+ title: 'Test Banner',
584
+ body: 'Hello World!',
585
+ },
586
+ });
587
+ ```
588
+
589
+ ### Send Location
590
+
591
+ Send location with coordinates.
592
+
593
+ ```typescript
594
+ await wa.send(ctx.roomId, {
595
+ location: {
596
+ latitude: -6.2,
597
+ longitude: 106.816666,
598
+ title: 'Jakarta',
599
+ footer: 'Capital of Indonesia',
600
+ url: 'https://maps.google.com/?q=-6.200000,106.816666',
601
+ },
602
+ });
603
+ ```
604
+
605
+ ### Send Contact
606
+
607
+ Send one or multiple contacts.
608
+
609
+ ```typescript
610
+ await wa.send(ctx.roomId, {
611
+ contacts: {
612
+ title: 'My Contacts',
613
+ contacts: [
614
+ {
615
+ fullname: 'John Doe',
616
+ phoneNumber: 6281234567890,
617
+ organization: 'Company Inc.',
618
+ },
619
+ {
620
+ fullname: 'Jane Smith',
621
+ phoneNumber: 6289876543210,
622
+ },
623
+ ],
624
+ },
625
+ });
626
+ ```
627
+
628
+ ### Send Poll
629
+
630
+ Create a poll with multiple options.
631
+
632
+ ```typescript
633
+ await wa.send(ctx.roomId, {
634
+ poll: {
635
+ name: 'What is your favorite color?',
636
+ answers: ['Red', 'Blue', 'Green', 'Yellow'],
637
+ isMultiple: false,
638
+ },
639
+ });
640
+ ```
641
+
642
+ ### Send Reaction
643
+
644
+ React to a message with an emoji.
645
+
646
+ ```typescript
647
+ await wa.reaction(ctx.message(), '๐Ÿ‘');
648
+
649
+ await wa.reaction(ctx.message(), 'โค๏ธ');
650
+ ```
651
+
652
+ ### Update Presence
653
+
654
+ Update your presence status in a chat.
655
+
656
+ ```typescript
657
+ await wa.presence(ctx.roomId, 'typing');
658
+
659
+ await wa.presence(ctx.roomId, 'recording');
660
+ ```
661
+
662
+ ### Mentions
663
+
664
+ Mentions are automatically detected when `autoMentions` is enabled (default: `true`).
665
+
666
+ ```typescript
667
+ // support lid
668
+ await wa.send(ctx.roomId, 'Hello @6281234567890!');
669
+ ```
670
+
671
+ ### Edit & Delete Messages
672
+
673
+ **Edit message:**
674
+
675
+ ```typescript
676
+ const sent = await wa.send(ctx.roomId, 'Original text');
677
+
678
+ setTimeout(async () => {
679
+ await wa.edit(sent, 'Edited text');
680
+ }, 2000);
681
+ ```
682
+
683
+ **Delete message:**
684
+
685
+ ```typescript
686
+ const sent = await wa.send(ctx.roomId, 'This will be deleted');
687
+
688
+ setTimeout(async () => {
689
+ await wa.delete(sent);
690
+ }, 2000);
691
+
692
+ // or multiple messages
693
+ await wa.delete([sent1, sent2]);
694
+ ```
695
+
696
+ ### Interactive Buttons
697
+
698
+ Send messages with interactive buttons.
699
+
700
+ **Simple Buttons:**
701
+
702
+ > โœ… Simple button has support Android/iPhone/Desktop
703
+
704
+ ```typescript
705
+ await wa.button(ctx.roomId, {
706
+ text: 'Choose an option:',
707
+ buttons: {
708
+ type: 'simple',
709
+ footer: 'Footer text',
710
+ data: [
711
+ { id: 'btn1', text: 'Option 1' },
712
+ { id: 'btn2', text: 'Option 2' },
713
+ { id: 'btn3', text: 'Option 3' },
714
+ ],
715
+ },
716
+ });
717
+ ```
718
+
719
+ **Interactive Buttons:**
720
+
721
+ > โš ๏ธ Experimental, only support Android/iPhone
722
+
723
+ ```typescript
724
+ await wa.button(ctx.roomId, {
725
+ text: 'Interactive menu:',
726
+ buttons: {
727
+ type: 'interactive',
728
+ footer: 'Footer text',
729
+ data: [
730
+ { type: 'quick_reply', id: 'reply1', text: 'Quick Reply' },
731
+ { type: 'cta_url', text: 'Visit Website', url: 'https://example.com' },
732
+ { type: 'cta_copy', id: 'copy1', text: 'Copy Code', copy: 'PROMO123' },
733
+ { type: 'cta_call', text: 'Call Us', phoneNumber: '+6281234567890' },
734
+ ],
735
+ },
736
+ });
737
+ ```
738
+
739
+ **Lists Buttons:**
740
+
741
+ > โš ๏ธ Experimental, not supported on some devices. Don't use in production!
742
+
743
+ ```typescript
744
+ await wa.button(ctx.roomId, {
745
+ text: 'Choose an option:',
746
+ buttons: {
747
+ type: 'interactive',
748
+ footer: 'Footer text',
749
+ data: [
750
+ {
751
+ type: 'single_select',
752
+ text: 'Choose an option:',
753
+ section: [
754
+ {
755
+ title: 'Section 1',
756
+ rows: [
757
+ { id: 'btn1', title: 'Option 1' },
758
+ { id: 'btn2', title: 'Option 2' },
759
+ { id: 'btn3', title: 'Option 3' },
760
+ ],
761
+ },
762
+ ],
763
+ },
764
+ ],
765
+ },
766
+ });
767
+ ```
768
+
769
+ ### Member Label
770
+
771
+ Labeling user member on group chat.
772
+
773
+ ```typescript
774
+ await wa.memberLabel(ctx.roomId, 'Fullstack Developer');
775
+ ```
776
+
777
+ ## ๐Ÿ‘ฅ Group Management
778
+
779
+ > **Quick Jump:** [Create](#create-group) ยท [Participants](#manage-participants) ยท [Profile](#group-profile) ยท [Settings](#group-settings) ยท [Invite Code](#invite-code) ยท [Metadata](#group-metadata) ยท [Join Requests](#join-requests) ยท [Fetch All](#fetch-all-groups) ยท [Ephemeral](#ephemeral-messages) ยท [Leave](#leave-group)
780
+
781
+ Manage groups, participants, and settings easily.
782
+
783
+ ### Create Group
784
+
785
+ Create a new group with initial participants.
786
+
787
+ ```typescript
788
+ // Create group with name and participants
789
+ const group = await wa.group.create('My Group', ['senderId']);
790
+ console.log('Group created:', group);
791
+ ```
792
+
793
+ ### Manage Participants
794
+
795
+ Add, remove, promote, or demote participants.
796
+
797
+ ```typescript
798
+ const groupId = '1234567890@g.us';
799
+
800
+ // Add participants
801
+ await wa.group.participant(groupId, ['senderId'], 'add');
802
+
803
+ // Remove participants
804
+ await wa.group.participant(groupId, [...], 'remove');
805
+
806
+ // Promote to admin
807
+ await wa.group.participant(groupId, [...], 'promote');
808
+
809
+ // Demote to member
810
+ await wa.group.participant(groupId, [...], 'demote');
811
+ ```
812
+
813
+ ### Group Profile
814
+
815
+ Update group subject, description, or icon.
816
+
817
+ ```typescript
818
+ // Update subject
819
+ await wa.group.profile(groupId, 'New Group Name', 'subject');
820
+
821
+ // Update description
822
+ await wa.group.profile(groupId, 'This is the new description', 'description');
823
+
824
+ // Update group avatar (from URL or Buffer)
825
+ await wa.group.profile(groupId, 'https://example.com/icon.jpg', 'avatar');
826
+ ```
827
+
828
+ ### Group Settings
829
+
830
+ Configure group permissions.
831
+
832
+ ```typescript
833
+ // All members can send messages
834
+ await wa.group.setting(groupId, 'open');
835
+
836
+ // Only admins can send messages
837
+ await wa.group.setting(groupId, 'close');
838
+
839
+ // Only admins can edit group info
840
+ await wa.group.setting(groupId, 'locked');
841
+
842
+ // All members can edit group info
843
+ await wa.group.setting(groupId, 'unlocked');
844
+
845
+ // Only admins can add members
846
+ await wa.group.setting(groupId, 'admin_add');
847
+
848
+ // All members can add members
849
+ await wa.group.setting(groupId, 'all_member_add');
850
+ ```
851
+
852
+ ### Invite Code
853
+
854
+ Manage group invite links.
855
+
856
+ ```typescript
857
+ // Get current invite code
858
+ const code = await wa.group.inviteCode(groupId, 'code');
859
+ console.log('Invite link:', `https://chat.whatsapp.com/${code}`);
860
+
861
+ // Revoke invite code
862
+ await wa.group.inviteCode(groupId, 'revoke');
863
+
864
+ // Get invite info
865
+ const info = await wa.group.inviteCode('INVITE_CODE', 'info');
866
+
867
+ // Join group via invite code
868
+ await wa.group.inviteCode('INVITE_CODE', 'accept');
869
+ ```
870
+
871
+ ### Group Metadata
872
+
873
+ Get full group metadata.
874
+
875
+ ```typescript
876
+ const metadata = await wa.group.metadata(groupId);
877
+ console.log(metadata);
878
+ ```
879
+
880
+ ### Join Requests
881
+
882
+ Manage pending join requests.
883
+
884
+ ```typescript
885
+ // Get list of pending requests
886
+ const requests = await wa.group.requestJoinList(groupId);
887
+
888
+ // Approve requests
889
+ await wa.group.requestJoin(groupId, ['senderId'], 'approve');
890
+
891
+ // Reject requests
892
+ await wa.group.requestJoin(groupId, [...], 'reject');
893
+ ```
894
+
895
+ ### Fetch All Groups
896
+
897
+ Get all groups the bot is part of.
898
+
899
+ ```typescript
900
+ const groups = await wa.group.fetchAllGroups();
901
+ console.log('Joined groups:', Object.keys(groups).length);
902
+ ```
903
+
904
+ ### Ephemeral Messages
905
+
906
+ Set disappearing messages in groups.
907
+
908
+ ```typescript
909
+ // Turn off disappearing messages
910
+ await wa.group.ephemeral(groupId, 'off');
911
+
912
+ // Set to 24 hours
913
+ await wa.group.ephemeral(groupId, '24h');
914
+
915
+ // Set to 7 days
916
+ await wa.group.ephemeral(groupId, '7d');
917
+
918
+ // Set to 90 days
919
+ await wa.group.ephemeral(groupId, '90d');
920
+ ```
921
+
922
+ ### Leave Group
923
+
924
+ Leave group.
925
+
926
+ ```typescript
927
+ await wa.group.leave(groupId);
928
+ ```
929
+
930
+ ## ๐Ÿ“ฐ Newsletter (Channel)
931
+
932
+ Create and manage WhatsApp Channels (Newsletters).
933
+
934
+ > **Quick Jump:** [Create](#create-channel) ยท [Actions](#channel-actions) ยท [Update](#update-channel) ยท [Info](#channel-info) ยท [Messages](#manage-messages) ยท [Admin](#admin-actions)
935
+
936
+ ### Create Channel
937
+
938
+ ```typescript
939
+ const channel = await wa.newsletter.create('My Channel', 'Description here');
940
+ console.log('Channel created:', channel);
941
+ ```
942
+
943
+ ### Channel Actions
944
+
945
+ Follow, unfollow, mute, or unmute a channel.
946
+
947
+ ```typescript
948
+ const channelId = '1234567890@newsletter';
949
+
950
+ // Follow
951
+ await wa.newsletter.action(channelId, 'follow');
952
+
953
+ // Unfollow
954
+ await wa.newsletter.action(channelId, 'unfollow');
955
+
956
+ // Mute
957
+ await wa.newsletter.action(channelId, 'mute');
958
+
959
+ // Unmute
960
+ await wa.newsletter.action(channelId, 'unmute');
961
+ ```
962
+
963
+ ### Update Channel
964
+
965
+ Update channel info.
966
+
967
+ ```typescript
968
+ // Update name
969
+ await wa.newsletter.update(channelId, 'New Name', 'name');
970
+
971
+ // Update description
972
+ await wa.newsletter.update(channelId, 'New Description', 'description');
973
+
974
+ // Update picture (URL/Buffer)
975
+ await wa.newsletter.update(channelId, 'https://example.com/image.jpg', 'picture');
976
+
977
+ // Remove picture
978
+ await wa.newsletter.removePicture(channelId);
979
+ ```
980
+
981
+ ### Channel Info
982
+
983
+ Get channel details.
984
+
985
+ ```typescript
986
+ // Get metadata by ChannelId
987
+ const meta = await wa.newsletter.metadata(channelId, 'jid');
988
+
989
+ // Get metadata by Invite Code
990
+ const metaInvite = await wa.newsletter.metadata('INVITE_CODE', 'invite');
991
+
992
+ // Get subscribers
993
+ const subs = await wa.newsletter.subscribers(channelId);
994
+
995
+ // Get admin count
996
+ const adminCount = await wa.newsletter.adminCount(channelId);
997
+ ```
998
+
999
+ ### Manage Messages
1000
+
1001
+ Fetch messages or react to them.
1002
+
1003
+ ```typescript
1004
+ // Fetch messages
1005
+ const since = new Date() - 1000 * 60 * 60 * 24; // 1 day
1006
+ const after = new Date();
1007
+
1008
+ const count = 10;
1009
+
1010
+ const messages = await wa.newsletter.fetchMessages(channelId, count, since, after);
1011
+
1012
+ // React to message
1013
+ await wa.newsletter.reaction(channelId, 'chatId', '๐Ÿ‘');
1014
+ ```
1015
+
1016
+ ### Admin Actions
1017
+
1018
+ Manage channel ownership and admins.
1019
+
1020
+ ```typescript
1021
+ // Change owner
1022
+ await wa.newsletter.changeOwner(channelId, 'senderId');
1023
+
1024
+ // Demote admin
1025
+ await wa.newsletter.demote(channelId, 'senderId');
1026
+
1027
+ // Delete channel
1028
+ await wa.newsletter.delete(channelId);
1029
+ ```
1030
+
1031
+ ## ๐ŸŒ Community Management
1032
+
1033
+ Create and manage WhatsApp Communities.
1034
+
1035
+ > **Quick Jump:** [Create](#create-community) ยท [Create Group](#create-group-in-community) ยท [Groups](#manage-groups) ยท [Info](#community-info) ยท [Participants](#manage-participants-1) ยท [Invite](#invite-code-1) ยท [Settings](#community-settings) ยท [Leave](#leave-community)
1036
+
1037
+ ### Create Community
1038
+
1039
+ ```typescript
1040
+ const community = await wa.community.create('My Community', 'Description here');
1041
+ console.log('Community created:', community);
1042
+ ```
1043
+
1044
+ ### Create Group in Community
1045
+
1046
+ Create a new group linked to a community.
1047
+
1048
+ ```typescript
1049
+ const communityId = '1234567890@g.us';
1050
+ const group = await wa.community.createGroup('New Group', ['senderId'], communityId);
1051
+ ```
1052
+
1053
+ ### Manage Groups
1054
+
1055
+ Link or unlink groups from a community.
1056
+
1057
+ ```typescript
1058
+ const groupId = '0987654321@g.us';
1059
+
1060
+ // Link group
1061
+ await wa.community.group(communityId, 'link', groupId);
1062
+
1063
+ // Unlink group
1064
+ await wa.community.group(communityId, 'unlink', groupId);
1065
+
1066
+ // Get linked groups
1067
+ const linkedGroups = await wa.community.group(communityId, 'linked');
1068
+ ```
1069
+
1070
+ ### Community Info
1071
+
1072
+ Get metadata or update info.
1073
+
1074
+ ```typescript
1075
+ // Get metadata
1076
+ const meta = await wa.community.metadata(communityId);
1077
+
1078
+ // Update subject
1079
+ await wa.community.update(communityId, 'subject', 'New Name');
1080
+
1081
+ // Update description
1082
+ await wa.community.update(communityId, 'description', 'New Description');
1083
+ ```
1084
+
1085
+ ### Manage Participants
1086
+
1087
+ Manage community participants.
1088
+
1089
+ ```typescript
1090
+ // List participants
1091
+ const participants = await wa.community.participants(communityId, 'list');
1092
+
1093
+ // Add participant
1094
+ await wa.community.participants(communityId, 'update', 'add', ['senderId']);
1095
+
1096
+ // Remove participant
1097
+ await wa.community.participants(communityId, 'update', 'remove', ['senderId']);
1098
+
1099
+ // Promote to admin
1100
+ await wa.community.participants(communityId, 'update', 'promote', ['senderId']);
1101
+
1102
+ // Demote to member
1103
+ await wa.community.participants(communityId, 'update', 'demote', ['senderId']);
1104
+ ```
1105
+
1106
+ ### Invite Code
1107
+
1108
+ Manage community invite links.
1109
+
1110
+ ```typescript
1111
+ // Get invite code
1112
+ const code = await wa.community.invite(communityId, 'code');
1113
+
1114
+ // Revoke invite code
1115
+ await wa.community.invite(communityId, 'revoke');
1116
+
1117
+ // Get invite info
1118
+ const info = await wa.community.invite('INVITE_CODE', 'info');
1119
+
1120
+ // Join via invite code
1121
+ await wa.community.invite('INVITE_CODE', 'accept');
1122
+ ```
1123
+
1124
+ ### Community Settings
1125
+
1126
+ Configure community settings.
1127
+
1128
+ ```typescript
1129
+ // Toggle ephemeral messages
1130
+ await wa.community.settings(communityId, 'ephemeral', 86400); // 24 hours
1131
+
1132
+ // Who can add members? 'all_member_add' or 'admin_add'
1133
+ await wa.community.settings(communityId, 'memberAdd', 'admin_add');
1134
+
1135
+ // Join approval mode? 'on' or 'off'
1136
+ await wa.community.settings(communityId, 'approval', 'on');
1137
+ ```
1138
+
1139
+ ### Leave Community
1140
+
1141
+ Leave a community.
1142
+
1143
+ ```typescript
1144
+ await wa.community.leave(communityId);
1145
+ ```
1146
+
1147
+ ## ๐Ÿ”’ Privacy Settings
1148
+
1149
+ Manage your privacy settings and block list.
1150
+
1151
+ > **Quick Jump:** [Block/Unblock](#blockunblock) ยท [Configuration](#privacy-configuration) ยท [Get Settings](#get-settings)
1152
+
1153
+ ### Block/Unblock
1154
+
1155
+ ```typescript
1156
+ // Block user
1157
+ await wa.privacy.block('senderId');
1158
+
1159
+ // Unblock user
1160
+ await wa.privacy.unblock('senderId');
1161
+
1162
+ // Get blocklist
1163
+ const blocklist = await wa.privacy.blocklist();
1164
+ ```
1165
+
1166
+ ### Privacy Configuration
1167
+
1168
+ Update privacy settings.
1169
+
1170
+ ```typescript
1171
+ // Last Seen: 'all', 'contacts', 'contact_blacklist', 'none'
1172
+ await wa.privacy.lastSeen('contacts');
1173
+
1174
+ // Online: 'all', 'match_last_seen'
1175
+ await wa.privacy.online('match_last_seen');
1176
+
1177
+ // Profile Picture: 'all', 'contacts', 'contact_blacklist', 'none'
1178
+ await wa.privacy.picture('all');
1179
+
1180
+ // Status: 'all', 'contacts', 'contact_blacklist', 'none'
1181
+ await wa.privacy.status('contacts');
1182
+
1183
+ // Read Receipts: 'all', 'none'
1184
+ await wa.privacy.readReceipt('all');
1185
+
1186
+ // Group Add: 'all', 'contacts', 'contact_blacklist', 'none'
1187
+ await wa.privacy.groupsAdd('contacts');
1188
+
1189
+ // Default Disappearing Mode: 'off', '24h', '7d', '90d'
1190
+ await wa.privacy.ephemeral('90d');
1191
+ ```
1192
+
1193
+ ### Get Settings
1194
+
1195
+ Fetch current privacy settings.
1196
+
1197
+ ```typescript
1198
+ const settings = await wa.privacy.getSettings();
1199
+ console.log(settings);
1200
+ ```
1201
+
1202
+ ## ๐Ÿค Contributing
1203
+
1204
+ Contributions are welcome! Please follow these steps:
1205
+
1206
+ 1. Fork the repository.
1207
+ 2. Create new branch: `git checkout -b feature/my-feature`.
1208
+ 3. Commit your changes: `git commit -m 'Add some feature'`.
1209
+ 4. Push to the branch: `git push origin feature/my-feature`.
1210
+ 5. Open Pull Request.
1211
+
1212
+ ## ๐ŸŽฏ Issues & Feedback
1213
+
1214
+ **If you encounter any problems or have feature requests, please open an [issue](https://github.com/zeative/zaileys/issues)**
1215
+
1216
+ - [Buy me coffee โ˜•](https://saweria.co/zaadevofc)
1217
+ - [Ko-Fi](https://ko-fi.com/zaadevofc)
1218
+ - [Trakteer](https://trakteer.id/zaadevofc)
1219
+ - โญ Star the repo on GitHub
1220
+
1221
+ ## ๐Ÿ“œ License
1222
+
1223
+ Distributed under the **MIT License**. See [`LICENSE`](https://github.com/zeative/zaileys/blob/main/LICENSE) for details.
1224
+
1225
+ <div align="left">
1226
+ <p>
1227
+ <img alt="Zaileys - Simplified WhatsApp Node.js TypeScript/JavaScript API" src="https://github.com/zeative/zeative/blob/main/libraries/zaileys/zaileys-clean.png?raw=true" width="28" align="center">
1228
+ Copyright ยฉ 2025 zaadevofc. All rights reserved.
1229
+ </p>
1230
+ </div>