wa-multi-mongodb 3.9.5 → 3.9.6

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,5 +1,5 @@
1
1
  import { WASocket } from "baileys";
2
- import type { MessageReceived, MessageUpdated, StartSessionParams, StartSessionWithPairingCodeParams } from "../Types";
2
+ import type { MessageReceived, MessageUpdated, StartSessionParams } from "../Types";
3
3
  /**
4
4
  * Set MongoDB URI for connection
5
5
  * This function will be used to configure MongoDB connection with just the URI
@@ -10,10 +10,15 @@ export declare const setMongoURI: (uri: string) => Promise<void>;
10
10
  export declare function setMongoCollection(collection: any): void;
11
11
  export declare const startSession: (sessionId?: string, options?: StartSessionParams) => Promise<WASocket>;
12
12
  /**
13
+ * Start WhatsApp session using pairing code method
14
+ * This is the recommended way to create sessions with pairing code
13
15
  *
14
- * @deprecated Use startSession method instead
16
+ * @param sessionId Unique session identifier
17
+ * @param phoneNumber Phone number with country code (without + prefix)
18
+ * @param options Optional configuration for the session
19
+ * @returns Promise<WASocket> The WhatsApp socket instance
15
20
  */
16
- export declare const startSessionWithPairingCode: (sessionId: string, options: StartSessionWithPairingCodeParams) => Promise<WASocket>;
21
+ export declare const startSessionWithPairingCode: (sessionId: string, phoneNumber: string, options?: StartSessionParams) => Promise<WASocket>;
17
22
  /**
18
23
  * @deprecated Use startSession method instead
19
24
  */
@@ -65,6 +70,30 @@ export declare const setCredentialsDir: (dirname?: string) => void;
65
70
  * @returns Promise<boolean> indicating success
66
71
  */
67
72
  export declare const reconnect: (sessionId: string) => Promise<boolean>;
73
+ /**
74
+ * Reconnect all pairing code sessions that are tracked
75
+ * Useful for bulk reconnection after system restart
76
+ */
77
+ export declare const reconnectAllPairingCodeSessions: () => Promise<{
78
+ [sessionId: string]: boolean;
79
+ }>;
80
+ /**
81
+ * Get all tracked pairing code sessions
82
+ * @returns Array of session IDs that were created with pairing code
83
+ */
84
+ export declare const getPairingCodeSessions: () => string[];
85
+ /**
86
+ * Get session status information
87
+ * @param sessionId Session ID to check
88
+ * @returns Object with session status information
89
+ */
90
+ export declare const getSessionStatus: (sessionId: string) => {
91
+ sessionId: string;
92
+ isRunning: boolean;
93
+ isPairingCodeSession: boolean;
94
+ retryAttempts: number;
95
+ hasCredentials: boolean;
96
+ };
68
97
  export declare const setGroupCacheConfig: (options: {
69
98
  stdTTL?: number;
70
99
  checkperiod?: number;
@@ -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;AAKjB,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iCAAiC,EAClC,MAAM,UAAU,CAAC;AA8BlB;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,kBAkB5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,GAAG,QAEjD;AAkBD,eAAO,MAAM,YAAY,GACvB,kBAAuB,EACvB,UAAS,kBAAsC,KAC9C,OAAO,CAAC,QAAQ,CAkIlB,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,iCAxPf,kBAAkB,KAC1B,OAAO,CAAC,QAAQ,CAuPsB,CAAC;AAE1C,eAAO,MAAM,aAAa,GAAU,WAAW,MAAM,kBAkCpD,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;AAGF,eAAO,MAAM,mBAAmB,GAAI,SAAS;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,SAEA,CAAC;AAGF,eAAO,MAAM,gBAAgB,GAC3B,WAAW,MAAM,EACjB,KAAK,MAAM,EACX,aAAY,OAAe,KAC1B,OAAO,CAAC,GAAG,CA4Bb,CAAC;AAGF,eAAO,MAAM,uBAAuB,GAAU,WAAW,MAAM,EAAE,KAAK,MAAM,kBAE3E,CAAC;AAGF,eAAO,MAAM,8BAA8B,GAAU,WAAW,MAAM,kBAErE,CAAC;AAGF,eAAO,MAAM,0BAA0B,YAEtC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Socket/index.ts"],"names":[],"mappings":"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"}
@@ -45,7 +45,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
45
45
  return (mod && mod.__esModule) ? mod : { "default": mod };
46
46
  };
47
47
  Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.clearAllGroupMetadataCache = exports.clearSessionGroupMetadataCache = exports.clearGroupMetadataCache = exports.getGroupMetadata = exports.setGroupCacheConfig = exports.reconnect = exports.setCredentialsDir = exports.setMongoDBNames = exports.loadSessionsFromMongo = exports.onPairingCode = exports.onMessageUpdate = exports.onConnecting = exports.onDisconnected = exports.onConnected = exports.onQRUpdated = exports.onMessageReceived = exports.loadSessionsFromStorage = exports.getSession = exports.getAllSessionSync = exports.getAllSession = exports.deleteSession = exports.startWhatsapp = exports.startSessionWithPairingCode = exports.startSession = exports.setMongoURI = void 0;
48
+ exports.clearAllGroupMetadataCache = exports.clearSessionGroupMetadataCache = exports.clearGroupMetadataCache = exports.getGroupMetadata = exports.setGroupCacheConfig = exports.getSessionStatus = exports.getPairingCodeSessions = exports.reconnectAllPairingCodeSessions = exports.reconnect = exports.setCredentialsDir = exports.setMongoDBNames = exports.loadSessionsFromMongo = exports.onPairingCode = exports.onMessageUpdate = exports.onConnecting = exports.onDisconnected = exports.onConnected = exports.onQRUpdated = exports.onMessageReceived = exports.loadSessionsFromStorage = exports.getSession = exports.getAllSessionSync = exports.getAllSession = exports.deleteSession = exports.startWhatsapp = exports.startSessionWithPairingCode = exports.startSession = exports.setMongoURI = void 0;
49
49
  exports.setMongoCollection = setMongoCollection;
50
50
  const baileys_1 = __importStar(require("baileys"));
51
51
  const path_1 = __importDefault(require("path"));
@@ -62,6 +62,8 @@ const create_delay_1 = require("../Utils/create-delay");
62
62
  const sessions = new Map();
63
63
  const callback = new Map();
64
64
  const retryCount = new Map();
65
+ // Tambahkan Map untuk melacak session yang menggunakan pairing code
66
+ const pairingCodeSessions = new Map();
65
67
  const P = require("pino")({
66
68
  level: "silent",
67
69
  });
@@ -90,7 +92,7 @@ const setMongoURI = (uri) => __awaiter(void 0, void 0, void 0, function* () {
90
92
  mongoClient = undefined;
91
93
  authCollection = null;
92
94
  }
93
- console.log("MongoDB URI configured successfully");
95
+ // MongoDB URI configured successfully - removed console.log for npm package
94
96
  });
