@raevon/n8n-nodes-whatsapp 1.0.12 → 1.0.14

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.
@@ -60,5 +60,6 @@ export declare function getConnectionStatus(): {
60
60
  dailyLimit: number;
61
61
  lastError: string | null;
62
62
  };
63
+ export declare function disconnect(): Promise<void>;
63
64
  export declare function parseIncomingMessage(msg: any): Record<string, any> | null;
64
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"));
@@ -485,6 +486,20 @@ function getConnectionStatus() {
485
486
  lastError: lastDisconnectError,
486
487
  };
487
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
+ }
488
503
  function parseIncomingMessage(msg) {
489
504
  var _a, _b, _c, _d, _e, _f, _g, _h;
490
505
  if (!msg.message || !msg.key || !msg.key.remoteJid)
@@ -1,8 +1,18 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.WhatsAppConnect = void 0;
4
7
  const n8n_workflow_1 = require("n8n-workflow");
5
8
  const WhatsAppApiHelper_1 = require("./WhatsAppApiHelper");
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ function expandHome(p) {
12
+ if (!p.startsWith('~'))
13
+ return p;
14
+ return node_path_1.default.join(process.env.HOME || process.env.USERPROFILE || '', p.slice(1));
15
+ }
6
16
  class WhatsAppConnect {
7
17
  constructor() {
8
18
  this.description = {
@@ -12,7 +22,7 @@ class WhatsAppConnect {
12
22
  group: ['transform'],
13
23
  version: 1,
14
24
  subtitle: '={{$parameter["operation"]}}',
15
- description: 'Connect to WhatsApp — scan QR code on first run, then reconnects automatically',
25
+ description: 'Connect to WhatsApp — scan QR code on first run, then disconnects',
16
26
  defaults: { name: 'WhatsApp Connect' },
17
27
  inputs: ['main'],
18
28
  outputs: ['main'],
@@ -26,6 +36,7 @@ class WhatsAppConnect {
26
36
  options: [
27
37
  { name: 'Connect', value: 'connect', description: 'Connect to WhatsApp (scan QR on first run)', action: 'Connect to WhatsApp' },
28
38
  { name: 'Get Status', value: 'status', description: 'Get current connection status', action: 'Get connection status' },
39
+ { name: 'Sign Out', value: 'signOut', description: 'Sign out and delete session (requires re-scan QR)', action: 'Sign out of WhatsApp' },
29
40
  ],
30
41
  default: 'connect',
31
42
  },
@@ -41,8 +52,11 @@ class WhatsAppConnect {
41
52
  for (let i = 0; i < items.length; i++) {
42
53
  try {
43
54
  if (operation === 'connect') {
44
- // Non-blocking: returns QR URL immediately if needed, doesn't wait for scan
45
55
  const result = await (0, WhatsAppApiHelper_1.connectOrGetQr)(cfg);
56
+ // If connected, disconnect gracefully to avoid conflict with Send node
57
+ if (result.connected) {
58
+ await (0, WhatsAppApiHelper_1.disconnect)();
59
+ }
46
60
  returnData.push({
47
61
  json: {
48
62
  ...result,
@@ -61,6 +75,27 @@ class WhatsAppConnect {
61
75
  pairedItem: { item: i },
62
76
  });
63
77
  }
78
+ else if (operation === 'signOut') {
79
+ // Disconnect first
80
+ await (0, WhatsAppApiHelper_1.disconnect)();
81
+ // Delete session files
82
+ const resolvedPath = expandHome(cfg.sessionPath);
83
+ if (node_fs_1.default.existsSync(resolvedPath)) {
84
+ const files = node_fs_1.default.readdirSync(resolvedPath);
85
+ for (const file of files) {
86
+ node_fs_1.default.unlinkSync(node_path_1.default.join(resolvedPath, file));
87
+ }
88
+ node_fs_1.default.rmdirSync(resolvedPath);
89
+ }
90
+ returnData.push({
91
+ json: {
92
+ success: true,
93
+ message: 'Signed out. Session deleted. Run Connect to scan QR again.',
94
+ sessionPath: cfg.sessionPath,
95
+ },
96
+ pairedItem: { item: i },
97
+ });
98
+ }
64
99
  }
65
100
  catch (error) {
66
101
  if (this.continueOnFail()) {
@@ -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.12",
3
+ "version": "1.0.14",
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",