@raevon/n8n-nodes-whatsapp 1.0.11 → 1.0.13

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.
@@ -58,6 +58,8 @@ export declare function getConnectionStatus(): {
58
58
  queueSize: number;
59
59
  sentToday: number;
60
60
  dailyLimit: number;
61
+ lastError: string | null;
61
62
  };
63
+ export declare function disconnect(): Promise<void>;
62
64
  export declare function parseIncomingMessage(msg: any): Record<string, any> | null;
63
65
  export {};
@@ -42,6 +42,7 @@ exports.connectOrGetQr = connectOrGetQr;
42
42
  exports.simulateTyping = simulateTyping;
43
43
  exports.sendMessageWithAntiBan = sendMessageWithAntiBan;
44
44
  exports.getConnectionStatus = getConnectionStatus;
45
+ exports.disconnect = disconnect;
45
46
  exports.parseIncomingMessage = parseIncomingMessage;
46
47
  const n8n_workflow_1 = require("n8n-workflow");
47
48
  const baileys_1 = __importStar(require("@whiskeysockets/baileys"));
@@ -89,6 +90,7 @@ let qrResolve = null;
89
90
  let latestQr = null;
90
91
  let generation = 0; // #10: Generation counter — prevents stale handlers on reconnect
91
92
  let credsSavedPromise = null; // Track credential save completion
93
+ let lastDisconnectError = null; // Track last disconnect reason for output
92
94
  function todayStartIso() {
93
95
  return new Date().toISOString().slice(0, 10) + 'T00:00:00.000Z';
94
96
  }
@@ -168,7 +170,7 @@ async function initSocket(cfg, authPath) {
168
170
  });
169
171
  });
170
172
  sock.ev.on('connection.update', async (update) => {
171
- var _a, _b;
173
+ var _a, _b, _c;
172
174
  if (gen !== generation)
173
175
  return; // #10: Ignore stale connection events
174
176
  const { connection, lastDisconnect, qr } = update;
@@ -186,22 +188,27 @@ async function initSocket(cfg, authPath) {
186
188
  socketStatus = 'connected';
187
189
  reconnectAttempts = 0;
188
190
  latestQr = null;
189
- console.log('[WhatsApp] Connected successfully');
191
+ lastDisconnectError = null;
190
192
  return;
191
193
  }
192
194
  if (connection === 'close') {
193
195
  const code = (_b = (_a = lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) === null || _a === void 0 ? void 0 : _a.output) === null || _b === void 0 ? void 0 : _b.statusCode;
196
+ const errorMsg = ((_c = lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) === null || _c === void 0 ? void 0 : _c.message) || 'Unknown error';
194
197
  const reason = baileys_1.DisconnectReason[code] || 'Unknown';
195
- console.log(`[WhatsApp] Connection closed: ${reason} (code: ${code})`);
198
+ // Store error for output in nodes
199
+ lastDisconnectError = `Code: ${code} (${reason}), Error: ${errorMsg}`;
196
200
  if (code === baileys_1.DisconnectReason.loggedOut) {
197
201
  socketStatus = 'logged_out';
198
202
  socketInstance = null;
199
- ++generation; // #10: Invalidate all handlers from this session
203
+ ++generation;
200
204
  }
201
205
  else {
202
206
  socketStatus = 'disconnected';
203
207
  socketInstance = null;
204
- scheduleReconnect(cfg);
208
+ // Don't auto-reconnect if we're in a loop — let the node handle it
209
+ if (reconnectAttempts < 3) {
210
+ scheduleReconnect(cfg);
211
+ }
205
212
  }
206
213
  }
207
214
  });
@@ -476,8 +483,23 @@ function getConnectionStatus() {
476
483
  queueSize: queue ? queue.size + queue.pending : 0,
477
484
  sentToday: sentTodayCount,
478
485
  dailyLimit: (_a = socketConfig === null || socketConfig === void 0 ? void 0 : socketConfig.dailySendLimit) !== null && _a !== void 0 ? _a : 0,
486
+ lastError: lastDisconnectError,
479
487
  };
480
488
  }
489
+ // Gracefully disconnect — important for n8n queue mode where multiple workers run
490
+ async function disconnect() {
491
+ if (socketInstance) {
492
+ try {
493
+ socketInstance.end(new Error('n8n execution finished'));
494
+ }
495
+ catch {
496
+ // ignore
497
+ }
498
+ }
499
+ socketInstance = null;
500
+ socketStatus = 'stopped';
501
+ ++generation; // Invalidate any pending handlers
502
+ }
481
503
  function parseIncomingMessage(msg) {
482
504
  var _a, _b, _c, _d, _e, _f, _g, _h;
483
505
  if (!msg.message || !msg.key || !msg.key.remoteJid)
@@ -12,7 +12,7 @@ class WhatsAppConnect {
12
12
  group: ['transform'],
13
13
  version: 1,
14
14
  subtitle: '={{$parameter["operation"]}}',
15
- description: 'Connect to WhatsApp — scan QR code on first run, then reconnects automatically',
15
+ description: 'Connect to WhatsApp — scan QR code on first run, then disconnects',
16
16
  defaults: { name: 'WhatsApp Connect' },
17
17
  inputs: ['main'],
18
18
  outputs: ['main'],
@@ -41,8 +41,11 @@ class WhatsAppConnect {
41
41
  for (let i = 0; i < items.length; i++) {
42
42
  try {
43
43
  if (operation === 'connect') {
44
- // Non-blocking: returns QR URL immediately if needed, doesn't wait for scan
45
44
  const result = await (0, WhatsAppApiHelper_1.connectOrGetQr)(cfg);
45
+ // If connected, disconnect gracefully to avoid conflict with Send node
46
+ if (result.connected) {
47
+ await (0, WhatsAppApiHelper_1.disconnect)();
48
+ }
46
49
  returnData.push({
47
50
  json: {
48
51
  ...result,
@@ -210,6 +210,8 @@ class WhatsAppSend {
210
210
  throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
211
211
  }
212
212
  }
213
+ // Disconnect after sending — prevents conflict with other n8n workers
214
+ await (0, WhatsAppApiHelper_1.disconnect)();
213
215
  return [returnData];
214
216
  }
215
217
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raevon/n8n-nodes-whatsapp",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "n8n community node for WhatsApp — send and receive messages with anti-ban protection via the Baileys library",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",