95
97
  exports.setMongoURI = setMongoURI;
96
98
  function setMongoCollection(collection) {
@@ -137,6 +139,7 @@ const startSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, funct
137
139
  const update = events["connection.update"];
138
140
  const { connection, lastDisconnect } = update;
139
141
  if (update.qr) {
142
+ // Print QR to console if requested
140
143
  if (options.printQR) {
141
144
  qrcode_1.default.toString(update.qr, {
142
145
  type: 'terminal',
@@ -148,9 +151,10 @@ const startSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, funct
148
151
  }
149
152
  });
150
153
  }
154
+ // Send QR data raw to callback for frontend processing
151
155
  (_a = callback.get(Defaults_1.CALLBACK_KEY.ON_QR)) === null || _a === void 0 ? void 0 : _a({
152
156
  sessionId,
153
- qr: update.qr,
157
+ qr: update.qr
154
158
  });
155
159
  (_b = options.onQRUpdated) === null || _b === void 0 ? void 0 : _b.call(options, update.qr);
156
160
  }
@@ -172,7 +176,14 @@ const startSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, funct
172
176
  }
173
177
  else {
174
178
  retryCount.delete(sessionId);
175
- (0, exports.deleteSession)(sessionId);
179
+ // For pairing code sessions, preserve data for future reconnection
180
+ if (pairingCodeSessions.has(sessionId)) {
181
+ yield softDeleteSession(sessionId, true);
182
+ }
183
+ else {
184
+ // For regular sessions, completely delete
185
+ yield softDeleteSession(sessionId, false);
186
+ }
176
187
  (_h = callback.get(Defaults_1.CALLBACK_KEY.ON_DISCONNECTED)) === null || _h === void 0 ? void 0 : _h(sessionId);
177
188
  (_j = options.onDisconnected) === null || _j === void 0 ? void 0 : _j.call(options);
178
189
  }
@@ -241,16 +252,23 @@ const startSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, funct
241
252
  });
242
253
  exports.startSession = startSession;
243
254
  /**
255
+ * Start WhatsApp session using pairing code method
256
+ * This is the recommended way to create sessions with pairing code
244
257
  *
245
- * @deprecated Use startSession method instead
258
+ * @param sessionId Unique session identifier
259
+ * @param phoneNumber Phone number with country code (without + prefix)
260
+ * @param options Optional configuration for the session
261
+ * @returns Promise<WASocket> The WhatsApp socket instance
246
262
  */
