Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export class BaileysMessageProcessor {
this.subscription = this.messageSubject
.pipe(
tap(({ messages }) => {
this.processorLogs.log(`Processing batch of ${messages.length} messages`);
this.processorLogs.log(`🚀 [BaileysMessageProcessor] Processing batch of ${messages.length} messages`);
messages.forEach((msg, index) => {
this.processorLogs.log(`📱 [BaileysMessageProcessor] Message ${index + 1}: ${msg.key?.remoteJid} - ${msg.message?.conversation || msg.message?.extendedTextMessage?.text || 'NO_TEXT'}`);
});
}),
concatMap(({ messages, type, requestId, settings }) =>
from(onMessageReceive({ messages, type, requestId }, settings)).pipe(
Expand Down
22 changes: 16 additions & 6 deletions src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,10 @@ export class BaileysStartupService extends ChannelStartupService {
settings: any,
) => {
try {
this.logger.log(`🚀 [Baileys] MESSAGES.UPSERT STARTED - type: ${type}, messages: ${messages.length}`);

for (const received of messages) {
this.logger.log(`📱 [Baileys] Processing message: ${received.key.id} from ${received.key.remoteJid} - text: "${received.message?.conversation || received.message?.extendedTextMessage?.text || 'NO_TEXT'}"`);
if (received.key.remoteJid?.includes('@lid') && received.key.senderPn) {
(received.key as { previousRemoteJid?: string | null }).previousRemoteJid = received.key.remoteJid;
received.key.remoteJid = received.key.senderPn;
Expand Down Expand Up @@ -1336,12 +1339,19 @@ export class BaileysStartupService extends ChannelStartupService {

this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw);

await chatbotController.emit({
instance: { instanceName: this.instance.name, instanceId: this.instanceId },
remoteJid: messageRaw.key.remoteJid,
msg: messageRaw,
pushName: messageRaw.pushName,
});
this.logger.log(`🤖 [Baileys] Calling chatbotController.emit for remoteJid: ${messageRaw.key.remoteJid}`);

try {
await chatbotController.emit({
instance: { instanceName: this.instance.name, instanceId: this.instanceId },
remoteJid: messageRaw.key.remoteJid,
msg: messageRaw,
Comment on lines 1339 to +1348
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Error logging may omit stack trace information.

Log the full error object or stack trace to improve error reporting and facilitate debugging.

pushName: messageRaw.pushName,
});
this.logger.log(`✅ [Baileys] chatbotController.emit completed successfully`);
} catch (error) {
this.logger.error(`❌ [Baileys] Error in chatbotController.emit: ${error.message}`);
}

const contact = await this.prismaRepository.contact.findFirst({
where: { remoteJid: received.key.remoteJid, instanceId: this.instanceId },
Expand Down
64 changes: 49 additions & 15 deletions src/api/integrations/chatbot/base-chatbot.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,29 +775,46 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC

// Base implementation for emit
public async emit({ instance, remoteJid, msg }: EmitData) {
if (!this.integrationEnabled) return;
this.logger.log(`🚀 [${this.integrationName}] EMIT STARTED - remoteJid: ${remoteJid}, instance: ${instance.instanceName}`);

if (!this.integrationEnabled) {
this.logger.warn(`❌ [${this.integrationName}] Integration is DISABLED`);
return;
}

try {
this.logger.log(`🔍 [${this.integrationName}] Looking for settings...`);
const settings = await this.settingsRepository.findFirst({
where: {
instanceId: instance.instanceId,
},
});

this.logger.log(`⚙️ [${this.integrationName}] Settings found: ${settings ? 'YES' : 'NO'}`);

if (this.checkIgnoreJids(settings?.ignoreJids, remoteJid)) return;
if (this.checkIgnoreJids(settings?.ignoreJids, remoteJid)) {
this.logger.warn(`🚫 [${this.integrationName}] Message ignored due to ignoreJids`);
return;
}

this.logger.log(`🔍 [${this.integrationName}] Looking for session...`);
const session = await this.getSession(remoteJid, instance);
this.logger.log(`📱 [${this.integrationName}] Session found: ${session ? 'YES' : 'NO'}`);

const content = getConversationMessage(msg);
this.logger.log(`💬 [${this.integrationName}] Content: ${content}`);

// Get integration type
// const integrationType = this.getIntegrationType();

// Find a bot for this message
this.logger.log(`🤖 [${this.integrationName}] Looking for bot trigger...`);
let findBot: any = await this.findBotTrigger(this.botRepository, content, instance, session);
this.logger.log(`🤖 [${this.integrationName}] Bot found: ${findBot ? 'YES' : 'NO'} - ID: ${findBot?.id || 'NONE'}`);

// If no bot is found, try to use fallback
if (!findBot) {
this.logger.warn(`⚠️ [${this.integrationName}] No bot found, trying fallback...`);
const fallback = await this.settingsRepository.findFirst({
where: {
instanceId: instance.instanceId,
Expand All @@ -806,6 +823,7 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC

// Get the fallback ID for this integration type
const fallbackId = this.getFallbackBotId(fallback);
this.logger.log(`🔄 [${this.integrationName}] Fallback ID: ${fallbackId || 'NONE'}`);

if (fallbackId) {
const findFallback = await this.botRepository.findFirst({
Expand All @@ -815,13 +833,16 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
});

findBot = findFallback;
this.logger.log(`🔄 [${this.integrationName}] Fallback bot found: ${findFallback ? 'YES' : 'NO'}`);
} else {
this.logger.warn(`❌ [${this.integrationName}] No fallback bot available`);
return;
}
}

// If we still don't have a bot, return
if (!findBot) {
this.logger.warn(`❌ [${this.integrationName}] Still no bot found, returning`);
return;
}

Expand Down Expand Up @@ -904,29 +925,42 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC

// Process with debounce if needed
if (debounceTime && debounceTime > 0) {
this.logger.log(`⏱️ [${this.integrationName}] Processing with debounce (${debounceTime}s)...`);
this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {
this.logger.log(`🚀 [${this.integrationName}] Debounce complete! Calling processBot...`);
try {
await this.processBot(
this.waMonitor.waInstances[instance.instanceName],
remoteJid,
findBot,
session,
mergedSettings,
debouncedContent,
msg?.pushName,
msg,
);
this.logger.log(`✅ [${this.integrationName}] processBot completed successfully`);
} catch (error) {
this.logger.error(`❌ [${this.integrationName}] Error in processBot: ${error.message}`);
}
});
} else {
this.logger.log(`🚀 [${this.integrationName}] Processing without debounce...`);
try {
await this.processBot(
this.waMonitor.waInstances[instance.instanceName],
remoteJid,
findBot,
session,
mergedSettings,
debouncedContent,
content,
msg?.pushName,
msg,
);
});
} else {
await this.processBot(
this.waMonitor.waInstances[instance.instanceName],
remoteJid,
findBot,
session,
mergedSettings,
content,
msg?.pushName,
msg,
);
this.logger.log(`✅ [${this.integrationName}] processBot completed successfully`);
} catch (error) {
this.logger.error(`❌ [${this.integrationName}] Error in processBot: ${error.message}`);
}
}
} catch (error) {
this.logger.error(error);
Expand Down
49 changes: 36 additions & 13 deletions src/api/integrations/chatbot/chatbot.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,26 +84,49 @@ export class ChatbotController {
pushName?: string;
isIntegration?: boolean;
}): Promise<void> {
this.logger.log(`🚀 [ChatbotController] EMIT STARTED - remoteJid: ${remoteJid}, instance: ${instance.instanceName}`);

const emitData = {
instance,
remoteJid,
msg,
pushName,
isIntegration,
};
await evolutionBotController.emit(emitData);

await typebotController.emit(emitData);

await openaiController.emit(emitData);

await difyController.emit(emitData);

await n8nController.emit(emitData);

await evoaiController.emit(emitData);

await flowiseController.emit(emitData);

try {
this.logger.log(`🤖 [ChatbotController] Calling evolutionBotController.emit...`);
await evolutionBotController.emit(emitData);
this.logger.log(`✅ [ChatbotController] evolutionBotController.emit completed`);

this.logger.log(`🤖 [ChatbotController] Calling typebotController.emit...`);
await typebotController.emit(emitData);
this.logger.log(`✅ [ChatbotController] typebotController.emit completed`);

this.logger.log(`🤖 [ChatbotController] Calling openaiController.emit...`);
await openaiController.emit(emitData);
this.logger.log(`✅ [ChatbotController] openaiController.emit completed`);

this.logger.log(`🤖 [ChatbotController] Calling difyController.emit...`);
await difyController.emit(emitData);
this.logger.log(`✅ [ChatbotController] difyController.emit completed`);

this.logger.log(`🤖 [ChatbotController] Calling n8nController.emit...`);
await n8nController.emit(emitData);
this.logger.log(`✅ [ChatbotController] n8nController.emit completed`);

this.logger.log(`🤖 [ChatbotController] Calling evoaiController.emit...`);
await evoaiController.emit(emitData);
this.logger.log(`✅ [ChatbotController] evoaiController.emit completed`);

this.logger.log(`🤖 [ChatbotController] Calling flowiseController.emit...`);
await flowiseController.emit(emitData);
this.logger.log(`✅ [ChatbotController] flowiseController.emit completed`);

this.logger.log(`🎉 [ChatbotController] All controllers completed successfully`);
} catch (error) {
this.logger.error(`❌ [ChatbotController] Error in emit: ${error.message}`);
}
}

public processDebounce(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export class OpenaiService extends BaseChatbotService<OpenaiBot, OpenaiSetting>
msg?: any,
): Promise<void> {
try {
this.logger.log(`Starting process for remoteJid: ${remoteJid}, bot type: ${openaiBot.botType}`);
this.logger.log(`🚀 [OpenaiService] PROCESS STARTED - remoteJid: ${remoteJid}, bot type: ${openaiBot.botType}`);
this.logger.log(`🤖 [OpenaiService] Bot ID: ${openaiBot.id}, enabled: ${openaiBot.enabled}`);
this.logger.log(`💬 [OpenaiService] Content: "${content}"`);
this.logger.log(`📱 [OpenaiService] Session: ${session ? 'EXISTS' : 'NEW'}`);

// Handle audio message transcription
if (content.startsWith('audioMessage|') && msg) {
Expand Down
5 changes: 5 additions & 0 deletions src/utils/findBotByTrigger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { advancedOperatorsSearch } from './advancedOperatorsSearch';

export const findBotByTrigger = async (botRepository: any, content: string, instanceId: string) => {
console.log(`🔍 [findBotByTrigger] Searching for bot - content: "${content}", instanceId: ${instanceId}`);

// Check for triggerType 'all' or 'none' (both should match any message)
const findTriggerAllOrNone = await botRepository.findFirst({
where: {
Expand All @@ -12,7 +14,10 @@ export const findBotByTrigger = async (botRepository: any, content: string, inst
},
});

console.log(`🤖 [findBotByTrigger] All/None trigger found: ${findTriggerAllOrNone ? 'YES' : 'NO'} - ID: ${findTriggerAllOrNone?.id || 'NONE'}`);

if (findTriggerAllOrNone) {
console.log(`✅ [findBotByTrigger] Returning bot with triggerType: ${findTriggerAllOrNone.triggerType}`);
Comment on lines 14 to +20
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Use of console.log for logging may be inconsistent with other logger usage.

Replace console.log with the project's structured logger to ensure consistent logging and log level management.

Suggested implementation:

import { advancedOperatorsSearch } from './advancedOperatorsSearch';
import { logger } from '../logger';

export const findBotByTrigger = async (botRepository: any, content: string, instanceId: string) => {
  logger.info(`🔍 [findBotByTrigger] Searching for bot - content: "${content}", instanceId: ${instanceId}`);

  // Check for triggerType 'all' or 'none' (both should match any message)
  const findTriggerAllOrNone = await botRepository.findFirst({
    where: {
    },
  });

  logger.info(`🤖 [findBotByTrigger] All/None trigger found: ${findTriggerAllOrNone ? 'YES' : 'NO'} - ID: ${findTriggerAllOrNone?.id || 'NONE'}`);

  if (findTriggerAllOrNone) {
    logger.info(`✅ [findBotByTrigger] Returning bot with triggerType: ${findTriggerAllOrNone.triggerType}`);
    return findTriggerAllOrNone;

If your logger uses a different import path or method (e.g., import logger from ... or logger.log('info', ...)), adjust the import and usage accordingly.

return findTriggerAllOrNone;
}

Expand Down