wa-multi-mongodb 3.9.1 → 3.9.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Socket/index.ts"],"names":[],"mappings":"AAAA,OAAqB,EAInB,QAAQ,EACT,MAAM,SAAS,CAAC;AAIjB,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iCAAiC,EAClC,MAAM,UAAU,CAAC;AA6BlB;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,kBAe5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,GAAG,QAEjD;AAkBD,eAAO,MAAM,YAAY,GACvB,kBAAuB,EACvB,UAAS,kBAAsC,KAC9C,OAAO,CAAC,QAAQ,CA2FlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GACtC,WAAW,MAAM,EACjB,SAAS,iCAAiC,KACzC,OAAO,CAAC,QAAQ,CA8FlB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,iCAxMf,kBAAkB,KAC1B,OAAO,CAAC,QAAQ,CAuMsB,CAAC;AAE1C,eAAO,MAAM,aAAa,GAAU,WAAW,MAAM,kBA0BpD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,EAAE,CAsBtD,CAAC;AAGF,eAAO,MAAM,iBAAiB,QAAO,MAAM,EAAiC,CAAC;AAE7E,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,QAAQ,GAAG,SACrB,CAAC;AAoChC;;GAEG;AACH,eAAO,MAAM,uBAAuB,YAMnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,CAAC,GAAG,EAAE,eAAe,KAAK,GAAG,SAExE,CAAC;AACF,eAAO,MAAM,WAAW,GACtB,UAAU,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAAK,GAAG,SAGxE,CAAC;AACF,eAAO,MAAM,WAAW,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAE/D,CAAC;AACF,eAAO,MAAM,cAAc,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAElE,CAAC;AACF,eAAO,MAAM,YAAY,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAEhE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,UAAU,CAAC,IAAI,EAAE,cAAc,KAAK,GAAG,SAEtE,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,GAAG,SAGnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,qBAcjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,SAAQ,MAAqB,EAAE,iBAAgB,MAAe,SAI7F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAS,MAAyB,SAGnE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,OAAO,CAsDlE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Socket/index.ts"],"names":[],"mappings":"AAAA,OAAqB,EAInB,QAAQ,EACT,MAAM,SAAS,CAAC;AAKjB,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iCAAiC,EAClC,MAAM,UAAU,CAAC;AA6BlB;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,kBAe5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,GAAG,QAEjD;AAkBD,eAAO,MAAM,YAAY,GACvB,kBAAuB,EACvB,UAAS,kBAAsC,KAC9C,OAAO,CAAC,QAAQ,CAsGlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GACtC,WAAW,MAAM,EACjB,SAAS,iCAAiC,KACzC,OAAO,CAAC,QAAQ,CAuGlB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,iCA5Nf,kBAAkB,KAC1B,OAAO,CAAC,QAAQ,CA2NsB,CAAC;AAE1C,eAAO,MAAM,aAAa,GAAU,WAAW,MAAM,kBA0BpD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,EAAE,CAsBtD,CAAC;AAGF,eAAO,MAAM,iBAAiB,QAAO,MAAM,EAAiC,CAAC;AAE7E,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,QAAQ,GAAG,SACrB,CAAC;AAoChC;;GAEG;AACH,eAAO,MAAM,uBAAuB,YAMnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,UAAU,CAAC,GAAG,EAAE,eAAe,KAAK,GAAG,SAExE,CAAC;AACF,eAAO,MAAM,WAAW,GACtB,UAAU,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAAK,GAAG,SAGxE,CAAC;AACF,eAAO,MAAM,WAAW,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAE/D,CAAC;AACF,eAAO,MAAM,cAAc,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAElE,CAAC;AACF,eAAO,MAAM,YAAY,GAAI,UAAU,CAAC,SAAS,EAAE,MAAM,KAAK,GAAG,SAEhE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,UAAU,CAAC,IAAI,EAAE,cAAc,KAAK,GAAG,SAEtE,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,GAAG,SAGnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,qBAcjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,SAAQ,MAAqB,EAAE,iBAAgB,MAAe,SAI7F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAS,MAAyB,SAGnE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,OAAO,CAsDlE,CAAC"}
@@ -50,6 +50,7 @@ exports.setMongoCollection = setMongoCollection;
50
50
  const baileys_1 = __importStar(require("baileys"));
51
51
  const path_1 = __importDefault(require("path"));
52
52
  const fs_1 = __importDefault(require("fs"));
53
+ const qrcode_1 = __importDefault(require("qrcode"));
53
54
  const Defaults_1 = require("../Defaults");
54
55
  const save_media_1 = require("../Utils/save-media");
55
56
  const Error_1 = require("../Error");
@@ -116,7 +117,6 @@ const startSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, funct
116
117
  const { state, saveCreds } = yield (0, mongo_auth_state_1.useMongoAuthState)(sessionId, authCollection);