247
- const startSessionWithPairingCode = (sessionId, options) => __awaiter(void 0, void 0, void 0, function* () {
263
+ const startSessionWithPairingCode = (sessionId_1, phoneNumber_1, ...args_1) => __awaiter(void 0, [sessionId_1, phoneNumber_1, ...args_1], void 0, function* (sessionId, phoneNumber, options = {}) {
248
264
  if (isSessionExistAndRunning(sessionId))
249
265
  throw new Error_1.WhatsappError(Defaults_1.Messages.sessionAlreadyExist(sessionId));
266
+ // Simpan informasi session pairing code untuk auto-reconnect
267
+ pairingCodeSessions.set(sessionId, { phoneNumber, options });
250
268
  yield initMongo();
251
269
  const { version } = yield (0, baileys_1.fetchLatestBaileysVersion)();
252
270
  const startSocket = () => __awaiter(void 0, void 0, void 0, function* () {
253
- var _a;
271
+ var _a, _b;
254
272
  const { state, saveCreds } = yield (0, mongo_auth_state_1.useMongoAuthState)(sessionId, authCollection);
255
273
  const sock = (0, baileys_1.default)({
256
274
  version,
@@ -258,80 +276,162 @@ const startSessionWithPairingCode = (sessionId, options) => __awaiter(void 0, vo
258
276
  logger: P,
259
277
  markOnlineOnConnect: false,
260
278
  browser: baileys_1.Browsers.ubuntu("Chrome"),
279
+ // Opsi tambahan untuk meningkatkan kompatibilitas
280
+ linkPreviewImageThumbnailWidth: 300,
281
+ generateHighQualityLinkPreview: true,
282
+ syncFullHistory: false, // Sinkronisasi hanya riwayat baru
283
+ connectTimeoutMs: 60000, // Timeout koneksi ditingkatkan
284
+ printQRInTerminal: false, // QR tidak dicetak untuk pairing code
285
+ // Configure caching group metadata using our hybrid implementation with session ID
286
+ cachedGroupMetadata: (jid) => __awaiter(void 0, void 0, void 0, function* () {
287
+ return yield Utils_1.groupCache.get(sessionId, jid);
288
+ })
261
289
  });
262
290
  sessions.set(sessionId, Object.assign({}, sock));
263
291
  try {
264
292
  if (!sock.authState.creds.registered) {
265
- console.log("first time pairing");
266
- const code = yield sock.requestPairingCode(options.phoneNumber);
267
- console.log(code);
268
- (_a = callback.get(Defaults_1.CALLBACK_KEY.ON_PAIRING_CODE)) === null || _a === void 0 ? void 0 : _a(sessionId, code);
293
+ // Pastikan kita mendapatkan kode pairing dan menampilkannya dengan jelas
294
+ try {
295
+ // Tambahkan delay untuk memastikan state sudah siap
296
+ yield new Promise(resolve => setTimeout(resolve, 2000));
297
+ // Hapus awalan + dari nomor telepon jika ada
298
+ const phoneNumberFormatted = phoneNumber.replace(/^\+/, '');
299
+ // Memanggil fungsi requestPairingCode dengan nomor telepon yang sudah dibersihkan
300
+ const code = yield sock.requestPairingCode(phoneNumberFormatted);
301
+ // Pastikan kode ada dan merupakan string
302
+ if (code && typeof code === 'string') {
303
+ console.log(`Pairing code untuk session ${sessionId}: ${code}`);
304
+ // Panggil callback yang terdaftar
305
+ (_a = callback.get(Defaults_1.CALLBACK_KEY.ON_PAIRING_CODE)) === null || _a === void 0 ? void 0 : _a(sessionId, code);
306
+ (_b = options.onPairingCode) === null || _b === void 0 ? void 0 : _b.call(options, code);
307
+ }
308
+ else {
309
+ console.error("Error: Kode pairing tidak valid atau kosong");
310
+ }
311
+ }
312
+ catch (error) {
313
+ console.error("Error saat meminta kode pairing:", error);
314
+ throw new Error_1.WhatsappError(`Gagal mendapatkan kode pairing: ${error.message || String(error)}`);
315
+ }
269
316
  }
270
317
  sock.ev.process((events) => __awaiter(void 0, void 0, void 0, function* () {
271
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
318
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
272
319
  if (events["connection.update"]) {
273
320
  const update = events["connection.update"];
274
321
  const { connection, lastDisconnect } = update;
275
322
  if (update.qr) {
276
- qrcode_1.default.toString(update.qr, {
277
- type: 'terminal',
278
- small: true,
279
- margin: 1
280
- }, (err, qrString) => {
281
- if (!err) {
282
- console.log(qrString);
283
- }
284
- });
323
+ // Send QR data raw to callback for frontend processing
285
324
  (_a = callback.get(Defaults_1.CALLBACK_KEY.ON_QR)) === null || _a === void 0 ? void 0 : _a({
286
325
  sessionId,
287
- qr: update.qr,
326
+ qr: update.qr
288
327
  });
289
328
  }
290
329
  if (connection == "connecting") {
291
330
  (_b = callback.get(Defaults_1.CALLBACK_KEY.ON_CONNECTING)) === null || _b === void 0 ? void 0 : _b(sessionId);
331
+ (_c = options.onConnecting) === null || _c === void 0 ? void 0 : _c.call(options);
292
332
  }
293
333
  if (connection === "close") {
294
- const code = (_d = (_c = lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) === null || _c === void 0 ? void 0 : _c.output) === null || _d === void 0 ? void 0 : _d.statusCode;
295
- let retryAttempt = (_e = retryCount.get(sessionId)) !== null && _e !== void 0 ? _e : 0;
334
+ const code = (_e = (_d = lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) === null || _d === void 0 ? void 0 : _d.output) === null || _e === void 0 ? void 0 : _e.statusCode;
335
+ let retryAttempt = (_f = retryCount.get(sessionId)) !== null && _f !== void 0 ? _f : 0;
296
336
  let shouldRetry;
297
337
  if (code != baileys_1.DisconnectReason.loggedOut && retryAttempt < 10) {
298
338
  shouldRetry = true;
299
339
  }
300
340
  if (shouldRetry) {
301
341
  retryAttempt++;
302
- }
303
- if (shouldRetry) {
304
342
  retryCount.set(sessionId, retryAttempt);
305
- startSocket();
343
+ // Untuk session pairing code, coba reconnect dengan metode yang tepat
344
+ try {
345
+ // Tunggu sebentar sebelum reconnect
346
+ yield (0, create_delay_1.createDelay)(2000);
347
+ startSocket();
348
+ }
349
+ catch (reconnectError) {
350
+ console.error(`Auto-reconnect failed for session ${sessionId}:`, reconnectError.message);
351
+ // Jika reconnect gagal beberapa kali, coba dengan pairing code lagi (jika masih dalam 3 attempt pertama)
352
+ if (retryAttempt <= 3 && pairingCodeSessions.has(sessionId)) {
353
+ const sessionInfo = pairingCodeSessions.get(sessionId);
354
+ // Bersihkan session lama
355
+ sessions.delete(sessionId);
356
+ // Coba mulai ulang dengan pairing code baru
357
+ setTimeout(() => {
358
+ startSocket().catch(err => {
359
+ console.error(`Failed to restart with pairing code for session ${sessionId}:`, err);
360
+ });
361
+ }, 3000);
362
+ }
363
+ else {
364
+ // Jika sudah terlalu banyak gagal, panggil startSocket biasa
365
+ startSocket();
366
+ }
367
+ }
306
368
  }
307
369
  else {
308
370
  retryCount.delete(sessionId);
309
- (0, exports.deleteSession)(sessionId);
310
- (_f = callback.get(Defaults_1.CALLBACK_KEY.ON_DISCONNECTED)) === null || _f === void 0 ? void 0 : _f(sessionId);
371
+ // For pairing code sessions, preserve data for future reconnection
372
+ if (pairingCodeSessions.has(sessionId)) {
373
+ yield softDeleteSession(sessionId, true);
374
+ // Don't remove from pairing code tracking completely to allow manual reconnection
375
+ }
376
+ else {
377
+ pairingCodeSessions.delete(sessionId); // Only delete from tracking if it's not a pairing code session
378
+ yield softDeleteSession(sessionId, false);
379
+ }
380
+ (_g = callback.get(Defaults_1.CALLBACK_KEY.ON_DISCONNECTED)) === null || _g === void 0 ? void 0 : _g(sessionId);
381
+ (_h = options.onDisconnected) === null || _h === void 0 ? void 0 : _h.call(options);
311
382
  }
312
383
  }
313
384
  if (connection == "open") {
314
385
  retryCount.delete(sessionId);
315
- (_g = callback.get(Defaults_1.CALLBACK_KEY.ON_CONNECTED)) === null || _g === void 0 ? void 0 : _g(sessionId);
386
+ (_j = callback.get(Defaults_1.CALLBACK_KEY.ON_CONNECTED)) === null || _j === void 0 ? void 0 : _j(sessionId);
387
+ (_k = options.onConnected) === null || _k === void 0 ? void 0 : _k.call(options);
316
388
  }
317
389
  }
318
390
  if (events["creds.update"]) {
319
391
  yield saveCreds();
320
392
  }
393
+ // Menangani event update data grup
394
+ if (events["groups.update"]) {
395
+ const updates = events["groups.update"];
396
+ for (const update of updates) {
397
+ try {
398
+ // Dapatkan metadata grup terbaru dan simpan ke cache dengan sessionId
399
+ const metadata = yield sock.groupMetadata(update.id);
400
+ yield Utils_1.groupCache.set(sessionId, update.id, metadata);
401
+ }
402
+ catch (error) {
403
+ console.error(`Error updating group metadata in cache: ${error}`);
404
+ }
405
+ }
406
+ }
407
+ // Menangani event perubahan peserta grup
408
+ if (events["group-participants.update"]) {
409
+ const update = events["group-participants.update"];
410
+ try {
411
+ // Dapatkan metadata grup terbaru dan simpan ke cache dengan sessionId
412
+ const metadata = yield sock.groupMetadata(update.id);
413
+ yield Utils_1.groupCache.set(sessionId, update.id, metadata);
414
+ }
415
+ catch (error) {
416
+ console.error(`Error updating group participants in cache: ${error}`);
417
+ }
418
+ }
321
419
  if (events["messages.update"]) {
322
420
  const msg = events["messages.update"][0];
323
421
  const data = Object.assign({ sessionId: sessionId, messageStatus: (0, message_status_1.parseMessageStatusCodeToReadable)(msg.update.status) }, msg);
324
- (_h = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_UPDATED)) === null || _h === void 0 ? void 0 : _h(sessionId, data);
422
+ (_l = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_UPDATED)) === null || _l === void 0 ? void 0 : _l(sessionId, data);
423
+ (_m = options.onMessageUpdated) === null || _m === void 0 ? void 0 : _m.call(options, data);
325
424
  }
326
425
  if (events["messages.upsert"]) {
327
- const msg = (_j = events["messages.upsert"]
328
- .messages) === null || _j === void 0 ? void 0 : _j[0];
426
+ const msg = (_o = events["messages.upsert"]
427
+ .messages) === null || _o === void 0 ? void 0 : _o[0];
329
428
  msg.sessionId = sessionId;
330
429
  msg.saveImage = (path) => (0, save_media_1.saveImageHandler)(msg, path);
331
430
  msg.saveVideo = (path) => (0, save_media_1.saveVideoHandler)(msg, path);
332
431
  msg.saveDocument = (path) => (0, save_media_1.saveDocumentHandler)(msg, path);
333
432
  msg.saveAudio = (path) => (0, save_media_1.saveAudioHandler)(msg, path);
334
- (_k = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_RECEIVED)) === null || _k === void 0 ? void 0 : _k(Object.assign({}, msg));
433
+ (_p = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_RECEIVED)) === null || _p === void 0 ? void 0 : _p(Object.assign({}, msg));
434
+ (_q = options.onMessageReceived) === null || _q === void 0 ? void 0 : _q.call(options, msg);
335
435
  }
336
436
  }));
337
437
  return sock;
@@ -348,6 +448,45 @@ exports.startSessionWithPairingCode = startSessionWithPairingCode;
348
448
  * @deprecated Use startSession method instead
349
449
  */
350
450
  exports.startWhatsapp = exports.startSession;
451
+ /**
452
+ * Soft delete session - removes from memory but preserves MongoDB data for pairing code sessions
453
+ * @param sessionId Session ID to soft delete
454
+ */
455
+ const softDeleteSession = (sessionId_1, ...args_1) => __awaiter(void 0, [sessionId_1, ...args_1], void 0, function* (sessionId, preserveData = false) {
456
+ const session = (0, exports.getSession)(sessionId);
457
+ try {
458
+ yield (session === null || session === void 0 ? void 0 : session.logout());
459
+ }
460
+ catch (error) { }
461
+ session === null || session === void 0 ? void 0 : session.end(undefined);
462
+ sessions.delete(sessionId);
463
+ // Only completely remove from MongoDB if not preserving data or not a pairing code session
464
+ if (!preserveData && !pairingCodeSessions.has(sessionId)) {
465
+ if (authCollection) {
466
+ try {
467
+ yield authCollection.deleteOne({ sessionId });
468
+ }
469
+ catch (error) {
470
+ console.error(`Error deleting session ${sessionId} from MongoDB:`, error);
471
+ }
472
+ }
473
+ }
474
+ else if (pairingCodeSessions.has(sessionId)) {
475
+ // Preserving MongoDB data for pairing code session
476
+ }
477
+ // Hapus cache grup untuk session ini
478
+ try {
479
+ yield Utils_1.groupCache.clearSessionCache(sessionId);
480
+ }
481
+ catch (error) {
482
+ console.error(`Error clearing group cache for session ${sessionId}:`, error);
483
+ }
484
+ // Legacy: hapus juga dari file system jika ada
485
+ const dir = path_1.default.resolve(Defaults_1.CREDENTIALS.DIR_NAME, sessionId + Defaults_1.CREDENTIALS.PREFIX);
486
+ if (fs_1.default.existsSync(dir)) {
487
+ fs_1.default.rmSync(dir, { force: true, recursive: true });
488
+ }
489
+ });
351
490
  const deleteSession = (sessionId) => __awaiter(void 0, void 0, void 0, function* () {
352
491
  const session = (0, exports.getSession)(sessionId);
353
492
  try {
@@ -356,11 +495,12 @@ const deleteSession = (sessionId) => __awaiter(void 0, void 0, void 0, function*
356
495
  catch (error) { }
357
496
  session === null || session === void 0 ? void 0 : session.end(undefined);
358
497
  sessions.delete(sessionId);
498
+ // Hapus tracking pairing code session jika ada
499
+ pairingCodeSessions.delete(sessionId);
359
500
  // Hapus juga dari MongoDB jika authCollection ada
360
501
  if (authCollection) {
361
502
  try {
362
503
  yield authCollection.deleteOne({ sessionId });
363
- console.log(`Session ${sessionId} deleted from MongoDB`);
364
504
  }
365
505
  catch (error) {
366
506
  console.error(`Error deleting session ${sessionId} from MongoDB:`, error);
@@ -369,7 +509,6 @@ const deleteSession = (sessionId) => __awaiter(void 0, void 0, void 0, function*
369
509
  // Hapus cache grup untuk session ini
370
510
  try {
371
511
  yield Utils_1.groupCache.clearSessionCache(sessionId);
372
- console.log(`Group metadata cache for session ${sessionId} cleared`);
373
512
  }
374
513
  catch (error) {
375
514
  console.error(`Error clearing group cache for session ${sessionId}:`, error);
@@ -479,7 +618,8 @@ const onMessageUpdate = (listener) => {
479
618
  };
480
619
  exports.onMessageUpdate = onMessageUpdate;
481
620
  const onPairingCode = (listener) => {
482
- callback.set(Defaults_1.CALLBACK_KEY.ON_MESSAGE_UPDATED, listener);
621
+ // Set callback ke registry dengan key yang benar
622
+ callback.set(Defaults_1.CALLBACK_KEY.ON_PAIRING_CODE, listener);
483
623
  };
484
624
  exports.onPairingCode = onPairingCode;
485
625
  /**
@@ -511,7 +651,6 @@ exports.loadSessionsFromMongo = loadSessionsFromMongo;
511
651
  const setMongoDBNames = (dbName = "wa_session", collectionName = "auth") => {
512
652
  Defaults_1.CREDENTIALS.MONGO_DB_NAME = dbName;
513
653
  Defaults_1.CREDENTIALS.MONGO_COLLECTION_NAME = collectionName;
514
- console.log(`MongoDB names configured: database="${dbName}", collection="${collectionName}"`);
515
654
  };
516
655
  exports.setMongoDBNames = setMongoDBNames;
517
656
  /**
@@ -555,36 +694,115 @@ const reconnect = (sessionId) => __awaiter(void 0, void 0, void 0, function* ()
555
694
  }
556
695
  // Tunggu sedikit waktu untuk memastikan cleanup selesai
557
696
  yield (0, create_delay_1.createDelay)(1000);
558
- // Cek jika data session tersedia di MongoDB
559
- yield initMongo();
560
- const sessionExists = yield shouldLoadSession(sessionId);
561
- if (sessionExists) {
562
- // Mulai session baru dari data yang tersimpan di MongoDB
563
- // Gunakan opsi khusus untuk reconnect
697
+ // Cek jika ini session pairing code dari tracking terlebih dahulu
698
+ const pairingInfo = pairingCodeSessions.get(sessionId);
699
+ if (pairingInfo) {
700
+ // Ini adalah session pairing code, gunakan metode pairing code untuk reconnect
564
701
  try {
565
- yield (0, exports.startSession)(sessionId, {
566
- printQR: false,
702
+ // Reset retry count untuk session ini
703
+ retryCount.delete(sessionId);
704
+ yield (0, exports.startSessionWithPairingCode)(sessionId, pairingInfo.phoneNumber, Object.assign(Object.assign({}, pairingInfo.options), { printQR: false,
567
705
  // Tambahkan callback khusus untuk reconnect
568
- onConnected: () => { },
569
- onDisconnected: () => { },
570
- onQRUpdated: (qr) => { }
571
- });
706
+ onConnected: () => {
707
+ // Pairing code session reconnected successfully
708
+ }, onDisconnected: () => {
709
+ // Pairing code session disconnected after reconnect
710
+ } }));
572
711
  // Periksa jika session berhasil dimulai
573
712
  return !!(0, exports.getSession)(sessionId);
574
713
  }
575
714
  catch (startError) {
715
+ console.error(`Failed to reconnect pairing code session ${sessionId}:`, startError.message);
576
716
  return false;
577
717
  }
578
718
  }
579
719
  else {
580
- return false;
720
+ // Cek jika data session tersedia di MongoDB untuk session biasa
721
+ yield initMongo();
722
+ const sessionExists = yield shouldLoadSession(sessionId);
723
+ if (sessionExists) {
724
+ // Session biasa, gunakan metode startSession normal
725
+ try {
726
+ yield (0, exports.startSession)(sessionId, {
727
+ printQR: false,
728
+ // Tambahkan callback khusus untuk reconnect
729
+ onConnected: () => {
730
+ // Session reconnected successfully
731
+ },
732
+ onDisconnected: () => {
733
+ // Session disconnected after reconnect
734
+ },
735
+ onQRUpdated: (qr) => {
736
+ // QR code updated for reconnecting session
737
+ }
738
+ });
739
+ // Periksa jika session berhasil dimulai
740
+ return !!(0, exports.getSession)(sessionId);
741
+ }
742
+ catch (startError) {
743
+ console.error(`Failed to reconnect session ${sessionId}:`, startError.message);
744
+ return false;
745
+ }
746
+ }
747
+ else {
748
+ // No session data found in MongoDB
749
+ return false;
750
+ }
581
751
  }
582
752
  }
583
753
  catch (error) {
754
+ console.error(`Error during reconnect for session ${sessionId}:`, error.message);
584
755
  return false;
585
756
  }
586
757
  });
587
758
  exports.reconnect = reconnect;
759
+ /**
760
+ * Reconnect all pairing code sessions that are tracked
761
+ * Useful for bulk reconnection after system restart
762
+ */
763
+ const reconnectAllPairingCodeSessions = () => __awaiter(void 0, void 0, void 0, function* () {
764
+ const results = {};
765
+ for (const [sessionId, sessionInfo] of pairingCodeSessions.entries()) {
766
+ try {
767
+ const success = yield (0, exports.reconnect)(sessionId);
768
+ results[sessionId] = success;
769
+ // Add delay between reconnection attempts
770
+ yield (0, create_delay_1.createDelay)(2000);
771
+ }
772
+ catch (error) {
773
+ console.error(`Error reconnecting pairing code session ${sessionId}:`, error.message);
774
+ results[sessionId] = false;
775
+ }
776
+ }
777
+ return results;
778
+ });
779
+ exports.reconnectAllPairingCodeSessions = reconnectAllPairingCodeSessions;
780
+ /**
781
+ * Get all tracked pairing code sessions
782
+ * @returns Array of session IDs that were created with pairing code
783
+ */
784
+ const getPairingCodeSessions = () => {
785
+ return Array.from(pairingCodeSessions.keys());
786
+ };
787
+ exports.getPairingCodeSessions = getPairingCodeSessions;
788
+ /**
789
+ * Get session status information
790
+ * @param sessionId Session ID to check
791
+ * @returns Object with session status information
792
+ */
793
+ const getSessionStatus = (sessionId) => {
794
+ const isRunning = !!(0, exports.getSession)(sessionId);
795
+ const isPairingCodeSession = pairingCodeSessions.has(sessionId);
796
+ const retryAttempts = retryCount.get(sessionId) || 0;
797
+ return {
798
+ sessionId,
799
+ isRunning,
800
+ isPairingCodeSession,
801
+ retryAttempts,
802
+ hasCredentials: isRunning ? true : null // null means unknown when not running
803
+ };
804
+ };
805
+ exports.getSessionStatus = getSessionStatus;
588
806
  // Fungsi baru untuk mendapatkan konfigurasi TTL cache grup
589
807
  const setGroupCacheConfig = (options) => {
590
808
  Utils_1.groupCache.setConfig(options);
@@ -54,6 +54,7 @@ export interface StartSessionParams {
54
54
  onConnected?: () => void;
55
55
  onConnecting?: () => void;
56
56
  onDisconnected?: () => void;
57
+ onPairingCode?: (code: string) => void;
57
58
  onMessageReceived?: (message: MessageReceived) => void;
58
59
  onMessageUpdated?: (message: MessageUpdated) => void;
59
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC;CACxB;AAED,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,eAAe;IAC5D;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAG5B,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACvD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,iCAAiC;IAChD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EACT,OAAO,GACP,SAAS,GACT,QAAQ,GACR,WAAW,GACX,MAAM,GACN,QAAQ,CAAC;CACd,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC;CACxB;AAED,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,eAAe;IAC5D;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAGvC,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACvD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,iCAAiC;IAChD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EACT,OAAO,GACP,SAAS,GACT,QAAQ,GACR,WAAW,GACX,MAAM,GACN,QAAQ,CAAC;CACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wa-multi-mongodb",
3
- "version": "3.9.5",
3
+ "version": "3.9.6",
4
4
  "description": "Multi Session Whatsapp Library with MongoDB Integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,6 +19,7 @@
19
19
  "@hapi/boom": "^10.0.1",
20
20
  "@types/node-cache": "^4.1.3",
21
21
  "@types/qrcode": "^1.5.5",
22
+ "aws4": "^1.13.2",
22
23
  "baileys": "^6.7.18",
23
24
  "dotenv": "^16.5.0",
24
25
  "link-preview-js": "^3.0.14",
package/readme.md CHANGED
@@ -98,7 +98,7 @@ For secure MongoDB URI management, we recommend using environment variables:
98
98
  ### Session Management
99
99
 
100
100
  ```javascript
101
- // Start a new session
101
+ // Start a new session with QR Code
102
102
  const session = await whatsapp.startSession("mysession");
103
103
 
104
104
  // Start with options
@@ -106,7 +106,22 @@ await whatsapp.startSession("mysession2", {
106
106
  printQR: true,
107
107
  onConnected: () => console.log("Connected!"),
108
108
  onDisconnected: () => console.log("Disconnected!"),
109
- onQRUpdated: (qr) => console.log("New QR:", qr)
109
+ onQRUpdated: (qr) => {
110
+ console.log("New QR:", qr);
111
+ // QR data is raw and ready for frontend use
112
+ // You can display this in React, Vue, Angular, etc.
113
+ }
114
+ });
115
+
116
+ // Start session with Pairing Code (v3.9.6+)
117
+ await whatsapp.startSessionWithPairingCode("mysession3", {
118
+ mobile: "6281234567890", // your phone number with country code
119
+ onConnected: () => console.log("Pairing session connected!"),
120
+ onDisconnected: () => console.log("Pairing session disconnected!"),
121
+ onPairingCode: (code) => {
122
+ console.log("Pairing code:", code);
123
+ // Enter this code in your WhatsApp app: Settings > Linked Devices > Link a Device > Link with phone number
124
+ }
110
125
  });
111
126
 
112
127
  // Get all active sessions
@@ -117,6 +132,27 @@ const sessionData = whatsapp.getSession("mysession");
117
132
 
118
133
  // Load all saved sessions from MongoDB
119
134
  await whatsapp.loadSessionsFromMongo();
135
+
136
+ // Session Management Utilities (v3.9.6+)
137
+ // Get session status with detailed information
138
+ const status = await whatsapp.getSessionStatus("mysession");
139
+ console.log("Session status:", status);
140
+ // Returns: { exists: true, connected: true, sessionType: 'qr' | 'pairing' }
141
+
142
+ // Manual reconnection for any session
143
+ try {
144
+ const reconnected = await whatsapp.reconnect("mysession");
145
+ console.log("Reconnection successful:", reconnected);
146
+ } catch (error) {
147
+ console.error("Reconnection failed:", error);
148
+ }
149
+
150
+ // Get all pairing code sessions
151
+ const pairingSessions = whatsapp.getPairingCodeSessions();
152
+ console.log("Pairing code sessions:", pairingSessions);
153
+
154
+ // Bulk reconnect all pairing code sessions
155
+ await whatsapp.reconnectAllPairingCodeSessions();
120
156
  ```
121
157
 
122
158
  ### Sending Messages
@@ -511,6 +547,214 @@ startApp().catch(err => {
511
547
  });
512
548
  ```
513
549
 
550
+ ## Complete Example: Pairing Code with Auto-Reconnect (v3.9.6+)
551
+
552
+ ```javascript
553
+ import * as whatsapp from "wa-multi-mongodb";
554
+ require('dotenv').config();
555
+
556
+ // Store connection status
557
+ const sessionStatus = {};
558
+
559
+ async function startPairingApp() {
560
+ // MongoDB Configuration
561
+ await whatsapp.setMongoURI(process.env.MONGODB_URI);
562
+
563
+ // Event listeners for pairing code sessions
564
+ whatsapp.onConnected((sessionId) => {
565
+ console.log(`Pairing session ${sessionId} connected!`);
566
+ sessionStatus[sessionId] = 'connected';
567
+ });
568
+
569
+ whatsapp.onDisconnected(async (sessionId) => {
570
+ console.log(`Pairing session ${sessionId} disconnected!`);
571
+ sessionStatus[sessionId] = 'disconnected';
572
+
573
+ // Check if it's a pairing code session
574
+ const status = await whatsapp.getSessionStatus(sessionId);
575
+ if (status.sessionType === 'pairing') {
576
+ console.log(`Attempting to reconnect pairing session ${sessionId}...`);
577
+
578
+ // Auto-reconnect after 5 seconds
579
+ setTimeout(async () => {
580
+ try {
581
+ const reconnected = await whatsapp.reconnect(sessionId);
582
+ if (reconnected) {
583
+ console.log(`Pairing session ${sessionId} reconnected successfully!`);
584
+ sessionStatus[sessionId] = 'connected';
585
+ }
586
+ } catch (error) {
587
+ console.error(`Failed to reconnect pairing session ${sessionId}:`, error);
588
+ }
589
+ }, 5000);
590
+ }
591
+ });
592
+
593
+ // Message handler
594
+ whatsapp.onMessageReceived(async (msg) => {
595
+ if (msg.key.fromMe || msg.key.remoteJid.includes("status")) return;
596
+
597
+ const messageContent = msg.message?.conversation ||
598
+ msg.message?.extendedTextMessage?.text ||
599
+ "";
600
+
601
+ console.log(`Message from ${msg.key.remoteJid}: ${messageContent}`);
602
+
603
+ // Auto-reply example
604
+ if (messageContent.toLowerCase().includes("ping")) {
605
+ await whatsapp.sendTextMessage({
606
+ sessionId: msg.sessionId,
607
+ to: msg.key.remoteJid,
608
+ text: "Pong! Message received from pairing session.",
609
+ answering: msg
610
+ });
611
+ }
612
+ });
613
+
614
+ // Load existing sessions from MongoDB
615
+ await whatsapp.loadSessionsFromMongo();
616
+
617
+ // Start a new pairing code session
618
+ const pairingSessionId = "pairing_session_1";
619
+ const yourPhoneNumber = "6281234567890"; // Replace with your phone number
620
+
621
+ try {
622
+ await whatsapp.startSessionWithPairingCode(pairingSessionId, {
623
+ mobile: yourPhoneNumber,
624
+ onConnected: () => {
625
+ console.log("Pairing session connected successfully!");
626
+ sessionStatus[pairingSessionId] = 'connected';
627
+ },
628
+ onDisconnected: () => {
629
+ console.log("Pairing session disconnected!");
630
+ sessionStatus[pairingSessionId] = 'disconnected';
631
+ },
632
+ onPairingCode: (code) => {
633
+ console.log("\n" + "=".repeat(50));
634
+ console.log("📱 PAIRING CODE:", code);
635
+ console.log("=".repeat(50));
636
+ console.log("1. Open WhatsApp on your phone");
637
+ console.log("2. Go to Settings > Linked Devices");
638
+ console.log("3. Tap 'Link a Device'");
639
+ console.log("4. Tap 'Link with phone number instead'");
640
+ console.log("5. Enter the pairing code above");
641
+ console.log("=".repeat(50) + "\n");
642
+ }
643
+ });
644
+
645
+ sessionStatus[pairingSessionId] = 'connecting';
646
+ } catch (error) {
647
+ console.error("Error starting pairing session:", error);
648
+ }
649
+
650
+ // Periodic health check for pairing sessions
651
+ setInterval(async () => {
652
+ const pairingSessions = whatsapp.getPairingCodeSessions();
653
+ console.log(`Active pairing sessions: ${pairingSessions.length}`);
654
+
655
+ // Check each pairing session status
656
+ for (const sessionId of pairingSessions) {
657
+ const status = await whatsapp.getSessionStatus(sessionId);
658
+ console.log(`Session ${sessionId}: ${status.connected ? 'Connected' : 'Disconnected'}`);
659
+
660
+ if (!status.connected && sessionStatus[sessionId] === 'connected') {
661
+ console.log(`Detected disconnection for ${sessionId}, attempting reconnect...`);
662
+ try {
663
+ await whatsapp.reconnect(sessionId);
664
+ } catch (error) {
665
+ console.error(`Reconnect failed for ${sessionId}:`, error);
666
+ }
667
+ }
668
+ }
669
+ }, 30000); // Check every 30 seconds
670
+
671
+ // Bulk reconnect utility
672
+ setInterval(async () => {
673
+ try {
674
+ await whatsapp.reconnectAllPairingCodeSessions();
675
+ console.log("Bulk reconnect completed for all pairing sessions");
676
+ } catch (error) {
677
+ console.error("Bulk reconnect failed:", error);
678
+ }
679
+ }, 10 * 60 * 1000); // Every 10 minutes
680
+
681
+ console.log("Pairing code application started!");
682
+ }
683
+
684
+ startPairingApp().catch(err => {
685
+ console.error("Failed to start pairing application:", err);
686
+ process.exit(1);
687
+ });
688
+ ```
689
+
690
+ ## Frontend Integration Example: QR Code Display (v3.9.6+)
691
+
692
+ ```javascript
693
+ // React.js example for QR code display
694
+ import React, { useState, useEffect } from 'react';
695
+ import QRCode from 'qrcode';
696
+ import * as whatsapp from "wa-multi-mongodb";
697
+
698
+ function WhatsAppQRComponent() {
699
+ const [qrDataURL, setQrDataURL] = useState('');
700
+ const [sessionStatus, setSessionStatus] = useState('disconnected');
701
+
702
+ useEffect(() => {
703
+ // Initialize WhatsApp connection
704
+ const initWhatsApp = async () => {
705
+ await whatsapp.setMongoURI(process.env.REACT_APP_MONGODB_URI);
706
+
707
+ // Start session with simplified QR callback
708
+ await whatsapp.startSession("frontend_session", {
709
+ printQR: false, // Don't print in terminal
710
+ onQRUpdated: async (qr) => {
711
+ // QR data is raw and ready for frontend use
712
+ try {
713
+ const qrDataURL = await QRCode.toDataURL(qr);
714
+ setQrDataURL(qrDataURL);
715
+ } catch (error) {
716
+ console.error('Error generating QR code:', error);
717
+ }
718
+ },
719
+ onConnected: () => {
720
+ setSessionStatus('connected');
721
+ setQrDataURL(''); // Clear QR when connected
722
+ },
723
+ onDisconnected: () => {
724
+ setSessionStatus('disconnected');
725
+ }
726
+ });
727
+ };
728
+
729
+ initWhatsApp().catch(console.error);
730
+ }, []);
731
+
732
+ return (
733
+ <div className="whatsapp-qr">
734
+ <h2>WhatsApp Connection</h2>
735
+ <div className="status">
736
+ Status: <span className={sessionStatus}>{sessionStatus}</span>
737
+ </div>
738
+
739
+ {qrDataURL && (
740
+ <div className="qr-container">
741
+ <p>Scan this QR code with WhatsApp:</p>
742
+ <img src={qrDataURL} alt="WhatsApp QR Code" />
743
+ </div>
744
+ )}
745
+
746
+ {sessionStatus === 'connected' && (
747
+ <div className="connected">
748
+ <p>✅ WhatsApp connected successfully!</p>
749
+ </div>
750
+ )}
751
+ </div>
752
+ );
753
+ }
754
+
755
+ export default WhatsAppQRComponent;
756
+ ```
757
+
514
758
  ## Best Practices for Group Chats
515
759
 
516
760
  1. **Auto Group Detection**: Since v3.9.0, the library automatically detects if a chat is a group based on its JID format
@@ -529,7 +773,29 @@ startApp().catch(err => {
529
773
 
530
774
  ## Changelog
531
775
 
532
- ### v3.9.5 (current)
776
+ ### v3.9.6 (latest)
777
+ - **Enhanced Pairing Code Support**: Added comprehensive pairing code session management with auto-reconnect capabilities
778
+ - New `startSessionWithPairingCode()` function for creating sessions using pairing codes
779
+ - Intelligent session tracking system that preserves pairing code session data across disconnections
780
+ - Enhanced auto-reconnect mechanism that differentiates between QR code and pairing code sessions
781
+ - Session persistence in MongoDB for pairing code sessions to enable seamless reconnection
782
+ - **New Utility Functions for Session Management**:
783
+ - `reconnect(sessionId)` - Manual reconnection for any session type
784
+ - `reconnectAllPairingCodeSessions()` - Bulk reconnection for all tracked pairing code sessions
785
+ - `getPairingCodeSessions()` - Get list of all pairing code session IDs
786
+ - `getSessionStatus(sessionId)` - Get detailed session status information including session type
787
+ - **QR Data Raw for Frontend Integration**: Simplified QR handling optimized for frontend development
788
+ - Cleaned up QR callback to provide only essential QR data raw for frontend processing
789
+ - Removed unnecessary QR string complexity from callbacks for better performance
790
+ - QR data can be directly used with any frontend QR code library (React, Vue, Angular, etc.)
791
+ - Terminal QR display handled automatically via `printQR` option
792
+ - **Breaking Changes**:
793
+ - Simplified `onQRUpdated` callback signature: removed `qrString` parameter, now only provides raw QR data
794
+ - Session-level `onQRUpdated` option simplified from `(qr, qrString)` to `(qr)` only
795
+ - **Enhanced Session Persistence**: Pairing code sessions maintain authentication state in MongoDB during disconnections
796
+ - **Improved Error Handling**: Better error recovery and automatic session restoration for pairing code sessions
797
+
798
+ ### v3.9.5
533
799
  - New `deleteMessage()` function for deleting messages
534
800
  - Support for deleting both own messages and others' messages (requires admin permissions in groups)
535
801
  - Auto-delete message utility function example
@@ -592,4 +858,4 @@ startApp().catch(err => {
592
858
 
593
859
  ## License
594
860
 
595
- ISC
861
+ ISC