@@ -1325,6 +1325,35 @@ export class ChatwootService {
13251325 this . cache . delete ( keyToDelete ) ;
13261326 }
13271327
1328+ // Coordination: close paused bot sessions when conversation is resolved in Chatwoot
1329+ // This allows the bot to start a new session on the next incoming message
1330+ if ( body . event === 'conversation_status_changed' && body . status === 'resolved' && body . meta ?. sender ?. identifier ) {
1331+ const resolvedInstanceId = ( this . waMonitor . waInstances [ instance . instanceName ] ) ?. instanceId || instance . instanceId ;
1332+ const resolvedChatId = body . meta . sender . identifier ;
1333+ ( async ( ) => {
1334+ try {
1335+ const remoteJid = resolvedChatId . includes ( '@' ) ? resolvedChatId : `${ resolvedChatId } @s.whatsapp.net` ;
1336+ const closedSessions = await this . prismaRepository . integrationSession . updateMany ( {
1337+ where : {
1338+ instanceId : resolvedInstanceId ,
1339+ remoteJid : remoteJid ,
1340+ status : 'paused' ,
1341+ } ,
1342+ data : {
1343+ status : 'closed' ,
1344+ } ,
1345+ } ) ;
1346+ if ( closedSessions . count > 0 ) {
1347+ this . logger . verbose (
1348+ `[Coordination] Closed ${ closedSessions . count } paused bot session(s) for ${ remoteJid } - conversation resolved in Chatwoot` ,
1349+ ) ;
1350+ }
1351+ } catch ( error ) {
1352+ this . logger . error ( `[Coordination] Error closing paused sessions on resolve: ${ error ?. message } ` ) ;
1353+ }
1354+ } ) ( ) ;
1355+ }
1356+
13281357 if (
13291358 ! body ?. conversation ||
13301359 body . private ||
@@ -1452,41 +1481,57 @@ export class ChatwootService {
14521481 }
14531482
14541483 // Coordination: pause active bot sessions when human agent responds from Chatwoot
1484+ // Fire-and-forget to avoid blocking the webhook response (Chatwoot has a 5s timeout)
14551485 // Respects autoPause config (global env var + per-instance override)
1456- try {
1457- let shouldAutoPause = true ;
1486+ const coordInstanceId = instance . instanceId ;
1487+ const coordChatId = chatId ;
1488+ ( async ( ) => {
14581489 try {
1459- // eslint-disable-next-line @typescript-eslint/no-var-requires
1460- const { chatbotChatwootService } = require ( '@api/server.module' ) ;
1461- if ( chatbotChatwootService ) {
1462- const config = await chatbotChatwootService . getCoordinationConfig ( instance . instanceId ) ;
1463- shouldAutoPause = config . autoPause ;
1490+ let shouldAutoPause = true ;
1491+ try {
1492+ // eslint-disable-next-line @typescript-eslint/no-var-requires
1493+ const { chatbotChatwootService } = require ( '@api/server.module' ) ;
1494+ if ( chatbotChatwootService ) {
1495+ const config = await chatbotChatwootService . getCoordinationConfig ( coordInstanceId ) ;
1496+ shouldAutoPause = config . autoPause ;
1497+ }
1498+ } catch {
1499+ // If service not available, use default (true)
14641500 }
1465- } catch {
1466- // If service not available, use default (true)
1467- }
14681501
1469- if ( shouldAutoPause ) {
1470- const remoteJidForSession = chatId . includes ( '@' ) ? chatId : `${ chatId } @s.whatsapp.net` ;
1471- const pausedSessions = await this . prismaRepository . integrationSession . updateMany ( {
1472- where : {
1473- instanceId : instance . instanceId ,
1474- remoteJid : remoteJidForSession ,
1475- status : 'opened' ,
1476- } ,
1477- data : {
1478- status : 'paused' ,
1479- } ,
1480- } ) ;
1481- if ( pausedSessions . count > 0 ) {
1482- this . logger . verbose (
1483- `[Coordination] Paused ${ pausedSessions . count } bot session(s) for ${ remoteJidForSession } - human agent responded from Chatwoot` ,
1484- ) ;
1502+ if ( shouldAutoPause ) {
1503+ const remoteJidForSession = coordChatId . includes ( '@' ) ? coordChatId : `${ coordChatId } @s.whatsapp.net` ;
1504+ const pausedSessions = await this . prismaRepository . integrationSession . updateMany ( {
1505+ where : {
1506+ instanceId : coordInstanceId ,
1507+ remoteJid : remoteJidForSession ,
1508+ status : 'opened' ,
1509+ } ,
1510+ data : {
1511+ status : 'paused' ,
1512+ } ,
1513+ } ) ;
1514+ if ( pausedSessions . count > 0 ) {
1515+ this . logger . verbose (
1516+ `[Coordination] Paused ${ pausedSessions . count } bot session(s) for ${ remoteJidForSession } - human agent responded from Chatwoot` ,
1517+ ) ;
1518+
1519+ // Open the Chatwoot conversation so the agent can handle it
1520+ try {
1521+ // eslint-disable-next-line @typescript-eslint/no-var-requires
1522+ const { chatbotChatwootService : coordService } = require ( '@api/server.module' ) ;
1523+ if ( coordService ) {
1524+ await coordService . updateChatwootConversationStatus ( coordInstanceId , remoteJidForSession , 'open' ) ;
1525+ }
1526+ } catch ( err ) {
1527+ this . logger . error ( `[Coordination] Error opening conversation after pause: ${ err ?. message } ` ) ;
1528+ }
1529+ }
14851530 }
1531+ } catch ( error ) {
1532+ this . logger . error ( `[Coordination] Error pausing bot sessions: ${ error ?. message } ` ) ;
14861533 }
1487- } catch ( error ) {
1488- this . logger . error ( `[Coordination] Error pausing bot sessions: ${ error ?. message } ` ) ;
1489- }
1534+ } ) ( ) ;
14901535
14911536 let formatText : string ;
14921537 if ( senderName === null || senderName === undefined ) {
0 commit comments