117
118
  const sock = (0, baileys_1.default)({
118
119
  version,
119
- printQRInTerminal: options.printQR,
120
120
  auth: state,
121
121
  logger: P,
122
122
  markOnlineOnConnect: false,
@@ -130,6 +130,17 @@ const startSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, funct
130
130
  const update = events["connection.update"];
131
131
  const { connection, lastDisconnect } = update;
132
132
  if (update.qr) {
133
+ if (options.printQR) {
134
+ qrcode_1.default.toString(update.qr, {
135
+ type: 'terminal',
136
+ small: true,
137
+ margin: 1
138
+ }, (err, qrString) => {
139
+ if (!err) {
140
+ console.log(qrString);
141
+ }
142
+ });
143
+ }
133
144
  (_a = callback.get(Defaults_1.CALLBACK_KEY.ON_QR)) === null || _a === void 0 ? void 0 : _a({
134
145
  sessionId,
135
146
  qr: update.qr,
@@ -210,7 +221,6 @@ const startSessionWithPairingCode = (sessionId, options) => __awaiter(void 0, vo
210
221
  const { state, saveCreds } = yield (0, mongo_auth_state_1.useMongoAuthState)(sessionId, authCollection);
211
222
  const sock = (0, baileys_1.default)({
212
223
  version,
213
- printQRInTerminal: false,
214
224
  auth: state,
215
225
  logger: P,
216
226
  markOnlineOnConnect: false,
@@ -230,6 +240,15 @@ const startSessionWithPairingCode = (sessionId, options) => __awaiter(void 0, vo
230
240
  const update = events["connection.update"];
231
241
  const { connection, lastDisconnect } = update;
232
242
  if (update.qr) {
243
+ qrcode_1.default.toString(update.qr, {
244
+ type: 'terminal',
245
+ small: true,
246
+ margin: 1
247
+ }, (err, qrString) => {
248
+ if (!err) {
249
+ console.log(qrString);
250
+ }
251
+ });
233
252
  (_a = callback.get(Defaults_1.CALLBACK_KEY.ON_QR)) === null || _a === void 0 ? void 0 : _a({
234
253
  sessionId,
235
254
  qr: update.qr,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wa-multi-mongodb",
3
- "version": "3.9.1",
3
+ "version": "3.9.3",
4
4
  "description": "Multi Session Whatsapp Library with MongoDB Integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,12 +17,14 @@
17
17
  "dependencies": {
18
18
  "@adiwajshing/keyed-db": "^0.2.4",
19
19
  "@hapi/boom": "^10.0.1",
20
- "baileys": "^6.7.16",
20
+ "@types/qrcode": "^1.5.5",
21
+ "baileys": "^6.7.17",
21
22
  "dotenv": "^16.5.0",
22
23
  "link-preview-js": "^3.0.14",
23
24
  "mime": "^3.0.0",
24
25
  "mongodb": "^5.7.0",
25
26
  "pino": "^9.5.0",
27
+ "qrcode": "^1.5.4",
26
28
  "qrcode-terminal": "^0.12.0"
27
29
  },
28
30
  "repository": {
package/readme.md CHANGED
@@ -1,444 +1,454 @@
1
- # WhatsApp Multi MongoDB - Multi Session WhatsApp with MongoDB
2
-
3
- ## ⚠️ Important Note
4
- This repository is a modified version of [@mimamch/wa-multi-session](https://github.com/mimamch/wa-multi-session) with MongoDB session management integration. The original repository uses file-based session storage, while this version uses MongoDB for better scalability and session management.
5
-
6
- Lightweight library for WhatsApp with MongoDB integration. No Selenium or browser required.
7
-
8
- Built on [Baileys](https://github.com/WhiskeySockets/Baileys) Library.
9
-
10
- ## Features
11
- - Multi-session WhatsApp (multiple numbers simultaneously)
12
- - State (auth) storage in MongoDB instead of files
13
- - Automatic loading of all sessions from the database at startup
14
- - No need to scan QR again as long as MongoDB data is preserved
15
- - Automatic timeout handling for long-running operations
16
- - Auto-reconnect when connection is lost
17
- - Better group chat support
18
- - Automatic retry for failed message deliveries
19
- - Automatic group chat detection (v3.9.0+)
20
-
21
- ## Installation
22
-
23
- Install package using npm:
24
-
25
- ```bash
26
- npm install wa-multi-mongodb@latest
27
- ```
28
-
29
- Then import into your code:
30
-
31
- ```typescript
32
- // Using ES modules
33
- import * as whatsapp from "wa-multi-mongodb";
34
-
35
- // Or using CommonJS
36
- const whatsapp = require("wa-multi-mongodb");
37
- ```
38
-
39
- ## Environment Setup
40
-
41
- For secure MongoDB URI management, we recommend using environment variables:
42
-
43
- 1. Create a `.env` file in your project root (copy from `.env.example`):
44
- ```
45
- # MongoDB Configuration
46
- MONGODB_URI=mongodb://username:password@hostname:port/database
47
-
48
- # Optional database settings
49
- WA_DB_NAME=wa_session
50
- WA_COLLECTION_NAME=auth
51
- ```
52
-
53
- 2. Install and use the dotenv package:
54
- ```javascript
55
- // Load environment variables
56
- require('dotenv').config();
57
-
58
- // Use in your code
59
- const MONGODB_URI = process.env.MONGODB_URI;
60
- if (!MONGODB_URI) {
61
- console.error('Error: MONGODB_URI not found in environment variables');
62
- process.exit(1);
63
- }
64
-
65
- // Initialize WhatsApp with MongoDB
66
- await whatsapp.setMongoURI(MONGODB_URI);
67
- ```
68
-
69
- 3. Make sure to add `.env` to your `.gitignore` file to prevent exposing sensitive credentials
70
-
71
- ## MongoDB Configuration
72
-
73
- ### Setup MongoDB Connection
74
- 1. Make sure MongoDB is running (local/cloud)
75
- 2. Configure the connection using one of these methods:
76
-
77
- **Using environment variables (recommended):**
78
- ```javascript
79
- require('dotenv').config();
80
- await whatsapp.setMongoURI(process.env.MONGODB_URI);
81
- ```
82
-
83
- **Directly in code (not recommended for production):**
84
- ```javascript
85
- await whatsapp.setMongoURI("mongodb+srv://username:password@host/db?options");
86
- ```
87
-
88
- 3. Optionally customize the database and collection names:
89
- ```javascript
90
- // Default values are "wa_session" and "auth"
91
- whatsapp.setMongoDBNames("custom_database_name", "custom_collection_name");
92
- ```
93
-
94
- ## Basic Usage
95
-
96
- ### Session Management
97
-
98
- ```javascript
99
- // Start a new session
100
- const session = await whatsapp.startSession("mysession");
101
-
102
- // Start with options
103
- await whatsapp.startSession("mysession2", {
104
- printQR: true,
105
- onConnected: () => console.log("Connected!"),
106
- onDisconnected: () => console.log("Disconnected!"),
107
- onQRUpdated: (qr) => console.log("New QR:", qr)
108
- });
109
-
110
- // Get all active sessions
111
- const sessions = await whatsapp.getAllSession();
112
-
113
- // Get data for a specific session
114
- const sessionData = whatsapp.getSession("mysession");
115
-
116
- // Load all saved sessions from MongoDB
117
- await whatsapp.loadSessionsFromMongo();
118
- ```
119
-
120
- ### Sending Messages
121
-
122
- ```javascript
123
- // Send text message
124
- await whatsapp.sendTextMessage({
125
- sessionId: "mysession",
126
- to: "6281234567890", // always include country code
127
- text: "Hello from wa-multi-mongodb!"
128
- // isGroup parameter is optional (v3.9.0+)
129
- // The library will automatically detect if the destination is a group
130
- });
131
-
132
- // Send to a group (automatic detection in v3.9.0+)
133
- await whatsapp.sendTextMessage({
134
- sessionId: "mysession",
135
- to: "120363152682073800", // group ID
136
- text: "Hello group!"
137
- // No need for isGroup: true parameter in v3.9.0+
138
- });
139
-
140
- // Send to a group (compatible with older versions)
141
- await whatsapp.sendTextMessage({
142
- sessionId: "mysession",
143
- to: "120363152682073800", // group ID
144
- text: "Hello group!",
145
- isGroup: true // still works but optional in v3.9.0+
146
- });
147
-
148
- // Send media (unified function)
149
- await whatsapp.sendMedia({
150
- sessionId: "mysession",
151
- to: "6281234567890",
152
- type: "image", // options: image, video, pdf, doc, docx, xls, xlsx, zip, mp3
153
- media: fs.readFileSync("./image.jpg"), // or URL string
154
- caption: "Image caption",
155
- fileName: "image.jpg", // required for documents
156
- // isGroup parameter is optional (v3.9.0+)
157
- });
158
-
159
- // Send voice note
160
- await whatsapp.sendVoiceNote({
161
- sessionId: "mysession",
162
- to: "6281234567890",
163
- media: fs.readFileSync("./audio.mp3"),
164
- // isGroup parameter is optional (v3.9.0+)
165
- });
166
-
167
- // Mark message as read
168
- await whatsapp.readMessage({
169
- sessionId: "mysession",
170
- key: msg.key,
171
- });
172
-
173
- // Send typing indicator
174
- await whatsapp.sendTyping({
175
- sessionId: "mysession",
176
- to: "6281234567890", // or group ID
177
- duration: 3000, // milliseconds
178
- // isGroup parameter is optional (v3.9.0+)
179
- });
180
- ```
181
-
182
- ### Event Listeners
183
-
184
- ```javascript
185
- // Incoming messages
186
- whatsapp.onMessageReceived((msg) => {
187
- console.log(`Message from ${msg.key.remoteJid}:`, msg);
188
- });
189
-
190
- // QR code updates
191
- whatsapp.onQRUpdated(({ sessionId, qr }) => {
192
- console.log(`QR Code for ${sessionId}:`, qr);
193
- // You can display this QR in a UI or save it to a file
194
- });
195
-
196
- // Connection events
197
- whatsapp.onConnected((sessionId) => {
198
- console.log(`Session ${sessionId} connected`);
199
- });
200
-
201
- whatsapp.onDisconnected((sessionId) => {
202
- console.log(`Session ${sessionId} disconnected`);
203
- });
204
- ```
205
-
206
- ### Handling Media in Incoming Messages
207
-
208
- ```javascript
209
- whatsapp.onMessageReceived(async (msg) => {
210
- if (msg.message?.imageMessage) {
211
- await msg.saveImage("./saved-image.jpg");
212
- }
213
-
214
- if (msg.message?.videoMessage) {
215
- await msg.saveVideo("./saved-video.mp4");
216
- }
217
-
218
- if (msg.message?.documentMessage) {
219
- await msg.saveDocument("./saved-document"); // extension will be added automatically
220
- }
221
-
222
- if (msg.message?.audioMessage) {
223
- await msg.saveAudio("./saved-audio.mp3");
224
- }
225
- });
226
- ```
227
-
228
- ## Utility Functions
229
-
230
- ```javascript
231
- // Create a delay
232
- import { createDelay } from "wa-multi-mongodb";
233
- await createDelay(2000); // wait 2 seconds
234
-
235
- // Execute with timeout
236
- import { withTimeout } from "wa-multi-mongodb";
237
- try {
238
- const result = await withTimeout(
239
- functionThatMightTakeTooLong(),
240
- 10000, // timeout in ms
241
- "Operation timed out" // error message if timeout occurs
242
- );
243
- } catch (error) {
244
- console.error(error.message);
245
- }
246
-
247
- // Attempt to reconnect a session
248
- import { reconnect } from "wa-multi-mongodb";
249
- try {
250
- const reconnected = await reconnect("mysession");
251
- console.log("Reconnect successful:", reconnected);
252
- } catch (error) {
253
- console.error("Reconnect failed:", error);
254
- }
255
- ```
256
-
257
- ## Complete Example: Auto-Reconnect Application
258
-
259
- ```javascript
260
- import * as whatsapp from "wa-multi-mongodb";
261
- import { withTimeout } from "wa-multi-mongodb";
262
- require('dotenv').config();
263
-
264
- // Store connection status
265
- const sessionStatus = {};
266
-
267
- // Function to check and reconnect if disconnected
268
- async function checkAndReconnect(sessionId) {
269
- if (sessionStatus[sessionId] === 'disconnected') {
270
- try {
271
- const reconnected = await whatsapp.reconnect(sessionId);
272
- if (reconnected) {
273
- sessionStatus[sessionId] = 'connected';
274
- console.log(`Session ${sessionId} reconnected`);
275
- }
276
- } catch (error) {
277
- console.error(`Error during reconnect: ${error.message}`);
278
- }
279
- }
280
- }
281
-
282
- async function startApp() {
283
- // MongoDB Configuration
284
- await whatsapp.setMongoURI(process.env.MONGODB_URI);
285
-
286
- // Event listeners
287
- whatsapp.onQRUpdated(({ sessionId, qr }) => {
288
- console.log(`QR Code for session ${sessionId}:`, qr);
289
- });
290
-
291
- whatsapp.onConnected((sessionId) => {
292
- console.log(`Session ${sessionId} connected!`);
293
- sessionStatus[sessionId] = 'connected';
294
- });
295
-
296
- whatsapp.onDisconnected((sessionId) => {
297
- console.log(`Session ${sessionId} disconnected!`);
298
- sessionStatus[sessionId] = 'disconnected';
299
-
300
- // Try to reconnect after a few seconds
301
- setTimeout(() => checkAndReconnect(sessionId), 10000);
302
- });
303
-
304
- // Message handler with error handling and group detection
305
- whatsapp.onMessageReceived(async (msg) => {
306
- try {
307
- if (msg.key.fromMe || msg.key.remoteJid.includes("status")) return;
308
-
309
- const messageContent = msg.message?.conversation ||
310
- msg.message?.extendedTextMessage?.text ||
311
- "";
312
-
313
- // Detect if message is from a group
314
- const isGroup = msg.key.remoteJid.endsWith('@g.us');
315
-
316
- // Mark message as read
317
- try {
318
- await whatsapp.readMessage({
319
- sessionId: msg.sessionId,
320
- key: msg.key,
321
- });
322
- } catch (error) {
323
- if (error.message.includes('Connection Closed')) {
324
- sessionStatus[msg.sessionId] = 'disconnected';
325
- setTimeout(() => checkAndReconnect(msg.sessionId), 5000);
326
- }
327
- }
328
-
329
- // Reply to messages containing "hello"
330
- if (messageContent.toLowerCase().includes("hello")) {
331
- // Show typing indicator (works in both private and group chats since v3.9.1+)
332
- await whatsapp.sendTyping({
333
- sessionId: msg.sessionId,
334
- to: msg.key.remoteJid,
335
- duration: 2000,
336
- });
337
-
338
- // Use different timeouts for groups vs private chats
339
- const timeoutMs = isGroup ? 60000 : 30000;
340
-
341
- try {
342
- await withTimeout(
343
- whatsapp.sendTextMessage({
344
- sessionId: msg.sessionId,
345
- to: msg.key.remoteJid,
346
- text: "Hello! How can I help you?",
347
- answering: msg,
348
- // isGroup parameter is optional (v3.9.0+)
349
- }),
350
- timeoutMs,
351
- "Message sending timed out"
352
- );
353
- } catch (error) {
354
- console.error("Error sending message:", error.message);
355
- }
356
- }
357
- } catch (error) {
358
- // Prevent application crash
359
- console.error("Error processing message:", error.message);
360
- }
361
- });
362
-
363
- // Load all sessions from MongoDB
364
- await whatsapp.loadSessionsFromMongo();
365
-
366
- // Create a main session if it doesn't exist
367
- const mainSession = "main_session";
368
- const existingSessions = await whatsapp.getAllSession();
369
- if (!existingSessions.includes(mainSession)) {
370
- await whatsapp.startSession(mainSession);
371
- } else {
372
- sessionStatus[mainSession] = 'connected';
373
- }
374
-
375
- // Check connections periodically
376
- setInterval(() => {
377
- Object.keys(sessionStatus).forEach(sid => {
378
- checkAndReconnect(sid);
379
- });
380
- }, 5 * 60 * 1000); // check every 5 minutes
381
- }
382
-
383
- startApp().catch(err => {
384
- console.error("Failed to start application:", err);
385
- process.exit(1);
386
- });
387
- ```
388
-
389
- ## Best Practices for Group Chats
390
-
391
- 1. **Auto Group Detection**: Since v3.9.0, the library automatically detects if a chat is a group based on its JID format
392
- 2. **Typing Indicators**: Typing indicators now work in both private and group chats (v3.9.1+)
393
- 3. **Longer Timeouts**: Use longer timeouts when sending media to groups (60+ seconds)
394
- 4. **Handle Errors**: Implement retry mechanisms for failed group messages
395
- 5. **Announcement Channels**: Groups with announcement channels may trigger `MessageCounterError` (handled automatically in v3.9.1+)
396
- 6. **Retry Strategy**: For announcement channel groups, the library will automatically retry sending messages up to 3 times with increasing delays
397
-
398
- ## WhatsApp Limitations
399
-
400
- 1. **Media Transfer**: Large media files to groups may take longer or timeout
401
- 2. **Connection Stability**: Auto-reconnect may be needed in production apps
402
- 3. **Announcement Channels**: Some groups with announcement channels may still fail after multiple retries
403
-
404
- ## Changelog
405
-
406
- ### v3.9.1 (Current)
407
- - Added special handling for `MessageCounterError` in group chats with announcement channels
408
- - Implemented automatic retry mechanism for messages to announcement channels
409
- - Enhanced error reporting for group chat issues
410
- - Fixed typing indicators to work properly in group chats
411
- - Added automatic group chat detection - no need to specify `isGroup: true` parameter
412
- - Improved message sending reliability for group chats
413
- - Enhanced error handling with better timeout management
414
- - Implemented automatic format detection for group IDs
415
-
416
- ### v3.8.1
417
- - Updated baileys to v6.7.16
418
- - Improved MongoDB integration
419
- - Enhanced error handling and connection stability
420
-
421
- ### v3.8.0
422
- - Package renamed from wa-multi-session to wa-multi-mongodb
423
- - Added MongoDB session management
424
- - Fixed connection and authentication issues
425
-
426
- ### v3.7.0
427
- - Upgraded to baileys v6.7.9
428
- - Fixed phone number validation
429
- - Removed registered phone number validation requirement
430
-
431
- ## Links
432
-
433
- - [GitHub Repository](https://github.com/wahdalo/wa-multi-mongodb)
434
- - [Issue Tracker](https://github.com/wahdalo/wa-multi-mongodb/issues)
435
- - [Original wa-multi-session](https://github.com/mimamch/wa-multi-session)
436
- - [Baileys Library](https://github.com/WhiskeySockets/Baileys)
437
-
438
- ## Author
439
-
440
- - [@wahdalo](https://github.com/wahdalo)
441
-
442
- ## License
443
-
444
- ISC
1
+ # WhatsApp Multi MongoDB - Multi Session WhatsApp with MongoDB
2
+
3
+ ## ⚠️ Important Note
4
+ This repository is a modified version of [@mimamch/wa-multi-session](https://github.com/mimamch/wa-multi-session) with MongoDB session management integration. The original repository uses file-based session storage, while this version uses MongoDB for better scalability and session management.
5
+
6
+ Lightweight library for WhatsApp with MongoDB integration. No Selenium or browser required.
7
+
8
+ Built on [Baileys](https://github.com/WhiskeySockets/Baileys) Library.
9
+
10
+ ## Features
11
+ - Multi-session WhatsApp (multiple numbers simultaneously)
12
+ - State (auth) storage in MongoDB instead of files
13
+ - Automatic loading of all sessions from the database at startup
14
+ - No need to scan QR again as long as MongoDB data is preserved
15
+ - Automatic timeout handling for long-running operations
16
+ - Auto-reconnect when connection is lost
17
+ - Better group chat support
18
+ - Automatic retry for failed message deliveries
19
+ - Automatic group chat detection (v3.9.0+)
20
+
21
+ ## Installation
22
+
23
+ Install package using npm:
24
+
25
+ ```bash
26
+ npm install wa-multi-mongodb@latest
27
+ ```
28
+
29
+ Then import into your code:
30
+
31
+ ```typescript
32
+ // Using ES modules
33
+ import * as whatsapp from "wa-multi-mongodb";
34
+
35
+ // Or using CommonJS
36
+ const whatsapp = require("wa-multi-mongodb");
37
+ ```
38
+
39
+ ## Environment Setup
40
+
41
+ For secure MongoDB URI management, we recommend using environment variables:
42
+
43
+ 1. Create a `.env` file in your project root (copy from `.env.example`):
44
+ ```
45
+ # MongoDB Configuration
46
+ MONGODB_URI=mongodb://username:password@hostname:port/database
47
+
48
+ # Optional database settings
49
+ WA_DB_NAME=wa_session
50
+ WA_COLLECTION_NAME=auth
51
+ ```
52
+
53
+ 2. Install and use the dotenv package:
54
+ ```javascript
55
+ // Load environment variables
56
+ require('dotenv').config();
57
+
58
+ // Use in your code
59
+ const MONGODB_URI = process.env.MONGODB_URI;
60
+ if (!MONGODB_URI) {
61
+ console.error('Error: MONGODB_URI not found in environment variables');
62
+ process.exit(1);
63
+ }
64
+
65
+ // Initialize WhatsApp with MongoDB
66
+ await whatsapp.setMongoURI(MONGODB_URI);
67
+ ```
68
+
69
+ 3. Make sure to add `.env` to your `.gitignore` file to prevent exposing sensitive credentials
70
+
71
+ ## MongoDB Configuration
72
+
73
+ ### Setup MongoDB Connection
74
+ 1. Make sure MongoDB is running (local/cloud)
75
+ 2. Configure the connection using one of these methods:
76
+
77
+ **Using environment variables (recommended):**
78
+ ```javascript
79
+ require('dotenv').config();
80
+ await whatsapp.setMongoURI(process.env.MONGODB_URI);
81
+ ```
82
+
83
+ **Directly in code (not recommended for production):**
84
+ ```javascript
85
+ await whatsapp.setMongoURI("mongodb+srv://username:password@host/db?options");
86
+ ```
87
+
88
+ 3. Optionally customize the database and collection names:
89
+ ```javascript
90
+ // Default values are "wa_session" and "auth"
91
+ whatsapp.setMongoDBNames("custom_database_name", "custom_collection_name");
92
+ ```
93
+
94
+ ## Basic Usage
95
+
96
+ ### Session Management
97
+
98
+ ```javascript
99
+ // Start a new session
100
+ const session = await whatsapp.startSession("mysession");
101
+
102
+ // Start with options
103
+ await whatsapp.startSession("mysession2", {
104
+ printQR: true,
105
+ onConnected: () => console.log("Connected!"),
106
+ onDisconnected: () => console.log("Disconnected!"),
107
+ onQRUpdated: (qr) => console.log("New QR:", qr)
108
+ });
109
+
110
+ // Get all active sessions
111
+ const sessions = await whatsapp.getAllSession();
112
+
113
+ // Get data for a specific session
114
+ const sessionData = whatsapp.getSession("mysession");
115
+
116
+ // Load all saved sessions from MongoDB
117
+ await whatsapp.loadSessionsFromMongo();
118
+ ```
119
+
120
+ ### Sending Messages
121
+
122
+ ```javascript
123
+ // Send text message
124
+ await whatsapp.sendTextMessage({
125
+ sessionId: "mysession",
126
+ to: "6281234567890", // always include country code
127
+ text: "Hello from wa-multi-mongodb!"
128
+ // isGroup parameter is optional (v3.9.0+)
129
+ // The library will automatically detect if the destination is a group
130
+ });
131
+
132
+ // Send to a group (automatic detection in v3.9.0+)
133
+ await whatsapp.sendTextMessage({
134
+ sessionId: "mysession",
135
+ to: "120363152682073800", // group ID
136
+ text: "Hello group!"
137
+ // No need for isGroup: true parameter in v3.9.0+
138
+ });
139
+
140
+ // Send to a group (compatible with older versions)
141
+ await whatsapp.sendTextMessage({
142
+ sessionId: "mysession",
143
+ to: "120363152682073800", // group ID
144
+ text: "Hello group!",
145
+ isGroup: true // still works but optional in v3.9.0+
146
+ });
147
+
148
+ // Send media (unified function)
149
+ await whatsapp.sendMedia({
150
+ sessionId: "mysession",
151
+ to: "6281234567890",
152
+ type: "image", // options: image, video, pdf, doc, docx, xls, xlsx, zip, mp3
153
+ media: fs.readFileSync("./image.jpg"), // or URL string
154
+ caption: "Image caption",
155
+ fileName: "image.jpg", // required for documents
156
+ // isGroup parameter is optional (v3.9.0+)
157
+ });
158
+
159
+ // Send voice note
160
+ await whatsapp.sendVoiceNote({
161
+ sessionId: "mysession",
162
+ to: "6281234567890",
163
+ media: fs.readFileSync("./audio.mp3"),
164
+ // isGroup parameter is optional (v3.9.0+)
165
+ });
166
+
167
+ // Mark message as read
168
+ await whatsapp.readMessage({
169
+ sessionId: "mysession",
170
+ key: msg.key,
171
+ });
172
+
173
+ // Send typing indicator
174
+ await whatsapp.sendTyping({
175
+ sessionId: "mysession",
176
+ to: "6281234567890", // or group ID
177
+ duration: 3000, // milliseconds
178
+ // isGroup parameter is optional (v3.9.0+)
179
+ });
180
+ ```
181
+
182
+ ### Event Listeners
183
+
184
+ ```javascript
185
+ // Incoming messages
186
+ whatsapp.onMessageReceived((msg) => {
187
+ console.log(`Message from ${msg.key.remoteJid}:`, msg);
188
+ });
189
+
190
+ // QR code updates
191
+ whatsapp.onQRUpdated(({ sessionId, qr }) => {
192
+ console.log(`QR Code for ${sessionId}:`, qr);
193
+ // You can display this QR in a UI or save it to a file
194
+ });
195
+
196
+ // Connection events
197
+ whatsapp.onConnected((sessionId) => {
198
+ console.log(`Session ${sessionId} connected`);
199
+ });
200
+
201
+ whatsapp.onDisconnected((sessionId) => {
202
+ console.log(`Session ${sessionId} disconnected`);
203
+ });
204
+ ```
205
+
206
+ ### Handling Media in Incoming Messages
207
+
208
+ ```javascript
209
+ whatsapp.onMessageReceived(async (msg) => {
210
+ if (msg.message?.imageMessage) {
211
+ await msg.saveImage("./saved-image.jpg");
212
+ }
213
+
214
+ if (msg.message?.videoMessage) {
215
+ await msg.saveVideo("./saved-video.mp4");
216
+ }
217
+
218
+ if (msg.message?.documentMessage) {
219
+ await msg.saveDocument("./saved-document"); // extension will be added automatically
220
+ }
221
+
222
+ if (msg.message?.audioMessage) {
223
+ await msg.saveAudio("./saved-audio.mp3");
224
+ }
225
+ });
226
+ ```
227
+
228
+ ## Utility Functions
229
+
230
+ ```javascript
231
+ // Create a delay
232
+ import { createDelay } from "wa-multi-mongodb";
233
+ await createDelay(2000); // wait 2 seconds
234
+
235
+ // Execute with timeout
236
+ import { withTimeout } from "wa-multi-mongodb";
237
+ try {
238
+ const result = await withTimeout(
239
+ functionThatMightTakeTooLong(),
240
+ 10000, // timeout in ms
241
+ "Operation timed out" // error message if timeout occurs
242
+ );
243
+ } catch (error) {
244
+ console.error(error.message);
245
+ }
246
+
247
+ // Attempt to reconnect a session
248
+ import { reconnect } from "wa-multi-mongodb";
249
+ try {
250
+ const reconnected = await reconnect("mysession");
251
+ console.log("Reconnect successful:", reconnected);
252
+ } catch (error) {
253
+ console.error("Reconnect failed:", error);
254
+ }
255
+ ```
256
+
257
+ ## Complete Example: Auto-Reconnect Application
258
+
259
+ ```javascript
260
+ import * as whatsapp from "wa-multi-mongodb";
261
+ import { withTimeout } from "wa-multi-mongodb";
262
+ require('dotenv').config();
263
+
264
+ // Store connection status
265
+ const sessionStatus = {};
266
+
267
+ // Function to check and reconnect if disconnected
268
+ async function checkAndReconnect(sessionId) {
269
+ if (sessionStatus[sessionId] === 'disconnected') {
270
+ try {
271
+ const reconnected = await whatsapp.reconnect(sessionId);
272
+ if (reconnected) {
273
+ sessionStatus[sessionId] = 'connected';
274
+ console.log(`Session ${sessionId} reconnected`);
275
+ }
276
+ } catch (error) {
277
+ console.error(`Error during reconnect: ${error.message}`);
278
+ }
279
+ }
280
+ }
281
+
282
+ async function startApp() {
283
+ // MongoDB Configuration
284
+ await whatsapp.setMongoURI(process.env.MONGODB_URI);
285
+
286
+ // Event listeners
287
+ whatsapp.onQRUpdated(({ sessionId, qr }) => {
288
+ console.log(`QR Code for session ${sessionId}:`, qr);
289
+ });
290
+
291
+ whatsapp.onConnected((sessionId) => {
292
+ console.log(`Session ${sessionId} connected!`);
293
+ sessionStatus[sessionId] = 'connected';
294
+ });
295
+
296
+ whatsapp.onDisconnected((sessionId) => {
297
+ console.log(`Session ${sessionId} disconnected!`);
298
+ sessionStatus[sessionId] = 'disconnected';
299
+
300
+ // Try to reconnect after a few seconds
301
+ setTimeout(() => checkAndReconnect(sessionId), 10000);
302
+ });
303
+
304
+ // Message handler with error handling and group detection
305
+ whatsapp.onMessageReceived(async (msg) => {
306
+ try {
307
+ if (msg.key.fromMe || msg.key.remoteJid.includes("status")) return;
308
+
309
+ const messageContent = msg.message?.conversation ||
310
+ msg.message?.extendedTextMessage?.text ||
311
+ "";
312
+
313
+ // Detect if message is from a group
314
+ const isGroup = msg.key.remoteJid.endsWith('@g.us');
315
+
316
+ // Mark message as read
317
+ try {
318
+ await whatsapp.readMessage({
319
+ sessionId: msg.sessionId,
320
+ key: msg.key,
321
+ });
322
+ } catch (error) {
323
+ if (error.message.includes('Connection Closed')) {
324
+ sessionStatus[msg.sessionId] = 'disconnected';
325
+ setTimeout(() => checkAndReconnect(msg.sessionId), 5000);
326
+ }
327
+ }
328
+
329
+ // Reply to messages containing "hello"
330
+ if (messageContent.toLowerCase().includes("hello")) {
331
+ // Show typing indicator (works in both private and group chats since v3.9.1+)
332
+ await whatsapp.sendTyping({
333
+ sessionId: msg.sessionId,
334
+ to: msg.key.remoteJid,
335
+ duration: 2000,
336
+ });
337
+
338
+ // Use different timeouts for groups vs private chats
339
+ const timeoutMs = isGroup ? 60000 : 30000;
340
+
341
+ try {
342
+ await withTimeout(
343
+ whatsapp.sendTextMessage({
344
+ sessionId: msg.sessionId,
345
+ to: msg.key.remoteJid,
346
+ text: "Hello! How can I help you?",
347
+ answering: msg,
348
+ // isGroup parameter is optional (v3.9.0+)
349
+ }),
350
+ timeoutMs,
351
+ "Message sending timed out"
352
+ );
353
+ } catch (error) {
354
+ console.error("Error sending message:", error.message);
355
+ }
356
+ }
357
+ } catch (error) {
358
+ // Prevent application crash
359
+ console.error("Error processing message:", error.message);
360
+ }
361
+ });
362
+
363
+ // Load all sessions from MongoDB
364
+ await whatsapp.loadSessionsFromMongo();
365
+
366
+ // Create a main session if it doesn't exist
367
+ const mainSession = "main_session";
368
+ const existingSessions = await whatsapp.getAllSession();
369
+ if (!existingSessions.includes(mainSession)) {
370
+ await whatsapp.startSession(mainSession);
371
+ } else {
372
+ sessionStatus[mainSession] = 'connected';
373
+ }
374
+
375
+ // Check connections periodically
376
+ setInterval(() => {
377
+ Object.keys(sessionStatus).forEach(sid => {
378
+ checkAndReconnect(sid);
379
+ });
380
+ }, 5 * 60 * 1000); // check every 5 minutes
381
+ }
382
+
383
+ startApp().catch(err => {
384
+ console.error("Failed to start application:", err);
385
+ process.exit(1);
386
+ });
387
+ ```
388
+
389
+ ## Best Practices for Group Chats
390
+
391
+ 1. **Auto Group Detection**: Since v3.9.0, the library automatically detects if a chat is a group based on its JID format
392
+ 2. **Typing Indicators**: Typing indicators now work in both private and group chats (v3.9.1+)
393
+ 3. **Longer Timeouts**: Use longer timeouts when sending media to groups (60+ seconds)
394
+ 4. **Handle Errors**: Implement retry mechanisms for failed group messages
395
+ 5. **Announcement Channels**: Groups with announcement channels may trigger `MessageCounterError` (handled automatically in v3.9.1+)
396
+ 6. **Retry Strategy**: For announcement channel groups, the library will automatically retry sending messages up to 3 times with increasing delays
397
+
398
+ ## WhatsApp Limitations
399
+
400
+ 1. **Media Transfer**: Large media files to groups may take longer or timeout
401
+ 2. **Connection Stability**: Auto-reconnect may be needed in production apps
402
+ 3. **Announcement Channels**: Some groups with announcement channels may still fail after multiple retries
403
+
404
+ ## Changelog
405
+
406
+ ### v3.9.3 (Current)
407
+ - Updated QR code implementation for better display in terminal
408
+ - Replaced deprecated `printQRInTerminal` option with `qrcode` library implementation
409
+ - Added support for latest Baileys version
410
+
411
+ ### v3.9.2
412
+ - Updated Baileys dependency to v6.7.17 for improved stability and compatibility
413
+
414
+ ### v3.9.1
415
+ - Added special handling for `MessageCounterError` in group chats with announcement channels
416
+ - Implemented automatic retry mechanism for messages to announcement channels
417
+ - Enhanced error reporting for group chat issues
418
+ - Fixed typing indicators to work properly in group chats
419
+
420
+ ### v3.9.0
421
+ - Added automatic group chat detection - no need to specify `isGroup: true` parameter
422
+ - Improved message sending reliability for group chats
423
+ - Enhanced error handling with better timeout management
424
+ - Implemented automatic format detection for group IDs
425
+
426
+ ### v3.8.1
427
+ - Updated baileys to v6.7.16
428
+ - Improved MongoDB integration
429
+ - Enhanced error handling and connection stability
430
+
431
+ ### v3.8.0
432
+ - Package renamed from wa-multi-session to wa-multi-mongodb
433
+ - Added MongoDB session management
434
+ - Fixed connection and authentication issues
435
+
436
+ ### v3.7.0
437
+ - Upgraded to baileys v6.7.9
438
+ - Fixed phone number validation
439
+ - Removed registered phone number validation requirement
440
+
441
+ ## Links
442
+
443
+ - [GitHub Repository](https://github.com/wahdalo/wa-multi-mongodb)
444
+ - [Issue Tracker](https://github.com/wahdalo/wa-multi-mongodb/issues)
445
+ - [Original wa-multi-session](https://github.com/mimamch/wa-multi-session)
446
+ - [Baileys Library](https://github.com/WhiskeySockets/Baileys)
447
+
448
+ ## Author
449
+
450
+ - [@wahdalo](https://github.com/wahdalo)
451
+
452
+ ## License
453
+
454
+ ISC