Skip to content

Commit 0701fb3

Browse files
possebonclaude
andcommitted
fix(chatwoot): prevent message sends when WhatsApp instance is disconnected
Adds 3-layer defense against sending messages through a disconnected Baileys connection, which caused chatwoot to show "failed message" errors: 1. Connection guard in sendMessageWithTyping (universal safety net) 2. Pre-send check in chatwoot receiveWebhook with clear error reporting 3. Reconnection wait (up to 10s) when instance is actively reconnecting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ce12371 commit 0701fb3

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,6 +2308,12 @@ export class BaileysStartupService extends ChannelStartupService {
23082308
options?: Options,
23092309
isIntegration = false,
23102310
) {
2311+
if (this.stateConnection.state !== 'open') {
2312+
throw new BadRequestException(
2313+
`Instance "${this.instance.name}" is not connected (state: ${this.stateConnection.state}). Cannot send message.`,
2314+
);
2315+
}
2316+
23112317
const isWA = (await this.whatsappNumber({ numbers: [number] }))?.shift();
23122318

23132319
if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) {

src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,39 @@ export class ChatwootService {
14511451
return { message: 'bot' };
14521452
}
14531453

1454+
// Layer 2+3: Check connection state before attempting to send
1455+
// If reconnecting, wait briefly for the connection to come back
1456+
if (waInstance?.connectionStatus?.state !== 'open') {
1457+
const currentState = waInstance?.connectionStatus?.state;
1458+
if (currentState === 'connecting') {
1459+
this.logger.verbose(`Instance "${instance.instanceName}" is reconnecting. Waiting up to 10s...`);
1460+
const maxWaitMs = 10_000;
1461+
const pollIntervalMs = 1_000;
1462+
let waited = 0;
1463+
while (waited < maxWaitMs && waInstance?.connectionStatus?.state !== 'open') {
1464+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
1465+
waited += pollIntervalMs;
1466+
}
1467+
}
1468+
1469+
// After waiting (or if state was 'close'), check again
1470+
if (waInstance?.connectionStatus?.state !== 'open') {
1471+
const finalState = waInstance?.connectionStatus?.state;
1472+
this.logger.warn(
1473+
`Instance "${instance.instanceName}" is not connected (state: ${finalState}). Cannot send chatwoot message.`,
1474+
);
1475+
if (body.conversation?.id) {
1476+
this.onSendMessageError(
1477+
instance,
1478+
body.conversation.id,
1479+
`Instance is not connected (state: ${finalState}). Message will not be delivered.`,
1480+
);
1481+
}
1482+
return { message: 'bot' };
1483+
}
1484+
this.logger.verbose(`Instance "${instance.instanceName}" reconnected successfully. Proceeding with send.`);
1485+
}
1486+
14541487
let formatText: string;
14551488
if (senderName === null || senderName === undefined) {
14561489
formatText = messageReceived;

0 commit comments

Comments
 (0)