Merge pull request #1986 from dersonbsb2022/main
Some checks failed
Check Code Quality / check-lint-and-build (push) Has been cancelled
Build Docker image / Build and Deploy (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled

fix(evolutionbot):  Fixing the correct message sending method so that messages are split.
This commit is contained in:
Davidson Gomes
2025-09-22 08:02:11 -03:00
committed by GitHub
9 changed files with 419 additions and 109 deletions

View File

@@ -180,6 +180,7 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
remoteJid: string,
message: string,
settings: SettingsType,
linkPreview: boolean = true,
): Promise<void> {
if (!message) return;
@@ -202,7 +203,7 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
if (mediaType) {
// Send accumulated text before sending media
if (textBuffer.trim()) {
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages);
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages, linkPreview);
textBuffer = '';
}
@@ -252,7 +253,56 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
// Send any remaining text
if (textBuffer.trim()) {
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages);
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages, linkPreview);
}
}
/**
* Split message by double line breaks and return array of message parts
*/
private splitMessageByDoubleLineBreaks(message: string): string[] {
return message.split('\n\n').filter((part) => part.trim().length > 0);
}
/**
* Send a single message with proper typing indicators and delays
*/
private async sendSingleMessage(
instance: any,
remoteJid: string,
message: string,
settings: any,
linkPreview: boolean = true,
): Promise<void> {
const timePerChar = settings?.timePerChar ?? 0;
const minDelay = 1000;
const maxDelay = 20000;
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
this.logger.debug(`[BaseChatbot] Sending single message with linkPreview: ${linkPreview}`);
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
await instance.client.presenceSubscribe(remoteJid);
await instance.client.sendPresenceUpdate('composing', remoteJid);
}
await new Promise<void>((resolve) => {
setTimeout(async () => {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: message,
linkPreview,
},
false,
);
resolve();
}, delay);
});
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
await instance.client.sendPresenceUpdate('paused', remoteJid);
}
}
@@ -265,67 +315,24 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
text: string,
settings: any,
splitMessages: boolean,
linkPreview: boolean = true,
): Promise<void> {
const timePerChar = settings?.timePerChar ?? 0;
const minDelay = 1000;
const maxDelay = 20000;
if (splitMessages) {
const multipleMessages = text.split('\n\n');
for (let index = 0; index < multipleMessages.length; index++) {
const message = multipleMessages[index];
if (!message.trim()) continue;
const messageParts = this.splitMessageByDoubleLineBreaks(text);
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
this.logger.debug(`[BaseChatbot] Splitting message into ${messageParts.length} parts`);
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
await instance.client.presenceSubscribe(remoteJid);
await instance.client.sendPresenceUpdate('composing', remoteJid);
}
for (let index = 0; index < messageParts.length; index++) {
const message = messageParts[index];
await new Promise<void>((resolve) => {
setTimeout(async () => {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: message,
},
false,
);
resolve();
}, delay);
});
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
await instance.client.sendPresenceUpdate('paused', remoteJid);
}
this.logger.debug(`[BaseChatbot] Sending message part ${index + 1}/${messageParts.length}`);
await this.sendSingleMessage(instance, remoteJid, message, settings, linkPreview);
}
this.logger.debug(`[BaseChatbot] All message parts sent successfully`);
} else {
const delay = Math.min(Math.max(text.length * timePerChar, minDelay), maxDelay);
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
await instance.client.presenceSubscribe(remoteJid);
await instance.client.sendPresenceUpdate('composing', remoteJid);
}
await new Promise<void>((resolve) => {
setTimeout(async () => {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: text,
},
false,
);
resolve();
}, delay);
});
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
await instance.client.sendPresenceUpdate('paused', remoteJid);
}
this.logger.debug(`[BaseChatbot] Sending single message`);
await this.sendSingleMessage(instance, remoteJid, text, settings, linkPreview);
}
}

View File

