@@ -11,6 +11,22 @@ import { getConversationMessage } from '@utils/getConversationMessage';
1111import { BaseChatbotDto } from './base-chatbot.dto' ;
1212import { ChatbotController , ChatbotControllerInterface , EmitData } from './chatbot.controller' ;
1313
14+ // Lazy getter to avoid circular dependency at module load time
15+ // chatbotChatwootService is resolved at runtime when emit() is called
16+ let _chatbotChatwootService : any = null ;
17+ function getChatbotChatwootService ( ) {
18+ if ( ! _chatbotChatwootService ) {
19+ try {
20+ // eslint-disable-next-line @typescript-eslint/no-var-requires
21+ const mod = require ( '@api/server.module' ) ;
22+ _chatbotChatwootService = mod . chatbotChatwootService ;
23+ } catch {
24+ return null ;
25+ }
26+ }
27+ return _chatbotChatwootService ;
28+ }
29+
1430// Common settings interface for all chatbot integrations
1531export interface ChatbotSettings {
1632 expire : number ;
@@ -789,26 +805,36 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
789805 if ( ! this . integrationEnabled ) return ;
790806
791807 try {
808+ this . logger . log ( `[${ this . integrationName } ] emit() called for remoteJid: ${ remoteJid } , instanceId: ${ instance . instanceId } ` ) ;
809+
792810 const settings = await this . settingsRepository . findFirst ( {
793811 where : {
794812 instanceId : instance . instanceId ,
795813 } ,
796814 } ) ;
815+ this . logger . log ( `[${ this . integrationName } ] settings found: ${ ! ! settings } ` ) ;
797816
798- if ( this . checkIgnoreJids ( settings ?. ignoreJids , remoteJid ) ) return ;
817+ if ( this . checkIgnoreJids ( settings ?. ignoreJids , remoteJid ) ) {
818+ this . logger . log ( `[${ this . integrationName } ] remoteJid IGNORED by ignoreJids` ) ;
819+ return ;
820+ }
799821
800- const session = await this . getSession ( remoteJid , instance ) ;
822+ let session = await this . getSession ( remoteJid , instance ) ;
823+ this . logger . log ( `[${ this . integrationName } ] session: id=${ session ?. id } , status=${ session ?. status } , botId=${ session ?. botId } ` ) ;
801824
802825 const content = getConversationMessage ( msg ) ;
826+ this . logger . log ( `[${ this . integrationName } ] content extracted: "${ content } "` ) ;
803827
804828 // Get integration type
805829 // const integrationType = this.getIntegrationType();
806830
807831 // Find a bot for this message
808832 let findBot : any = await this . findBotTrigger ( this . botRepository , content , instance , session ) ;
833+ this . logger . log ( `[${ this . integrationName } ] findBot: id=${ findBot ?. id } , triggerType=${ findBot ?. triggerType } , enabled=${ findBot ?. enabled } ` ) ;
809834
810835 // If no bot is found, try to use fallback
811836 if ( ! findBot ) {
837+ this . logger . log ( `[${ this . integrationName } ] no bot found, trying fallback...` ) ;
812838 const fallback = await this . settingsRepository . findFirst ( {
813839 where : {
814840 instanceId : instance . instanceId ,
@@ -826,16 +852,21 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
826852 } ) ;
827853
828854 findBot = findFallback ;
855+ this . logger . log ( `[${ this . integrationName } ] fallback bot found: ${ ! ! findFallback } ` ) ;
829856 } else {
857+ this . logger . log ( `[${ this . integrationName } ] no fallback configured, returning` ) ;
830858 return ;
831859 }
832860 }
833861
834862 // If we still don't have a bot, return
835863 if ( ! findBot ) {
864+ this . logger . log ( `[${ this . integrationName } ] no bot found after fallback, returning` ) ;
836865 return ;
837866 }
838867
868+ this . logger . log ( `[${ this . integrationName } ] processing bot: ${ findBot . id } , expire=${ findBot . expire } , debounce=${ findBot . debounceTime } ` ) ;
869+
839870 // Collect settings with fallbacks to default settings
840871 let expire = findBot . expire ;
841872 let keywordFinish = findBot . keywordFinish ;
@@ -868,6 +899,8 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
868899 participant : string ;
869900 } ;
870901
902+ this . logger . log ( `[${ this . integrationName } ] key: fromMe=${ key . fromMe } , remoteJid=${ key . remoteJid } ` ) ;
903+
871904 // Handle stopping the bot if message is from me
872905 if ( stopBotFromMe && key . fromMe && session ) {
873906 await this . prismaRepository . integrationSession . update ( {
@@ -893,12 +926,38 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
893926
894927 // Skip if not listening to messages from me
895928 if ( ! listeningFromMe && key . fromMe ) {
929+ this . logger . log ( `[${ this . integrationName } ] skipping: fromMe=true, listeningFromMe=false` ) ;
896930 return ;
897931 }
898932
899- // Skip if session exists but not awaiting user input
933+ // If session is closed, nullify it so processBot treats it as a new conversation
900934 if ( session && session . status === 'closed' ) {
901- return ;
935+ this . logger . log ( `[${ this . integrationName } ] session is closed, nullifying to start new conversation` ) ;
936+ session = null ;
937+ }
938+
939+ // Coordination layer: check if Chatwoot has a human agent assigned
940+ // If so, the bot should not process this message
941+ const coordinationService = getChatbotChatwootService ( ) ;
942+ if ( coordinationService ?. isEnabled ( ) && msg ?. chatwootConversationId ) {
943+ const hasHuman = await coordinationService . hasHumanAgentAssigned (
944+ instance . instanceId ,
945+ msg . chatwootConversationId ,
946+ ) ;
947+ if ( hasHuman ) {
948+ this . logger . log (
949+ `[${ this . integrationName } ] Chatwoot conversation ${ msg . chatwootConversationId } has human agent, skipping bot` ,
950+ ) ;
951+ // If there's an active bot session, pause it
952+ if ( session && session . status === 'opened' ) {
953+ await this . prismaRepository . integrationSession . update ( {
954+ where : { id : session . id } ,
955+ data : { status : 'paused' } ,
956+ } ) ;
957+ this . logger . log ( `[${ this . integrationName } ] Paused bot session ${ session . id } due to human agent` ) ;
958+ }
959+ return ;
960+ }
902961 }
903962
904963 // Merged settings
@@ -917,6 +976,8 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
917976 timePerChar,
918977 } ;
919978
979+ this . logger . log ( `[${ this . integrationName } ] proceeding to processBot, debounceTime=${ debounceTime } ` ) ;
980+
920981 // Process with debounce if needed
921982 if ( debounceTime && debounceTime > 0 ) {
922983 this . processDebounce ( this . userMessageDebounce , content , remoteJid , debounceTime , async ( debouncedContent ) => {
@@ -944,7 +1005,8 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
9441005 ) ;
9451006 }
9461007 } catch ( error ) {
947- this . logger . error ( error ) ;
1008+ this . logger . error ( `[${ this . integrationName } ] emit() ERROR: ${ error ?. message || error } ` ) ;
1009+ this . logger . error ( error ?. stack || error ) ;
9481010 }
9491011 }
9501012}
0 commit comments