mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-16 04:02:54 -06:00
refactor(openai): improve service initialization and streamline audio transcription handling
- Updated OpenaiService and related classes to enhance the initialization process by ensuring the correct order of parameters. - Simplified audio message handling by consolidating transcription logic and improving error handling. - Refactored the OpenaiController to utilize the new structure, ensuring better integration with the base chatbot framework. - Enhanced logging for better traceability during audio processing and API interactions.
This commit is contained in:
parent
69b4f1aa02
commit
c30bae4c3a
@ -165,11 +165,7 @@ export class EvolutionStartupService extends ChannelStartupService {
|
|||||||
openAiDefaultSettings.speechToText &&
|
openAiDefaultSettings.speechToText &&
|
||||||
received?.message?.audioMessage
|
received?.message?.audioMessage
|
||||||
) {
|
) {
|
||||||
messageRaw.message.speechToText = await this.openaiService.speechToText(
|
messageRaw.message.speechToText = await this.openaiService.speechToText(received);
|
||||||
openAiDefaultSettings.OpenaiCreds,
|
|
||||||
received,
|
|
||||||
this.client.updateMediaMessage,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,16 +501,12 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
openAiDefaultSettings.speechToText &&
|
openAiDefaultSettings.speechToText &&
|
||||||
audioMessage
|
audioMessage
|
||||||
) {
|
) {
|
||||||
messageRaw.message.speechToText = await this.openaiService.speechToText(
|
messageRaw.message.speechToText = await this.openaiService.speechToText({
|
||||||
openAiDefaultSettings.OpenaiCreds,
|
message: {
|
||||||
{
|
mediaUrl: messageRaw.message.mediaUrl,
|
||||||
message: {
|
...messageRaw,
|
||||||
mediaUrl: messageRaw.message.mediaUrl,
|
|
||||||
...messageRaw,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
() => {},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1298,11 +1298,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (openAiDefaultSettings && openAiDefaultSettings.openaiCredsId && openAiDefaultSettings.speechToText) {
|
if (openAiDefaultSettings && openAiDefaultSettings.openaiCredsId && openAiDefaultSettings.speechToText) {
|
||||||
messageRaw.message.speechToText = await this.openaiService.speechToText(
|
messageRaw.message.speechToText = await this.openaiService.speechToText(received);
|
||||||
openAiDefaultSettings.OpenaiCreds,
|
|
||||||
received,
|
|
||||||
this.client.updateMediaMessage,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2297,11 +2293,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (openAiDefaultSettings && openAiDefaultSettings.openaiCredsId && openAiDefaultSettings.speechToText) {
|
if (openAiDefaultSettings && openAiDefaultSettings.openaiCredsId && openAiDefaultSettings.speechToText) {
|
||||||
messageRaw.message.speechToText = await this.openaiService.speechToText(
|
messageRaw.message.speechToText = await this.openaiService.speechToText(messageRaw);
|
||||||
openAiDefaultSettings.OpenaiCreds,
|
|
||||||
messageRaw,
|
|
||||||
this.client.updateMediaMessage,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,18 +47,21 @@ export interface BaseBotData {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class BaseChatbotController<BotType = any, BotData extends BaseChatbotDto = BaseChatbotDto> extends ChatbotController implements ChatbotControllerInterface {
|
export abstract class BaseChatbotController<BotType = any, BotData extends BaseChatbotDto = BaseChatbotDto>
|
||||||
|
extends ChatbotController
|
||||||
|
implements ChatbotControllerInterface
|
||||||
|
{
|
||||||
public readonly logger: Logger;
|
public readonly logger: Logger;
|
||||||
|
|
||||||
integrationEnabled: boolean;
|
integrationEnabled: boolean;
|
||||||
botRepository: any;
|
botRepository: any;
|
||||||
settingsRepository: any;
|
settingsRepository: any;
|
||||||
sessionRepository: any;
|
sessionRepository: any;
|
||||||
userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
|
userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
|
||||||
|
|
||||||
// Name of the integration, to be set by the derived class
|
// Name of the integration, to be set by the derived class
|
||||||
protected abstract readonly integrationName: string;
|
protected abstract readonly integrationName: string;
|
||||||
|
|
||||||
// Method to process bot-specific logic
|
// Method to process bot-specific logic
|
||||||
protected abstract processBot(
|
protected abstract processBot(
|
||||||
waInstance: any,
|
waInstance: any,
|
||||||
@ -70,16 +73,13 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
pushName?: string,
|
pushName?: string,
|
||||||
msg?: any,
|
msg?: any,
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
|
|
||||||
// Method to get the fallback bot ID from settings
|
// Method to get the fallback bot ID from settings
|
||||||
protected abstract getFallbackBotId(settings: any): string | undefined;
|
protected abstract getFallbackBotId(settings: any): string | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
|
||||||
prismaRepository: PrismaRepository,
|
|
||||||
waMonitor: WAMonitoringService,
|
|
||||||
) {
|
|
||||||
super(prismaRepository, waMonitor);
|
super(prismaRepository, waMonitor);
|
||||||
|
|
||||||
this.sessionRepository = this.prismaRepository.integrationSession;
|
this.sessionRepository = this.prismaRepository.integrationSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,9 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (checkTriggerAll && data.triggerType === 'all') {
|
if (checkTriggerAll && data.triggerType === 'all') {
|
||||||
throw new Error(`You already have a ${this.integrationName} with an "All" trigger, you cannot have more bots while it is active`);
|
throw new Error(
|
||||||
|
`You already have a ${this.integrationName} with an "All" trigger, you cannot have more bots while it is active`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for trigger keyword duplicates
|
// Check for trigger keyword duplicates
|
||||||
@ -309,7 +311,7 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
|
|
||||||
// Get the name of the fallback field for this integration type
|
// Get the name of the fallback field for this integration type
|
||||||
const fallbackFieldName = this.getFallbackFieldName();
|
const fallbackFieldName = this.getFallbackFieldName();
|
||||||
|
|
||||||
const settingsData = {
|
const settingsData = {
|
||||||
expire: data.expire,
|
expire: data.expire,
|
||||||
keywordFinish: data.keywordFinish,
|
keywordFinish: data.keywordFinish,
|
||||||
@ -336,20 +338,25 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
// Map the specific fallback field to a generic 'fallbackId' in the response
|
// Map the specific fallback field to a generic 'fallbackId' in the response
|
||||||
return {
|
return {
|
||||||
...settings,
|
...settings,
|
||||||
fallbackId: settings[fallbackFieldName]
|
fallbackId: settings[fallbackFieldName],
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const settings = await this.settingsRepository.create({
|
const settings = await this.settingsRepository.create({
|
||||||
data: {
|
data: {
|
||||||
...settingsData,
|
...settingsData,
|
||||||
instanceId: instanceId,
|
instanceId: instanceId,
|
||||||
|
Instance: {
|
||||||
|
connect: {
|
||||||
|
id: instanceId,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Map the specific fallback field to a generic 'fallbackId' in the response
|
// Map the specific fallback field to a generic 'fallbackId' in the response
|
||||||
return {
|
return {
|
||||||
...settings,
|
...settings,
|
||||||
fallbackId: settings[fallbackFieldName]
|
fallbackId: settings[fallbackFieldName],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -631,7 +638,9 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (checkTriggerAll) {
|
if (checkTriggerAll) {
|
||||||
throw new Error(`You already have a ${this.integrationName} with an "All" trigger, you cannot have more bots while it is active`);
|
throw new Error(
|
||||||
|
`You already have a ${this.integrationName} with an "All" trigger, you cannot have more bots while it is active`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -779,15 +788,15 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
if (this.checkIgnoreJids(settings?.ignoreJids, remoteJid)) return;
|
if (this.checkIgnoreJids(settings?.ignoreJids, remoteJid)) return;
|
||||||
|
|
||||||
const session = await this.getSession(remoteJid, instance);
|
const session = await this.getSession(remoteJid, instance);
|
||||||
|
|
||||||
const content = getConversationMessage(msg);
|
const content = getConversationMessage(msg);
|
||||||
|
|
||||||
// Get integration type
|
// Get integration type
|
||||||
const integrationType = this.getIntegrationType();
|
const integrationType = this.getIntegrationType();
|
||||||
|
|
||||||
// Find a bot for this message
|
// Find a bot for this message
|
||||||
let findBot: any = await this.findBotTrigger(this.botRepository, content, instance, session);
|
let findBot: any = await this.findBotTrigger(this.botRepository, content, instance, session);
|
||||||
|
|
||||||
// If no bot is found, try to use fallback
|
// If no bot is found, try to use fallback
|
||||||
if (!findBot) {
|
if (!findBot) {
|
||||||
const fallback = await this.settingsRepository.findFirst({
|
const fallback = await this.settingsRepository.findFirst({
|
||||||
@ -798,7 +807,7 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
|
|
||||||
// Get the fallback ID for this integration type
|
// Get the fallback ID for this integration type
|
||||||
const fallbackId = this.getFallbackBotId(fallback);
|
const fallbackId = this.getFallbackBotId(fallback);
|
||||||
|
|
||||||
if (fallbackId) {
|
if (fallbackId) {
|
||||||
const findFallback = await this.botRepository.findFirst({
|
const findFallback = await this.botRepository.findFirst({
|
||||||
where: {
|
where: {
|
||||||
@ -811,7 +820,7 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we still don't have a bot, return
|
// If we still don't have a bot, return
|
||||||
if (!findBot) {
|
if (!findBot) {
|
||||||
return;
|
return;
|
||||||
@ -918,4 +927,4 @@ export abstract class BaseChatbotController<BotType = any, BotData extends BaseC
|
|||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,4 +39,4 @@ export class BaseChatbotSettingDto {
|
|||||||
splitMessages?: boolean;
|
splitMessages?: boolean;
|
||||||
timePerChar?: number;
|
timePerChar?: number;
|
||||||
fallbackId?: string; // Unified fallback ID field for all integrations
|
fallbackId?: string; // Unified fallback ID field for all integrations
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { InstanceDto } from '@api/dto/instance.dto';
|
import { InstanceDto } from '@api/dto/instance.dto';
|
||||||
import { PrismaRepository } from '@api/repository/repository.service';
|
import { PrismaRepository } from '@api/repository/repository.service';
|
||||||
import { WAMonitoringService } from '@api/services/monitor.service';
|
import { WAMonitoringService } from '@api/services/monitor.service';
|
||||||
|
import { Integration } from '@api/types/wa.types';
|
||||||
import { ConfigService, Language } from '@config/env.config';
|
import { ConfigService, Language } from '@config/env.config';
|
||||||
import { Logger } from '@config/logger.config';
|
import { Logger } from '@config/logger.config';
|
||||||
import { IntegrationSession } from '@prisma/client';
|
import { IntegrationSession } from '@prisma/client';
|
||||||
import { Integration } from '@api/types/wa.types';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
protected readonly waMonitor: WAMonitoringService;
|
protected readonly waMonitor: WAMonitoringService;
|
||||||
protected readonly prismaRepository: PrismaRepository;
|
protected readonly prismaRepository: PrismaRepository;
|
||||||
protected readonly configService?: ConfigService;
|
protected readonly configService?: ConfigService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
waMonitor: WAMonitoringService,
|
waMonitor: WAMonitoringService,
|
||||||
prismaRepository: PrismaRepository,
|
prismaRepository: PrismaRepository,
|
||||||
@ -89,23 +89,23 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
this.logger.error('No OpenAI API key set for Whisper transcription');
|
this.logger.error('No OpenAI API key set for Whisper transcription');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lang = this.configService.get<Language>('LANGUAGE').includes('pt')
|
const lang = this.configService.get<Language>('LANGUAGE').includes('pt')
|
||||||
? 'pt'
|
? 'pt'
|
||||||
: this.configService.get<Language>('LANGUAGE');
|
: this.configService.get<Language>('LANGUAGE');
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', audioBuffer, 'audio.ogg');
|
formData.append('file', audioBuffer, 'audio.ogg');
|
||||||
formData.append('model', 'whisper-1');
|
formData.append('model', 'whisper-1');
|
||||||
formData.append('language', lang);
|
formData.append('language', lang);
|
||||||
|
|
||||||
const response = await axios.post('https://api.openai.com/v1/audio/transcriptions', formData, {
|
const response = await axios.post('https://api.openai.com/v1/audio/transcriptions', formData, {
|
||||||
headers: {
|
headers: {
|
||||||
...formData.getHeaders(),
|
...formData.getHeaders(),
|
||||||
Authorization: `Bearer ${apiKey}`,
|
Authorization: `Bearer ${apiKey}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return response?.data?.text || null;
|
return response?.data?.text || null;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(`Whisper transcription failed: ${err}`);
|
this.logger.error(`Whisper transcription failed: ${err}`);
|
||||||
@ -119,14 +119,16 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
public async createNewSession(instance: InstanceDto | any, data: any, type: string) {
|
public async createNewSession(instance: InstanceDto | any, data: any, type: string) {
|
||||||
try {
|
try {
|
||||||
// Extract pushName safely - if data.pushName is an object with a pushName property, use that
|
// Extract pushName safely - if data.pushName is an object with a pushName property, use that
|
||||||
const pushNameValue = typeof data.pushName === 'object' && data.pushName?.pushName
|
const pushNameValue =
|
||||||
? data.pushName.pushName
|
typeof data.pushName === 'object' && data.pushName?.pushName
|
||||||
: (typeof data.pushName === 'string' ? data.pushName : null);
|
? data.pushName.pushName
|
||||||
|
: typeof data.pushName === 'string'
|
||||||
|
? data.pushName
|
||||||
|
: null;
|
||||||
|
|
||||||
// Extract remoteJid safely
|
// Extract remoteJid safely
|
||||||
const remoteJidValue = typeof data.remoteJid === 'object' && data.remoteJid?.remoteJid
|
const remoteJidValue =
|
||||||
? data.remoteJid.remoteJid
|
typeof data.remoteJid === 'object' && data.remoteJid?.remoteJid ? data.remoteJid.remoteJid : data.remoteJid;
|
||||||
: data.remoteJid;
|
|
||||||
|
|
||||||
const session = await this.prismaRepository.integrationSession.create({
|
const session = await this.prismaRepository.integrationSession.create({
|
||||||
data: {
|
data: {
|
||||||
@ -203,18 +205,18 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
* This handles common patterns like markdown links and formatting
|
* This handles common patterns like markdown links and formatting
|
||||||
*/
|
*/
|
||||||
protected async sendMessageWhatsApp(
|
protected async sendMessageWhatsApp(
|
||||||
instance: any,
|
instance: any,
|
||||||
remoteJid: string,
|
remoteJid: string,
|
||||||
message: string,
|
message: string,
|
||||||
settings: SettingsType
|
settings: SettingsType,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
||||||
const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
|
const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
|
||||||
let textBuffer = '';
|
let textBuffer = '';
|
||||||
let lastIndex = 0;
|
let lastIndex = 0;
|
||||||
let match: RegExpExecArray | null;
|
let match: RegExpExecArray | null;
|
||||||
|
|
||||||
const splitMessages = (settings as any)?.splitMessages ?? false;
|
const splitMessages = (settings as any)?.splitMessages ?? false;
|
||||||
const timePerChar = (settings as any)?.timePerChar ?? 0;
|
const timePerChar = (settings as any)?.timePerChar ?? 0;
|
||||||
const minDelay = 1000;
|
const minDelay = 1000;
|
||||||
@ -224,18 +226,18 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
const [fullMatch, exclamation, altText, url] = match;
|
const [fullMatch, exclamation, altText, url] = match;
|
||||||
const mediaType = this.getMediaType(url);
|
const mediaType = this.getMediaType(url);
|
||||||
const beforeText = message.slice(lastIndex, match.index);
|
const beforeText = message.slice(lastIndex, match.index);
|
||||||
|
|
||||||
if (beforeText) {
|
if (beforeText) {
|
||||||
textBuffer += beforeText;
|
textBuffer += beforeText;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaType) {
|
if (mediaType) {
|
||||||
// Send accumulated text before sending media
|
// Send accumulated text before sending media
|
||||||
if (textBuffer.trim()) {
|
if (textBuffer.trim()) {
|
||||||
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages);
|
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages);
|
||||||
textBuffer = '';
|
textBuffer = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle sending the media
|
// Handle sending the media
|
||||||
try {
|
try {
|
||||||
switch (mediaType) {
|
switch (mediaType) {
|
||||||
@ -249,7 +251,7 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
break;
|
break;
|
||||||
case 'video':
|
case 'video':
|
||||||
await instance.mediaMessage({
|
await instance.mediaMessage({
|
||||||
number: remoteJid.split('@')[0],
|
number: remoteJid.split('@')[0],
|
||||||
delay: (settings as any)?.delayMessage || 1000,
|
delay: (settings as any)?.delayMessage || 1000,
|
||||||
caption: altText,
|
caption: altText,
|
||||||
media: url,
|
media: url,
|
||||||
@ -280,48 +282,48 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
// It's a regular link, keep it in the text
|
// It's a regular link, keep it in the text
|
||||||
textBuffer += `[${altText}](${url})`;
|
textBuffer += `[${altText}](${url})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastIndex = match.index + fullMatch.length;
|
lastIndex = match.index + fullMatch.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any remaining text after the last match
|
// Add any remaining text after the last match
|
||||||
if (lastIndex < message.length) {
|
if (lastIndex < message.length) {
|
||||||
textBuffer += message.slice(lastIndex);
|
textBuffer += message.slice(lastIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send any remaining text
|
// Send any remaining text
|
||||||
if (textBuffer.trim()) {
|
if (textBuffer.trim()) {
|
||||||
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages);
|
await this.sendFormattedText(instance, remoteJid, textBuffer.trim(), settings, splitMessages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to send formatted text with proper typing indicators and delays
|
* Helper method to send formatted text with proper typing indicators and delays
|
||||||
*/
|
*/
|
||||||
private async sendFormattedText(
|
private async sendFormattedText(
|
||||||
instance: any,
|
instance: any,
|
||||||
remoteJid: string,
|
remoteJid: string,
|
||||||
text: string,
|
text: string,
|
||||||
settings: any,
|
settings: any,
|
||||||
splitMessages: boolean
|
splitMessages: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const timePerChar = settings?.timePerChar ?? 0;
|
const timePerChar = settings?.timePerChar ?? 0;
|
||||||
const minDelay = 1000;
|
const minDelay = 1000;
|
||||||
const maxDelay = 20000;
|
const maxDelay = 20000;
|
||||||
|
|
||||||
if (splitMessages) {
|
if (splitMessages) {
|
||||||
const multipleMessages = text.split('\n\n');
|
const multipleMessages = text.split('\n\n');
|
||||||
for (let index = 0; index < multipleMessages.length; index++) {
|
for (let index = 0; index < multipleMessages.length; index++) {
|
||||||
const message = multipleMessages[index];
|
const message = multipleMessages[index];
|
||||||
if (!message.trim()) continue;
|
if (!message.trim()) continue;
|
||||||
|
|
||||||
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
|
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
|
||||||
|
|
||||||
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
||||||
await instance.client.presenceSubscribe(remoteJid);
|
await instance.client.presenceSubscribe(remoteJid);
|
||||||
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await instance.textMessage(
|
await instance.textMessage(
|
||||||
@ -335,19 +337,19 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
resolve();
|
resolve();
|
||||||
}, delay);
|
}, delay);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
||||||
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const delay = Math.min(Math.max(text.length * timePerChar, minDelay), maxDelay);
|
const delay = Math.min(Math.max(text.length * timePerChar, minDelay), maxDelay);
|
||||||
|
|
||||||
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
||||||
await instance.client.presenceSubscribe(remoteJid);
|
await instance.client.presenceSubscribe(remoteJid);
|
||||||
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await instance.textMessage(
|
await instance.textMessage(
|
||||||
@ -361,7 +363,7 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
resolve();
|
resolve();
|
||||||
}, delay);
|
}, delay);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
if (instance.integration === Integration.WHATSAPP_BAILEYS) {
|
||||||
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
||||||
}
|
}
|
||||||
@ -385,15 +387,18 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
// Create a session if none exists
|
// Create a session if none exists
|
||||||
if (!session) {
|
if (!session) {
|
||||||
// Extract pushName properly - if it's an object with pushName property, use that
|
// Extract pushName properly - if it's an object with pushName property, use that
|
||||||
const pushNameValue = typeof pushName === 'object' && pushName?.pushName
|
const pushNameValue =
|
||||||
? pushName.pushName
|
typeof pushName === 'object' && pushName?.pushName
|
||||||
: (typeof pushName === 'string' ? pushName : null);
|
? pushName.pushName
|
||||||
|
: typeof pushName === 'string'
|
||||||
|
? pushName
|
||||||
|
: null;
|
||||||
|
|
||||||
session = (
|
session = (
|
||||||
await this.createNewSession(
|
await this.createNewSession(
|
||||||
{
|
{
|
||||||
instanceName: instance.instanceName,
|
instanceName: instance.instanceName,
|
||||||
instanceId: instance.instanceId
|
instanceId: instance.instanceId,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
remoteJid,
|
remoteJid,
|
||||||
@ -440,4 +445,4 @@ export abstract class BaseChatbotService<BotType = any, SettingsType = any> {
|
|||||||
content: string,
|
content: string,
|
||||||
msg?: any,
|
msg?: any,
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { InstanceDto } from '@api/dto/instance.dto';
|
import { InstanceDto } from '@api/dto/instance.dto';
|
||||||
import { DifyDto } from '@api/integrations/chatbot/dify/dto/dify.dto';
|
import { DifyDto } from '@api/integrations/chatbot/dify/dto/dify.dto';
|
||||||
import { DifyService } from '@api/integrations/chatbot/dify/services/dify.service';
|
import { DifyService } from '@api/integrations/chatbot/dify/services/dify.service';
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { $Enums, TriggerOperator, TriggerType } from '@prisma/client';
|
import { $Enums, TriggerOperator, TriggerType } from '@prisma/client';
|
||||||
|
|
||||||
import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';
|
import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';
|
||||||
|
|
||||||
export class DifyDto extends BaseChatbotDto {
|
export class DifyDto extends BaseChatbotDto {
|
||||||
|
@ -2,21 +2,16 @@ import { InstanceDto } from '@api/dto/instance.dto';
|
|||||||
import { PrismaRepository } from '@api/repository/repository.service';
|
import { PrismaRepository } from '@api/repository/repository.service';
|
||||||
import { WAMonitoringService } from '@api/services/monitor.service';
|
import { WAMonitoringService } from '@api/services/monitor.service';
|
||||||
import { Integration } from '@api/types/wa.types';
|
import { Integration } from '@api/types/wa.types';
|
||||||
|
import { Auth, ConfigService, HttpServer } from '@config/env.config';
|
||||||
import { Dify, DifySetting, IntegrationSession } from '@prisma/client';
|
import { Dify, DifySetting, IntegrationSession } from '@prisma/client';
|
||||||
import { sendTelemetry } from '@utils/sendTelemetry';
|
import { sendTelemetry } from '@utils/sendTelemetry';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { downloadMediaMessage } from 'baileys';
|
import { downloadMediaMessage } from 'baileys';
|
||||||
|
|
||||||
import { BaseChatbotService } from '../../base-chatbot.service';
|
import { BaseChatbotService } from '../../base-chatbot.service';
|
||||||
import { ConfigService, HttpServer } from '@config/env.config';
|
|
||||||
import { Auth } from '@config/env.config';
|
|
||||||
|
|
||||||
export class DifyService extends BaseChatbotService<Dify, DifySetting> {
|
export class DifyService extends BaseChatbotService<Dify, DifySetting> {
|
||||||
constructor(
|
constructor(waMonitor: WAMonitoringService, configService: ConfigService, prismaRepository: PrismaRepository) {
|
||||||
waMonitor: WAMonitoringService,
|
|
||||||
configService: ConfigService,
|
|
||||||
prismaRepository: PrismaRepository,
|
|
||||||
) {
|
|
||||||
super(waMonitor, prismaRepository, 'DifyService', configService);
|
super(waMonitor, prismaRepository, 'DifyService', configService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +68,7 @@ export class DifyService extends BaseChatbotService<Dify, DifySetting> {
|
|||||||
];
|
];
|
||||||
payload.query = contentSplit[2] || content;
|
payload.query = contentSplit[2] || content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle audio messages
|
// Handle audio messages
|
||||||
if (this.isAudioMessage(content) && msg) {
|
if (this.isAudioMessage(content) && msg) {
|
||||||
try {
|
try {
|
||||||
@ -151,7 +146,7 @@ export class DifyService extends BaseChatbotService<Dify, DifySetting> {
|
|||||||
];
|
];
|
||||||
payload.inputs.query = contentSplit[2] || content;
|
payload.inputs.query = contentSplit[2] || content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle audio messages
|
// Handle audio messages
|
||||||
if (this.isAudioMessage(content) && msg) {
|
if (this.isAudioMessage(content) && msg) {
|
||||||
try {
|
try {
|
||||||
@ -229,7 +224,7 @@ export class DifyService extends BaseChatbotService<Dify, DifySetting> {
|
|||||||
];
|
];
|
||||||
payload.query = contentSplit[2] || content;
|
payload.query = contentSplit[2] || content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle audio messages
|
// Handle audio messages
|
||||||
if (this.isAudioMessage(content) && msg) {
|
if (this.isAudioMessage(content) && msg) {
|
||||||
try {
|
try {
|
||||||
@ -554,16 +549,7 @@ export class DifyService extends BaseChatbotService<Dify, DifySetting> {
|
|||||||
data,
|
data,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.initNewSession(
|
await this.initNewSession(instance, remoteJid, dify, settings, createSession.session, content, pushName, msg);
|
||||||
instance,
|
|
||||||
remoteJid,
|
|
||||||
dify,
|
|
||||||
settings,
|
|
||||||
createSession.session,
|
|
||||||
content,
|
|
||||||
pushName,
|
|
||||||
msg,
|
|
||||||
);
|
|
||||||
|
|
||||||
await sendTelemetry('/dify/session/start');
|
await sendTelemetry('/dify/session/start');
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { TriggerOperator, TriggerType } from '@prisma/client';
|
import { TriggerOperator, TriggerType } from '@prisma/client';
|
||||||
|
|
||||||
import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';
|
import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';
|
||||||
|
|
||||||
export class EvoaiDto extends BaseChatbotDto {
|
export class EvoaiDto extends BaseChatbotDto {
|
||||||
|
@ -11,11 +11,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import { BaseChatbotService } from '../../base-chatbot.service';
|
import { BaseChatbotService } from '../../base-chatbot.service';
|
||||||
|
|
||||||
export class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {
|
export class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {
|
||||||
constructor(
|
constructor(waMonitor: WAMonitoringService, prismaRepository: PrismaRepository, configService: ConfigService) {
|
||||||
waMonitor: WAMonitoringService,
|
|
||||||
prismaRepository: PrismaRepository,
|
|
||||||
configService: ConfigService,
|
|
||||||
) {
|
|
||||||
super(waMonitor, prismaRepository, 'EvoaiService', configService);
|
super(waMonitor, prismaRepository, 'EvoaiService', configService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,24 +41,24 @@ export class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
this.logger.debug(`[EvoAI] Processing message with custom process method`);
|
this.logger.debug(`[EvoAI] Processing message with custom process method`);
|
||||||
|
|
||||||
// Check if this is an audio message that we should try to transcribe
|
// Check if this is an audio message that we should try to transcribe
|
||||||
if (msg?.messageType === 'audioMessage' && msg?.message?.audioMessage) {
|
if (msg?.messageType === 'audioMessage' && msg?.message?.audioMessage) {
|
||||||
this.logger.debug(`[EvoAI] Detected audio message, attempting transcription`);
|
this.logger.debug(`[EvoAI] Detected audio message, attempting transcription`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Download the audio using the whole msg object
|
// Download the audio using the whole msg object
|
||||||
const mediaBuffer = await downloadMediaMessage(msg, 'buffer', {});
|
const mediaBuffer = await downloadMediaMessage(msg, 'buffer', {});
|
||||||
this.logger.debug(`[EvoAI] Downloaded audio: ${mediaBuffer?.length || 0} bytes`);
|
this.logger.debug(`[EvoAI] Downloaded audio: ${mediaBuffer?.length || 0} bytes`);
|
||||||
|
|
||||||
// Transcribe with OpenAI's Whisper
|
// Transcribe with OpenAI's Whisper
|
||||||
const transcribedText = await this.speechToText(mediaBuffer);
|
const transcribedText = await this.speechToText(mediaBuffer);
|
||||||
this.logger.debug(`[EvoAI] Transcription result: ${transcribedText || 'FAILED'}`);
|
this.logger.debug(`[EvoAI] Transcription result: ${transcribedText || 'FAILED'}`);
|
||||||
|
|
||||||
if (transcribedText) {
|
if (transcribedText) {
|
||||||
// Use the transcribed text instead of the original content
|
// Use the transcribed text instead of the original content
|
||||||
this.logger.debug(`[EvoAI] Using transcribed text: ${transcribedText}`);
|
this.logger.debug(`[EvoAI] Using transcribed text: ${transcribedText}`);
|
||||||
|
|
||||||
// Call the parent process method with the transcribed text
|
// Call the parent process method with the transcribed text
|
||||||
return super.process(instance, remoteJid, bot, session, settings, transcribedText, pushName, msg);
|
return super.process(instance, remoteJid, bot, session, settings, transcribedText, pushName, msg);
|
||||||
}
|
}
|
||||||
@ -70,7 +66,7 @@ export class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {
|
|||||||
this.logger.error(`[EvoAI] Audio transcription error: ${err}`);
|
this.logger.error(`[EvoAI] Audio transcription error: ${err}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For non-audio messages or if transcription failed, proceed normally
|
// For non-audio messages or if transcription failed, proceed normally
|
||||||
return super.process(instance, remoteJid, bot, session, settings, content, pushName, msg);
|
return super.process(instance, remoteJid, bot, session, settings, content, pushName, msg);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -91,7 +87,7 @@ export class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {
|
|||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
this.logger.debug(`[EvoAI] Sending message to bot with content: ${content}`);
|
this.logger.debug(`[EvoAI] Sending message to bot with content: ${content}`);
|
||||||
|
|
||||||
const endpoint: string = evoai.agentUrl;
|
const endpoint: string = evoai.agentUrl;
|
||||||
const callId = `call-${uuidv4()}`;
|
const callId = `call-${uuidv4()}`;
|
||||||
const taskId = `task-${uuidv4()}`;
|
const taskId = `task-${uuidv4()}`;
|
||||||
@ -108,13 +104,13 @@ export class EvoaiService extends BaseChatbotService<Evoai, EvoaiSetting> {
|
|||||||
if (this.isImageMessage(content) && msg) {
|
if (this.isImageMessage(content) && msg) {
|
||||||
const contentSplit = content.split('|');
|
const contentSplit = content.split('|');
|
||||||
parts[0].text = contentSplit[2] || content;
|
parts[0].text = contentSplit[2] || content;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Download the image
|
// Download the image
|
||||||
const mediaBuffer = await downloadMediaMessage(msg, 'buffer', {});
|
const mediaBuffer = await downloadMediaMessage(msg, 'buffer', {});
|
||||||
const fileContent = Buffer.from(mediaBuffer).toString('base64');
|
const fileContent = Buffer.from(mediaBuffer).toString('base64');
|
||||||
const fileName = contentSplit[2] || `${msg.key?.id || 'image'}.jpg`;
|
const fileName = contentSplit[2] || `${msg.key?.id || 'image'}.jpg`;
|
||||||
|
|
||||||
parts.push({
|
parts.push({
|
||||||
type: 'file',
|
type: 'file',
|
||||||
file: {
|
file: {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { TriggerOperator, TriggerType } from '@prisma/client';
|
import { TriggerOperator, TriggerType } from '@prisma/client';
|
||||||
|
|
||||||
import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';
|
import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';
|
||||||
|
|
||||||
export class N8nDto extends BaseChatbotDto {
|
export class N8nDto extends BaseChatbotDto {
|
||||||
|
@ -11,11 +11,7 @@ import { BaseChatbotService } from '../../base-chatbot.service';
|
|||||||
import { N8nDto } from '../dto/n8n.dto';
|
import { N8nDto } from '../dto/n8n.dto';
|
||||||
|
|
||||||
export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
||||||
constructor(
|
constructor(waMonitor: WAMonitoringService, prismaRepository: PrismaRepository, configService: ConfigService) {
|
||||||
waMonitor: WAMonitoringService,
|
|
||||||
prismaRepository: PrismaRepository,
|
|
||||||
configService: ConfigService,
|
|
||||||
) {
|
|
||||||
super(waMonitor, prismaRepository, 'N8nService', configService);
|
super(waMonitor, prismaRepository, 'N8nService', configService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,34 +190,34 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
|||||||
let textBuffer = '';
|
let textBuffer = '';
|
||||||
let lastIndex = 0;
|
let lastIndex = 0;
|
||||||
let match: RegExpExecArray | null;
|
let match: RegExpExecArray | null;
|
||||||
|
|
||||||
while ((match = linkRegex.exec(message)) !== null) {
|
while ((match = linkRegex.exec(message)) !== null) {
|
||||||
const [fullMatch, exclamation, altText, url] = match;
|
const [fullMatch, exclamation, altText, url] = match;
|
||||||
const mediaType = this.getMediaType(url);
|
const mediaType = this.getMediaType(url);
|
||||||
const beforeText = message.slice(lastIndex, match.index);
|
const beforeText = message.slice(lastIndex, match.index);
|
||||||
|
|
||||||
if (beforeText) {
|
if (beforeText) {
|
||||||
textBuffer += beforeText;
|
textBuffer += beforeText;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaType) {
|
if (mediaType) {
|
||||||
const splitMessages = settings.splitMessages ?? false;
|
const splitMessages = settings.splitMessages ?? false;
|
||||||
const timePerChar = settings.timePerChar ?? 0;
|
const timePerChar = settings.timePerChar ?? 0;
|
||||||
const minDelay = 1000;
|
const minDelay = 1000;
|
||||||
const maxDelay = 20000;
|
const maxDelay = 20000;
|
||||||
|
|
||||||
if (textBuffer.trim()) {
|
if (textBuffer.trim()) {
|
||||||
if (splitMessages) {
|
if (splitMessages) {
|
||||||
const multipleMessages = textBuffer.trim().split('\n\n');
|
const multipleMessages = textBuffer.trim().split('\n\n');
|
||||||
for (let index = 0; index < multipleMessages.length; index++) {
|
for (let index = 0; index < multipleMessages.length; index++) {
|
||||||
const message = multipleMessages[index];
|
const message = multipleMessages[index];
|
||||||
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
|
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.presenceSubscribe(remoteJid);
|
await instance.client.presenceSubscribe(remoteJid);
|
||||||
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await instance.textMessage(
|
await instance.textMessage(
|
||||||
@ -235,19 +231,19 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
|||||||
resolve();
|
resolve();
|
||||||
}, delay);
|
}, delay);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const delay = Math.min(Math.max(textBuffer.length * timePerChar, minDelay), maxDelay);
|
const delay = Math.min(Math.max(textBuffer.length * timePerChar, minDelay), maxDelay);
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.presenceSubscribe(remoteJid);
|
await instance.client.presenceSubscribe(remoteJid);
|
||||||
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await instance.textMessage(
|
await instance.textMessage(
|
||||||
@ -261,15 +257,15 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
|||||||
resolve();
|
resolve();
|
||||||
}, delay);
|
}, delay);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textBuffer = '';
|
textBuffer = '';
|
||||||
|
|
||||||
if (mediaType === 'image') {
|
if (mediaType === 'image') {
|
||||||
await instance.mediaMessage({
|
await instance.mediaMessage({
|
||||||
number: remoteJid.split('@')[0],
|
number: remoteJid.split('@')[0],
|
||||||
@ -306,32 +302,32 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
|||||||
} else {
|
} else {
|
||||||
textBuffer += `[${altText}](${url})`;
|
textBuffer += `[${altText}](${url})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastIndex = match.index + fullMatch.length;
|
lastIndex = match.index + fullMatch.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const remainingText = message.slice(lastIndex);
|
const remainingText = message.slice(lastIndex);
|
||||||
if (remainingText) {
|
if (remainingText) {
|
||||||
textBuffer += remainingText;
|
textBuffer += remainingText;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textBuffer.trim()) {
|
if (textBuffer.trim()) {
|
||||||
const splitMessages = settings.splitMessages ?? false;
|
const splitMessages = settings.splitMessages ?? false;
|
||||||
const timePerChar = settings.timePerChar ?? 0;
|
const timePerChar = settings.timePerChar ?? 0;
|
||||||
const minDelay = 1000;
|
const minDelay = 1000;
|
||||||
const maxDelay = 20000;
|
const maxDelay = 20000;
|
||||||
|
|
||||||
if (splitMessages) {
|
if (splitMessages) {
|
||||||
const multipleMessages = textBuffer.trim().split('\n\n');
|
const multipleMessages = textBuffer.trim().split('\n\n');
|
||||||
for (let index = 0; index < multipleMessages.length; index++) {
|
for (let index = 0; index < multipleMessages.length; index++) {
|
||||||
const message = multipleMessages[index];
|
const message = multipleMessages[index];
|
||||||
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
|
const delay = Math.min(Math.max(message.length * timePerChar, minDelay), maxDelay);
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.presenceSubscribe(remoteJid);
|
await instance.client.presenceSubscribe(remoteJid);
|
||||||
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await instance.textMessage(
|
await instance.textMessage(
|
||||||
@ -345,19 +341,19 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
|||||||
resolve();
|
resolve();
|
||||||
}, delay);
|
}, delay);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const delay = Math.min(Math.max(textBuffer.length * timePerChar, minDelay), maxDelay);
|
const delay = Math.min(Math.max(textBuffer.length * timePerChar, minDelay), maxDelay);
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.presenceSubscribe(remoteJid);
|
await instance.client.presenceSubscribe(remoteJid);
|
||||||
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
await instance.client.sendPresenceUpdate('composing', remoteJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await instance.textMessage(
|
await instance.textMessage(
|
||||||
@ -371,7 +367,7 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
|||||||
resolve();
|
resolve();
|
||||||
}, delay);
|
}, delay);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
if (instance.integration === 'WHATSAPP_BAILEYS') {
|
||||||
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
await instance.client.sendPresenceUpdate('paused', remoteJid);
|
||||||
}
|
}
|
||||||
@ -443,16 +439,7 @@ export class N8nService extends BaseChatbotService<N8n, N8nSetting> {
|
|||||||
data,
|
data,
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.initNewSession(
|
await this.initNewSession(instance, remoteJid, n8n, settings, createSession.session, content, pushName, msg);
|
||||||
instance,
|
|
||||||
remoteJid,
|
|
||||||
n8n,
|
|
||||||
settings,
|
|
||||||
createSession.session,
|
|
||||||
content,
|
|
||||||
pushName,
|
|
||||||
msg,
|
|
||||||
);
|
|
||||||
|
|
||||||
await sendTelemetry('/n8n/session/start');
|
await sendTelemetry('/n8n/session/start');
|
||||||
return;
|
return;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,15 @@
|
|||||||
import { TriggerOperator, TriggerType } from '@prisma/client';
|
import { TriggerOperator, TriggerType } from '@prisma/client';
|
||||||
|
|
||||||
|
import { BaseChatbotDto, BaseChatbotSettingDto } from '../../base-chatbot.dto';
|
||||||
|
|
||||||
export class OpenaiCredsDto {
|
export class OpenaiCredsDto {
|
||||||
name: string;
|
name: string;
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OpenaiDto {
|
export class OpenaiDto extends BaseChatbotDto {
|
||||||
enabled?: boolean;
|
|
||||||
description?: string;
|
|
||||||
openaiCredsId: string;
|
openaiCredsId: string;
|
||||||
botType?: string;
|
botType: string;
|
||||||
assistantId?: string;
|
assistantId?: string;
|
||||||
functionUrl?: string;
|
functionUrl?: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
@ -17,35 +17,10 @@ export class OpenaiDto {
|
|||||||
assistantMessages?: string[];
|
assistantMessages?: string[];
|
||||||
userMessages?: string[];
|
userMessages?: string[];
|
||||||
maxTokens?: number;
|
maxTokens?: number;
|
||||||
expire?: number;
|
|
||||||
keywordFinish?: string;
|
|
||||||
delayMessage?: number;
|
|
||||||
unknownMessage?: string;
|
|
||||||
listeningFromMe?: boolean;
|
|
||||||
stopBotFromMe?: boolean;
|
|
||||||
keepOpen?: boolean;
|
|
||||||
debounceTime?: number;
|
|
||||||
triggerType?: TriggerType;
|
|
||||||
triggerOperator?: TriggerOperator;
|
|
||||||
triggerValue?: string;
|
|
||||||
ignoreJids?: any;
|
|
||||||
splitMessages?: boolean;
|
|
||||||
timePerChar?: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OpenaiSettingDto {
|
export class OpenaiSettingDto extends BaseChatbotSettingDto {
|
||||||
openaiCredsId?: string;
|
openaiCredsId?: string;
|
||||||
expire?: number;
|
|
||||||
keywordFinish?: string;
|
|
||||||
delayMessage?: number;
|
|
||||||
unknownMessage?: string;
|
|
||||||
listeningFromMe?: boolean;
|
|
||||||
stopBotFromMe?: boolean;
|
|
||||||
keepOpen?: boolean;
|
|
||||||
debounceTime?: number;
|
|
||||||
openaiIdFallback?: string;
|
openaiIdFallback?: string;
|
||||||
ignoreJids?: any;
|
|
||||||
speechToText?: boolean;
|
speechToText?: boolean;
|
||||||
splitMessages?: boolean;
|
|
||||||
timePerChar?: number;
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -119,7 +119,7 @@ export const baileysController = new BaileysController(waMonitor);
|
|||||||
const typebotService = new TypebotService(waMonitor, configService, prismaRepository);
|
const typebotService = new TypebotService(waMonitor, configService, prismaRepository);
|
||||||
export const typebotController = new TypebotController(typebotService, prismaRepository, waMonitor);
|
export const typebotController = new TypebotController(typebotService, prismaRepository, waMonitor);
|
||||||
|
|
||||||
const openaiService = new OpenaiService(waMonitor, configService, prismaRepository);
|
const openaiService = new OpenaiService(waMonitor, prismaRepository, configService);
|
||||||
export const openaiController = new OpenaiController(openaiService, prismaRepository, waMonitor);
|
export const openaiController = new OpenaiController(openaiService, prismaRepository, waMonitor);
|
||||||
|
|
||||||
const difyService = new DifyService(waMonitor, configService, prismaRepository);
|
const difyService = new DifyService(waMonitor, configService, prismaRepository);
|
||||||
|
@ -47,7 +47,7 @@ export class ChannelStartupService {
|
|||||||
|
|
||||||
public typebotService = new TypebotService(waMonitor, this.configService, this.prismaRepository);
|
public typebotService = new TypebotService(waMonitor, this.configService, this.prismaRepository);
|
||||||
|
|
||||||
public openaiService = new OpenaiService(waMonitor, this.configService, this.prismaRepository);
|
public openaiService = new OpenaiService(waMonitor, this.prismaRepository, this.configService);
|
||||||
|
|
||||||
public difyService = new DifyService(waMonitor, this.configService, this.prismaRepository);
|
public difyService = new DifyService(waMonitor, this.configService, this.prismaRepository);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user