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..0c56143fc 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -299,6 +299,31 @@ 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 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 { + 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, {