@@ -128,7 +128,7 @@ export class DifyService extends BaseChatbotService<Dify, DifySetting> {
const conversationId = response?.data?.conversation_id;
if (message) {
await this.sendMessageWhatsApp(instance, remoteJid, message, settings);
await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);
}
await this.prismaRepository.integrationSession.update({
@@ -210,7 +210,7 @@ export class DifyService extends BaseChatbotService<Dify, DifySetting> {
const conversationId = response?.data?.conversation_id;
if (message) {
await this.sendMessageWhatsApp(instance, remoteJid, message, settings);
await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);
}
await this.prismaRepository.integrationSession.update({
@@ -298,7 +298,7 @@ export class DifyService extends BaseChatbotService<Dify, DifySetting> {
await instance.client.sendPresenceUpdate('paused', remoteJid);
if (answer) {
await this.sendMessageWhatsApp(instance, remoteJid, answer, settings);
await this.sendMessageWhatsApp(instance, remoteJid, answer, settings, true);
}
await this.prismaRepository.integrationSession.update({

View File

@@ -195,7 +195,7 @@ export class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {
this.logger.debug(`[EvoAI] Extracted message to send: ${message}`);
if (message) {
await this.sendMessageWhatsApp(instance, remoteJid, message, settings);
await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);
}
} catch (error) {
this.logger.error(

View File

@@ -126,15 +126,10 @@ export class EvolutionBotService extends BaseChatbotService<EvolutionBot, Evolut
},
};
this.logger.debug(`[EvolutionBot] Sending request to endpoint: ${endpoint}`);
this.logger.debug(`[EvolutionBot] Request payload: ${JSON.stringify(sanitizedPayload, null, 2)}`);
const response = await axios.post(endpoint, payload, {
headers,
});
this.logger.debug(`[EvolutionBot] Response received - Status: ${response.status}`);
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
await instance.client.sendPresenceUpdate('paused', remoteJid);
}
@@ -145,10 +140,6 @@ export class EvolutionBotService extends BaseChatbotService<EvolutionBot, Evolut
// Validate linkPreview is boolean and default to true for backward compatibility
const linkPreview = typeof rawLinkPreview === 'boolean' ? rawLinkPreview : true;
this.logger.debug(
`[EvolutionBot] Processing response - Message length: ${message?.length || 0}, LinkPreview: ${linkPreview}`,
);
if (message && typeof message === 'string' && message.startsWith("'") && message.endsWith("'")) {
const innerContent = message.slice(1, -1);
if (!innerContent.includes("'")) {
@@ -157,17 +148,8 @@ export class EvolutionBotService extends BaseChatbotService<EvolutionBot, Evolut
}
if (message) {
// Send message directly with validated linkPreview option
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: message,
linkPreview, // Always boolean, defaults to true
},
false,
);
this.logger.debug(`[EvolutionBot] Message sent successfully with linkPreview: ${linkPreview}`);
// Use the base class method that handles splitMessages functionality
await this.sendMessageWhatsApp(instance, remoteJid, message, settings, linkPreview);
} else {
this.logger.warn(`[EvolutionBot] No message content received from bot response`);
}

View File

@@ -142,7 +142,7 @@ export class FlowiseService extends BaseChatbotService<FlowiseModel> {
if (message) {
// Use the base class method to send the message to WhatsApp
await this.sendMessageWhatsApp(instance, remoteJid, message, settings);
await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);
}
}

View File

@@ -78,7 +78,7 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
const message = response?.data?.output || response?.data?.answer;
// Use base class method instead of custom implementation
await this.sendMessageWhatsApp(instance, remoteJid, message, settings);
await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);
await this.prismaRepository.integrationSession.update({
where: {

View File

@@ -86,6 +86,7 @@ export class OpenaiService extends BaseChatbotService<OpenaiBot, OpenaiSetting>
remoteJid,
"Sorry, I couldn't transcribe your audio message. Could you please type your message instead?",
settings,
true,
);
return;
}
@@ -236,7 +237,7 @@ export class OpenaiService extends BaseChatbotService<OpenaiBot, OpenaiSetting>
// Send the response
if (message) {
this.logger.log('Sending message to WhatsApp');
await this.sendMessageWhatsApp(instance, remoteJid, message, settings);
await this.sendMessageWhatsApp(instance, remoteJid, message, settings, true);
} else {
this.logger.error('No message to send to WhatsApp');
}

View File

@@ -318,7 +318,7 @@ export class TypebotService extends BaseChatbotService<TypebotModel, any> {
} else if (formattedText.includes('[buttons]')) {
await this.processButtonMessage(instance, formattedText, session.remoteJid);
} else {
await this.sendMessageWhatsApp(instance, session.remoteJid, formattedText, settings);
await this.sendMessageWhatsApp(instance, session.remoteJid, formattedText, settings, true);
}
sendTelemetry('/message/sendText');
@@ -393,7 +393,7 @@ export class TypebotService extends BaseChatbotService<TypebotModel, any> {
} else if (formattedText.includes('[buttons]')) {
await this.processButtonMessage(instance, formattedText, session.remoteJid);
} else {
await this.sendMessageWhatsApp(instance, session.remoteJid, formattedText, settings);
await this.sendMessageWhatsApp(instance, session.remoteJid, formattedText, settings, true);
}
sendTelemetry('/message/sendText');
@@ -642,15 +642,21 @@ export class TypebotService extends BaseChatbotService<TypebotModel, any> {
if (!content) {
if (unknownMessage) {
await this.sendMessageWhatsApp(waInstance, remoteJid, unknownMessage, {
delayMessage,
expire,
keywordFinish,
listeningFromMe,
stopBotFromMe,
keepOpen,
await this.sendMessageWhatsApp(
waInstance,
remoteJid,
unknownMessage,
});
{
delayMessage,
expire,
keywordFinish,
listeningFromMe,
stopBotFromMe,
keepOpen,
unknownMessage,
},
true,
);
sendTelemetry('/message/sendText');
}
return;
@@ -801,15 +807,21 @@ export class TypebotService extends BaseChatbotService<TypebotModel, any> {
if (!data?.messages || data.messages.length === 0) {
if (!content) {
if (unknownMessage) {
await this.sendMessageWhatsApp(waInstance, remoteJid, unknownMessage, {
delayMessage,
expire,
keywordFinish,
listeningFromMe,
stopBotFromMe,
keepOpen,
await this.sendMessageWhatsApp(
waInstance,
remoteJid,
unknownMessage,
});
{
delayMessage,
expire,
keywordFinish,
listeningFromMe,
stopBotFromMe,
keepOpen,
unknownMessage,
},
true,
);
sendTelemetry('/message/sendText');
}
return;
@@ -903,15 +915,21 @@ export class TypebotService extends BaseChatbotService<TypebotModel, any> {
if (!content) {
if (unknownMessage) {
await this.sendMessageWhatsApp(waInstance, remoteJid, unknownMessage, {
delayMessage,
expire,
keywordFinish,
listeningFromMe,
stopBotFromMe,
keepOpen,
await this.sendMessageWhatsApp(
waInstance,
remoteJid,
unknownMessage,
});
{
delayMessage,
expire,
keywordFinish,
listeningFromMe,
stopBotFromMe,
keepOpen,
unknownMessage,
},
true,
);
sendTelemetry('/message/sendText');
}
return;