@raevon/n8n-nodes-whatsapp 1.0.7 → 1.0.9

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.
@@ -123,8 +123,16 @@ async function scheduleReconnect(cfg) {
123
123
  }, delay);
124
124
  }
125
125
  async function initSocket(cfg, authPath) {
126
- if (socketInstance && socketStatus === 'connected')
127
- return socketInstance;
126
+ // Always create fresh socket if current one is dead
127
+ if (socketInstance && socketStatus === 'connected') {
128
+ try {
129
+ if (socketInstance.user)
130
+ return socketInstance;
131
+ }
132
+ catch {
133
+ // Socket dead, create new one
134
+ }
135
+ }
128
136
  const gen = ++generation; // #10: Snapshot generation for this connection attempt
129
137
  const resolvedPath = expandHome(authPath);
130
138
  if (!node_fs_1.default.existsSync(resolvedPath)) {
@@ -176,16 +184,20 @@ async function initSocket(cfg, authPath) {
176
184
  socketStatus = 'connected';
177
185
  reconnectAttempts = 0;
178
186
  latestQr = null;
187
+ console.log('[WhatsApp] Connected successfully');
179
188
  return;
180
189
  }
181
190
  if (connection === 'close') {
182
191
  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;
192
+ const reason = baileys_1.DisconnectReason[code] || 'Unknown';
193
+ console.log(`[WhatsApp] Connection closed: ${reason} (code: ${code})`);
183
194
  if (code === baileys_1.DisconnectReason.loggedOut) {
184
195
  socketStatus = 'logged_out';
185
196
  socketInstance = null;
186
197
  ++generation; // #10: Invalidate all handlers from this session
187
198
  }
188
199
  else {
200
+ socketStatus = 'disconnected';
189
201
  socketInstance = null;
190
202
  scheduleReconnect(cfg);
191
203
  }
@@ -210,8 +222,6 @@ async function getWhatsAppCredentials(credentials) {
210
222
  };
211
223
  }
212
224
  async function ensureConnected(cfg) {
213
- if (socketStatus === 'connected' && socketInstance)
214
- return socketInstance;
215
225
  const antiBanCfg = {
216
226
  messageDelayMinMs: cfg.messageDelayMinMs,
217
227
  messageDelayMaxMs: cfg.messageDelayMaxMs,
@@ -228,42 +238,46 @@ async function ensureConnected(cfg) {
228
238
  if (!queue) {
229
239
  queue = new p_queue_1.default({ concurrency: 1 });
230
240
  }
231
- // Check if session already exists
241
+ // Check if session exists on disk
232
242
  const resolvedPath = expandHome(cfg.sessionPath);
233
243
  const hasSession = node_fs_1.default.existsSync(resolvedPath) && node_fs_1.default.readdirSync(resolvedPath).length > 0;
234
- const sock = await initSocket(antiBanCfg, cfg.sessionPath);
235
- // If no session, wait for QR with a reasonable timeout
236
244
  if (!hasSession) {
237
- const qrData = await new Promise((resolve) => {
238
- qrResolve = resolve;
239
- // 90 second timeout — QR codes expire quickly, user needs to act fast
240
- setTimeout(() => {
241
- if (qrResolve) {
242
- qrResolve(null);
243
- qrResolve = null;
244
- }
245
- }, 90000);
245
+ throw new n8n_workflow_1.NodeApiError({}, {
246
+ message: 'No WhatsApp session found. Run the WhatsApp Connect node first to scan QR code.',
246
247
  });
247
- if (!qrData) {
248
- throw new n8n_workflow_1.NodeApiError({}, {
249
- message: 'QR code expired. Run the Connect node again to get a new QR code.',
250
- });
248
+ }
249
+ // Check if current socket is actually alive
250
+ if (socketInstance && socketStatus === 'connected') {
251
+ try {
252
+ if (socketInstance.user) {
253
+ console.log('[WhatsApp] Reusing existing connection');
254
+ return socketInstance;
255
+ }
251
256
  }
252
- // Wait for connection to open after scan (30s timeout)
253
- await new Promise((resolve, reject) => {
254
- const timeout = setTimeout(() => reject(new Error('Connection timeout — QR was scanned but connection did not open in time')), 30000);
255
- const checkInterval = setInterval(() => {
256
- if (socketStatus === 'connected') {
257
- clearTimeout(timeout);
258
- clearInterval(checkInterval);
259
- resolve();
260
- }
261
- if (socketStatus === 'logged_out' || socketStatus === 'error') {
262
- clearTimeout(timeout);
263
- clearInterval(checkInterval);
264
- reject(new Error('Connection failed after QR scan'));
265
- }
266
- }, 1000);
257
+ catch {
258
+ console.log('[WhatsApp] Existing socket is dead, reconnecting...');
259
+ }
260
+ }
261
+ // Session exists connect using saved credentials
262
+ console.log('[WhatsApp] Connecting from saved session...');
263
+ const sock = await initSocket(antiBanCfg, cfg.sessionPath);
264
+ // Wait for connection to open (up to 20s)
265
+ const connected = await new Promise((resolve) => {
266
+ const check = setInterval(() => {
267
+ if (socketStatus === 'connected') {
268
+ clearInterval(check);
269
+ resolve(true);
270
+ }
271
+ if (socketStatus === 'logged_out' || socketStatus === 'error') {
272
+ clearInterval(check);
273
+ resolve(false);
274
+ }
275
+ }, 500);
276
+ setTimeout(() => { clearInterval(check); resolve(false); }, 20000);
277
+ });
278
+ if (!connected) {
279
+ throw new n8n_workflow_1.NodeApiError({}, {
280
+ message: `WhatsApp connection failed (status: ${socketStatus}). Try running Connect node again.`,
267
281
  });
268
282
  }
269
283
  return sock;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raevon/n8n-nodes-whatsapp",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
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",