From d9d2ff1e6b9ce14dc0d57bddd1a7f0f871094c4a Mon Sep 17 00:00:00 2001 From: Wahyu Saputra Date: Mon, 8 Dec 2025 15:41:16 +0700 Subject: [PATCH 1/2] Add gated Baileys connection update logging --- CHANGELOG.md | 1 + .../whatsapp/whatsapp.baileys.service.ts | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f1dfeb46..6c1abd444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * [WIDGET-WORKS] Skip Chatwoot sync in `messages.upsert` when a message key already has `chatwootMessageId` (handles Chatwoot automation echoes/duplicates). * [WIDGET-WORKS] Avoid dropping group conversations when Chatwoot `updateContact` fails by logging the error and continuing with the existing contact. * [WIDGET-WORKS] Link template messages to Chatwoot to prevent echo duplicates (fixes "Pending Message" duplicate attribution for automated greetings). +* [WIDGET-WORKS] Add LOG_BAILEYS-gated Baileys `connection.update` logging (state, disconnect codes, close reason) to diagnose session drops. ### Features diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index ac221411f..05c8fea10 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -299,6 +299,29 @@ export class BaileysStartupService extends ChannelStartupService { } private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { + const logBaileysEnv = (process.env.LOG_BAILEYS ?? '').toLowerCase(); + const shouldLogConnectionUpdate = ['true', 'debug', 'trace'].includes(logBaileysEnv); + if (shouldLogConnectionUpdate) { + const lastDisconnectError = lastDisconnect?.error as Boom; + const statusCode = lastDisconnectError?.output?.statusCode; + const disconnectData = lastDisconnectError?.data; + const wsCloseCode = this.client?.ws?.closeCode; + const wsCloseReason = this.client?.ws?.closeReason; + let serializedDisconnectData = 'n/a'; + if (disconnectData) { + try { + serializedDisconnectData = JSON.stringify(disconnectData); + } catch { + serializedDisconnectData = '[unserializable]'; + } + } + + // [WIDGET-WORKS] Emit detailed Baileys connection updates when LOG_BAILEYS is enabled. + this.logger.warn( + `[WIDGET-WORKS] Baileys connection.update | instance=${this.instance.name} id=${this.instanceId} state=${connection ?? 'unknown'} statusCode=${statusCode ?? 'n/a'} wsCloseCode=${wsCloseCode ?? 'n/a'} wsCloseReason=${wsCloseReason ?? 'n/a'} disconnectData=${serializedDisconnectData}`, + ); + } + if (qr) { if (this.instance.qrcode.count === this.configService.get('QRCODE').LIMIT) { this.sendDataWebhook(Events.QRCODE_UPDATED, { From f5379f40899905ce2d36e21808d99b58daaaa2e6 Mon Sep 17 00:00:00 2001 From: Wahyu Saputra Date: Mon, 8 Dec 2025 15:45:03 +0700 Subject: [PATCH 2/2] Handle ws close metadata safely in Baileys logging --- .../channel/whatsapp/whatsapp.baileys.service.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 05c8fea10..0c56143fc 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -305,8 +305,10 @@ export class BaileysStartupService extends ChannelStartupService { const lastDisconnectError = lastDisconnect?.error as Boom; const statusCode = lastDisconnectError?.output?.statusCode; const disconnectData = lastDisconnectError?.data; - const wsCloseCode = this.client?.ws?.closeCode; - const wsCloseReason = this.client?.ws?.closeReason; + const wsSocket = this.client?.ws as any; + // [WIDGET-WORKS] ws from Baileys' WebSocketClient does not expose close metadata in typings; pull from runtime if present. + const wsCloseCode = wsSocket?.closeCode ?? wsSocket?._closeCode ?? wsSocket?.ws?.closeCode; + const wsCloseReason = wsSocket?.closeReason ?? wsSocket?._closeMessage ?? wsSocket?.ws?.closeReason; let serializedDisconnectData = 'n/a'; if (disconnectData) { try {