mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-21 19:47:21 -06:00
refactor: chatbot integration
This commit is contained in:
parent
8876797172
commit
edeb1efd2a
@ -60,13 +60,11 @@ import {
|
|||||||
configService,
|
configService,
|
||||||
ConfigSessionPhone,
|
ConfigSessionPhone,
|
||||||
Database,
|
Database,
|
||||||
Dify,
|
|
||||||
Log,
|
Log,
|
||||||
Openai,
|
Openai,
|
||||||
ProviderSession,
|
ProviderSession,
|
||||||
QrCode,
|
QrCode,
|
||||||
S3,
|
S3,
|
||||||
Typebot,
|
|
||||||
} from '@config/env.config';
|
} from '@config/env.config';
|
||||||
import { BadRequestException, InternalServerErrorException, NotFoundException } from '@exceptions';
|
import { BadRequestException, InternalServerErrorException, NotFoundException } from '@exceptions';
|
||||||
import ffmpegPath from '@ffmpeg-installer/ffmpeg';
|
import ffmpegPath from '@ffmpeg-installer/ffmpeg';
|
||||||
@ -2012,35 +2010,12 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot.enabled && isIntegration) {
|
await chatbotController.emit({
|
||||||
if (this.configService.get<Typebot>('TYPEBOT').ENABLED) {
|
instance: { instanceName: this.instance.name, instanceId: this.instanceId },
|
||||||
if (messageRaw.messageType !== 'reactionMessage')
|
remoteJid: messageRaw.key.remoteJid,
|
||||||
await this.typebotService.sendTypebot(
|
msg: messageRaw,
|
||||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
pushName: messageRaw.pushName,
|
||||||
messageRaw.key.remoteJid,
|
});
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.configService.get<Openai>('OPENAI').ENABLED) {
|
|
||||||
if (messageRaw.messageType !== 'reactionMessage')
|
|
||||||
await this.openaiService.sendOpenai(
|
|
||||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
|
||||||
messageRaw.key.remoteJid,
|
|
||||||
messageRaw.pushName,
|
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.configService.get<Dify>('DIFY').ENABLED) {
|
|
||||||
if (messageRaw.messageType !== 'reactionMessage')
|
|
||||||
await this.difyService.sendDify(
|
|
||||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
|
||||||
messageRaw.key.remoteJid,
|
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE)
|
if (this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE)
|
||||||
await this.prismaRepository.message.create({
|
await this.prismaRepository.message.create({
|
||||||
|
@ -20,7 +20,7 @@ import { chatbotController } from '@api/server.module';
|
|||||||
import { CacheService } from '@api/services/cache.service';
|
import { CacheService } from '@api/services/cache.service';
|
||||||
import { ChannelStartupService } from '@api/services/channel.service';
|
import { ChannelStartupService } from '@api/services/channel.service';
|
||||||
import { Events, wa } from '@api/types/wa.types';
|
import { Events, wa } from '@api/types/wa.types';
|
||||||
import { Chatwoot, ConfigService, Database, Dify, Openai, S3, Typebot, WaBusiness } from '@config/env.config';
|
import { Chatwoot, ConfigService, Database, Openai, S3, WaBusiness } from '@config/env.config';
|
||||||
import { BadRequestException, InternalServerErrorException } from '@exceptions';
|
import { BadRequestException, InternalServerErrorException } from '@exceptions';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { arrayUnique, isURL } from 'class-validator';
|
import { arrayUnique, isURL } from 'class-validator';
|
||||||
@ -923,35 +923,12 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot.enabled && isIntegration) {
|
await chatbotController.emit({
|
||||||
if (this.configService.get<Typebot>('TYPEBOT').ENABLED) {
|
instance: { instanceName: this.instance.name, instanceId: this.instanceId },
|
||||||
if (messageRaw.messageType !== 'reactionMessage')
|
remoteJid: messageRaw.key.remoteJid,
|
||||||
await this.typebotService.sendTypebot(
|
msg: messageRaw,
|
||||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
pushName: messageRaw.pushName,
|
||||||
messageRaw.key.remoteJid,
|
});
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.configService.get<Openai>('OPENAI').ENABLED) {
|
|
||||||
if (messageRaw.messageType !== 'reactionMessage')
|
|
||||||
await this.openaiService.sendOpenai(
|
|
||||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
|
||||||
messageRaw.key.remoteJid,
|
|
||||||
messageRaw.pushName,
|
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.configService.get<Dify>('DIFY').ENABLED) {
|
|
||||||
if (messageRaw.messageType !== 'reactionMessage')
|
|
||||||
await this.difyService.sendDify(
|
|
||||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
|
||||||
messageRaw.key.remoteJid,
|
|
||||||
messageRaw,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.prismaRepository.message.create({
|
await this.prismaRepository.message.create({
|
||||||
data: messageRaw,
|
data: messageRaw,
|
||||||
|
@ -6,6 +6,36 @@ import { Logger } from '@config/logger.config';
|
|||||||
import { IntegrationSession } from '@prisma/client';
|
import { IntegrationSession } from '@prisma/client';
|
||||||
import { findBotByTrigger } from '@utils/findBotByTrigger';
|
import { findBotByTrigger } from '@utils/findBotByTrigger';
|
||||||
|
|
||||||
|
export type EmitData = {
|
||||||
|
instance: InstanceDto;
|
||||||
|
remoteJid: string;
|
||||||
|
msg: any;
|
||||||
|
pushName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface ChatbotControllerInterface {
|
||||||
|
integrationEnabled: boolean;
|
||||||
|
botRepository: any;
|
||||||
|
settingsRepository: any;
|
||||||
|
sessionRepository: any;
|
||||||
|
userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } };
|
||||||
|
|
||||||
|
createBot(instance: InstanceDto, data: any): Promise<any>;
|
||||||
|
findBot(instance: InstanceDto): Promise<any>;
|
||||||
|
fetchBot(instance: InstanceDto, botId: string): Promise<any>;
|
||||||
|
updateBot(instance: InstanceDto, botId: string, data: any): Promise<any>;
|
||||||
|
deleteBot(instance: InstanceDto, botId: string): Promise<any>;
|
||||||
|
|
||||||
|
settings(instance: InstanceDto, data: any): Promise<any>;
|
||||||
|
fetchSettings(instance: InstanceDto): Promise<any>;
|
||||||
|
|
||||||
|
changeStatus(instance: InstanceDto, botId: string, status: string): Promise<any>;
|
||||||
|
fetchSessions(instance: InstanceDto, botId: string, remoteJid?: string): Promise<any>;
|
||||||
|
ignoreJid(instance: InstanceDto, data: any): Promise<any>;
|
||||||
|
|
||||||
|
emit(data: EmitData): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export class ChatbotController {
|
export class ChatbotController {
|
||||||
public prismaRepository: PrismaRepository;
|
public prismaRepository: PrismaRepository;
|
||||||
public waMonitor: WAMonitoringService;
|
public waMonitor: WAMonitoringService;
|
||||||
|
@ -1,84 +1,825 @@
|
|||||||
|
import { IgnoreJidDto } from '@api/dto/chatbot.dto';
|
||||||
import { InstanceDto } from '@api/dto/instance.dto';
|
import { InstanceDto } from '@api/dto/instance.dto';
|
||||||
import { DifyDto, DifyIgnoreJidDto } 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';
|
||||||
|
import { PrismaRepository } from '@api/repository/repository.service';
|
||||||
|
import { WAMonitoringService } from '@api/services/monitor.service';
|
||||||
import { configService, Dify } from '@config/env.config';
|
import { configService, Dify } from '@config/env.config';
|
||||||
|
import { Logger } from '@config/logger.config';
|
||||||
import { BadRequestException } from '@exceptions';
|
import { BadRequestException } from '@exceptions';
|
||||||
|
import { getConversationMessage } from '@utils/getConversationMessage';
|
||||||
|
|
||||||
export class DifyController {
|
import { ChatbotController, ChatbotControllerInterface, EmitData } from '../../chatbot.controller';
|
||||||
constructor(private readonly difyService: DifyService) {}
|
|
||||||
|
|
||||||
public async createDify(instance: InstanceDto, data: DifyDto) {
|
export class DifyController extends ChatbotController implements ChatbotControllerInterface {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
constructor(
|
||||||
|
private readonly difyService: DifyService,
|
||||||
|
prismaRepository: PrismaRepository,
|
||||||
|
waMonitor: WAMonitoringService,
|
||||||
|
) {
|
||||||
|
super(prismaRepository, waMonitor);
|
||||||
|
|
||||||
return this.difyService.create(instance, data);
|
this.botRepository = this.prismaRepository.dify;
|
||||||
|
this.settingsRepository = this.prismaRepository.difySetting;
|
||||||
|
this.sessionRepository = this.prismaRepository.integrationSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findDify(instance: InstanceDto) {
|
public readonly logger = new Logger(DifyController.name);
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
|
||||||
|
|
||||||
return this.difyService.find(instance);
|
integrationEnabled = configService.get<Dify>('DIFY').ENABLED;
|
||||||
|
botRepository: any;
|
||||||
|
settingsRepository: any;
|
||||||
|
sessionRepository: any;
|
||||||
|
userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
|
||||||
|
|
||||||
|
// Bots
|
||||||
|
public async createBot(instance: InstanceDto, data: DifyDto) {
|
||||||
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!data.expire ||
|
||||||
|
!data.keywordFinish ||
|
||||||
|
!data.delayMessage ||
|
||||||
|
!data.unknownMessage ||
|
||||||
|
!data.listeningFromMe ||
|
||||||
|
!data.stopBotFromMe ||
|
||||||
|
!data.keepOpen ||
|
||||||
|
!data.debounceTime ||
|
||||||
|
!data.ignoreJids
|
||||||
|
) {
|
||||||
|
const defaultSettingCheck = await this.settingsRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!data.expire) data.expire = defaultSettingCheck?.expire || 0;
|
||||||
|
if (!data.keywordFinish) data.keywordFinish = defaultSettingCheck?.keywordFinish || '';
|
||||||
|
if (!data.delayMessage) data.delayMessage = defaultSettingCheck?.delayMessage || 1000;
|
||||||
|
if (!data.unknownMessage) data.unknownMessage = defaultSettingCheck?.unknownMessage || '';
|
||||||
|
if (!data.listeningFromMe) data.listeningFromMe = defaultSettingCheck?.listeningFromMe || false;
|
||||||
|
if (!data.stopBotFromMe) data.stopBotFromMe = defaultSettingCheck?.stopBotFromMe || false;
|
||||||
|
if (!data.keepOpen) data.keepOpen = defaultSettingCheck?.keepOpen || false;
|
||||||
|
if (!data.debounceTime) data.debounceTime = defaultSettingCheck?.debounceTime || 0;
|
||||||
|
if (!data.ignoreJids) data.ignoreJids = defaultSettingCheck?.ignoreJids || [];
|
||||||
|
|
||||||
|
if (!defaultSettingCheck) {
|
||||||
|
await this.settings(instance, {
|
||||||
|
expire: data.expire,
|
||||||
|
keywordFinish: data.keywordFinish,
|
||||||
|
delayMessage: data.delayMessage,
|
||||||
|
unknownMessage: data.unknownMessage,
|
||||||
|
listeningFromMe: data.listeningFromMe,
|
||||||
|
stopBotFromMe: data.stopBotFromMe,
|
||||||
|
keepOpen: data.keepOpen,
|
||||||
|
debounceTime: data.debounceTime,
|
||||||
|
ignoreJids: data.ignoreJids,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkTriggerAll = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'all',
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkTriggerAll && data.triggerType === 'all') {
|
||||||
|
throw new Error('You already have a dify with an "All" trigger, you cannot have more bots while it is active');
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkDuplicate = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
botType: data.botType,
|
||||||
|
apiUrl: data.apiUrl,
|
||||||
|
apiKey: data.apiKey,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkDuplicate) {
|
||||||
|
throw new Error('Dify already exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.triggerType === 'keyword') {
|
||||||
|
if (!data.triggerOperator || !data.triggerValue) {
|
||||||
|
throw new Error('Trigger operator and value are required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkDuplicate = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
triggerOperator: data.triggerOperator,
|
||||||
|
triggerValue: data.triggerValue,
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkDuplicate) {
|
||||||
|
throw new Error('Trigger already exists');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.triggerType === 'advanced') {
|
||||||
|
if (!data.triggerValue) {
|
||||||
|
throw new Error('Trigger value is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkDuplicate = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
triggerValue: data.triggerValue,
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkDuplicate) {
|
||||||
|
throw new Error('Trigger already exists');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const bot = await this.botRepository.create({
|
||||||
|
data: {
|
||||||
|
enabled: data.enabled,
|
||||||
|
description: data.description,
|
||||||
|
botType: data.botType,
|
||||||
|
apiUrl: data.apiUrl,
|
||||||
|
apiKey: data.apiKey,
|
||||||
|
expire: data.expire,
|
||||||
|
keywordFinish: data.keywordFinish,
|
||||||
|
delayMessage: data.delayMessage,
|
||||||
|
unknownMessage: data.unknownMessage,
|
||||||
|
listeningFromMe: data.listeningFromMe,
|
||||||
|
stopBotFromMe: data.stopBotFromMe,
|
||||||
|
keepOpen: data.keepOpen,
|
||||||
|
debounceTime: data.debounceTime,
|
||||||
|
instanceId: instanceId,
|
||||||
|
triggerType: data.triggerType,
|
||||||
|
triggerOperator: data.triggerOperator,
|
||||||
|
triggerValue: data.triggerValue,
|
||||||
|
ignoreJids: data.ignoreJids,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return bot;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error creating dify');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchDify(instance: InstanceDto, difyId: string) {
|
public async findBot(instance: InstanceDto) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.fetch(instance, difyId);
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const bots = await this.botRepository.findMany({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!bots.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bots;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateDify(instance: InstanceDto, difyId: string, data: DifyDto) {
|
public async fetchBot(instance: InstanceDto, botId: string) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.update(instance, difyId, data);
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const bot = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
id: botId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!bot) {
|
||||||
|
throw new Error('Dify not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot.instanceId !== instanceId) {
|
||||||
|
throw new Error('Dify not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deleteDify(instance: InstanceDto, difyId: string) {
|
public async updateBot(instance: InstanceDto, botId: string, data: DifyDto) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.delete(instance, difyId);
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const bot = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
id: botId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!bot) {
|
||||||
|
throw new Error('Dify not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot.instanceId !== instanceId) {
|
||||||
|
throw new Error('Dify not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.triggerType === 'all') {
|
||||||
|
const checkTriggerAll = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'all',
|
||||||
|
id: {
|
||||||
|
not: botId,
|
||||||
|
},
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkTriggerAll) {
|
||||||
|
throw new Error('You already have a dify with an "All" trigger, you cannot have more bots while it is active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkDuplicate = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
id: {
|
||||||
|
not: botId,
|
||||||
|
},
|
||||||
|
instanceId: instanceId,
|
||||||
|
botType: data.botType,
|
||||||
|
apiUrl: data.apiUrl,
|
||||||
|
apiKey: data.apiKey,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkDuplicate) {
|
||||||
|
throw new Error('Dify already exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.triggerType === 'keyword') {
|
||||||
|
if (!data.triggerOperator || !data.triggerValue) {
|
||||||
|
throw new Error('Trigger operator and value are required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkDuplicate = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
triggerOperator: data.triggerOperator,
|
||||||
|
triggerValue: data.triggerValue,
|
||||||
|
id: { not: botId },
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkDuplicate) {
|
||||||
|
throw new Error('Trigger already exists');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.triggerType === 'advanced') {
|
||||||
|
if (!data.triggerValue) {
|
||||||
|
throw new Error('Trigger value is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkDuplicate = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
triggerValue: data.triggerValue,
|
||||||
|
id: { not: botId },
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkDuplicate) {
|
||||||
|
throw new Error('Trigger already exists');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const bot = await this.botRepository.update({
|
||||||
|
where: {
|
||||||
|
id: botId,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
enabled: data.enabled,
|
||||||
|
botType: data.botType,
|
||||||
|
apiUrl: data.apiUrl,
|
||||||
|
apiKey: data.apiKey,
|
||||||
|
expire: data.expire,
|
||||||
|
keywordFinish: data.keywordFinish,
|
||||||
|
delayMessage: data.delayMessage,
|
||||||
|
unknownMessage: data.unknownMessage,
|
||||||
|
listeningFromMe: data.listeningFromMe,
|
||||||
|
stopBotFromMe: data.stopBotFromMe,
|
||||||
|
keepOpen: data.keepOpen,
|
||||||
|
debounceTime: data.debounceTime,
|
||||||
|
instanceId: instanceId,
|
||||||
|
triggerType: data.triggerType,
|
||||||
|
triggerOperator: data.triggerOperator,
|
||||||
|
triggerValue: data.triggerValue,
|
||||||
|
ignoreJids: data.ignoreJids,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return bot;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error updating dify');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async deleteBot(instance: InstanceDto, botId: string) {
|
||||||
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const bot = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
id: botId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!bot) {
|
||||||
|
throw new Error('Dify not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bot.instanceId !== instanceId) {
|
||||||
|
throw new Error('Dify not found');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.prismaRepository.integrationSession.deleteMany({
|
||||||
|
where: {
|
||||||
|
botId: botId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.botRepository.delete({
|
||||||
|
where: {
|
||||||
|
id: botId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { bot: { id: botId } };
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error deleting dify bot');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings
|
||||||
public async settings(instance: InstanceDto, data: any) {
|
public async settings(instance: InstanceDto, data: any) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.setDefaultSettings(instance, data);
|
try {
|
||||||
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const settings = await this.settingsRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (settings) {
|
||||||
|
const updateSettings = await this.settingsRepository.update({
|
||||||
|
where: {
|
||||||
|
id: settings.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
expire: data.expire,
|
||||||
|
keywordFinish: data.keywordFinish,
|
||||||
|
delayMessage: data.delayMessage,
|
||||||
|
unknownMessage: data.unknownMessage,
|
||||||
|
listeningFromMe: data.listeningFromMe,
|
||||||
|
stopBotFromMe: data.stopBotFromMe,
|
||||||
|
keepOpen: data.keepOpen,
|
||||||
|
debounceTime: data.debounceTime,
|
||||||
|
difyIdFallback: data.difyIdFallback,
|
||||||
|
ignoreJids: data.ignoreJids,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
expire: updateSettings.expire,
|
||||||
|
keywordFinish: updateSettings.keywordFinish,
|
||||||
|
delayMessage: updateSettings.delayMessage,
|
||||||
|
unknownMessage: updateSettings.unknownMessage,
|
||||||
|
listeningFromMe: updateSettings.listeningFromMe,
|
||||||
|
stopBotFromMe: updateSettings.stopBotFromMe,
|
||||||
|
keepOpen: updateSettings.keepOpen,
|
||||||
|
debounceTime: updateSettings.debounceTime,
|
||||||
|
difyIdFallback: updateSettings.difyIdFallback,
|
||||||
|
ignoreJids: updateSettings.ignoreJids,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const newSetttings = await this.settingsRepository.create({
|
||||||
|
data: {
|
||||||
|
expire: data.expire,
|
||||||
|
keywordFinish: data.keywordFinish,
|
||||||
|
delayMessage: data.delayMessage,
|
||||||
|
unknownMessage: data.unknownMessage,
|
||||||
|
listeningFromMe: data.listeningFromMe,
|
||||||
|
stopBotFromMe: data.stopBotFromMe,
|
||||||
|
keepOpen: data.keepOpen,
|
||||||
|
debounceTime: data.debounceTime,
|
||||||
|
difyIdFallback: data.difyIdFallback,
|
||||||
|
ignoreJids: data.ignoreJids,
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
expire: newSetttings.expire,
|
||||||
|
keywordFinish: newSetttings.keywordFinish,
|
||||||
|
delayMessage: newSetttings.delayMessage,
|
||||||
|
unknownMessage: newSetttings.unknownMessage,
|
||||||
|
listeningFromMe: newSetttings.listeningFromMe,
|
||||||
|
stopBotFromMe: newSetttings.stopBotFromMe,
|
||||||
|
keepOpen: newSetttings.keepOpen,
|
||||||
|
debounceTime: newSetttings.debounceTime,
|
||||||
|
difyIdFallback: newSetttings.difyIdFallback,
|
||||||
|
ignoreJids: newSetttings.ignoreJids,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error setting default settings');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchSettings(instance: InstanceDto) {
|
public async fetchSettings(instance: InstanceDto) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.fetchDefaultSettings(instance);
|
try {
|
||||||
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const settings = await this.settingsRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
Fallback: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!settings) {
|
||||||
|
return {
|
||||||
|
expire: 0,
|
||||||
|
keywordFinish: '',
|
||||||
|
delayMessage: 0,
|
||||||
|
unknownMessage: '',
|
||||||
|
listeningFromMe: false,
|
||||||
|
stopBotFromMe: false,
|
||||||
|
keepOpen: false,
|
||||||
|
ignoreJids: [],
|
||||||
|
difyIdFallback: '',
|
||||||
|
fallback: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
expire: settings.expire,
|
||||||
|
keywordFinish: settings.keywordFinish,
|
||||||
|
delayMessage: settings.delayMessage,
|
||||||
|
unknownMessage: settings.unknownMessage,
|
||||||
|
listeningFromMe: settings.listeningFromMe,
|
||||||
|
stopBotFromMe: settings.stopBotFromMe,
|
||||||
|
keepOpen: settings.keepOpen,
|
||||||
|
ignoreJids: settings.ignoreJids,
|
||||||
|
difyIdFallback: settings.difyIdFallback,
|
||||||
|
fallback: settings.Fallback,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error fetching default settings');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sessions
|
||||||
public async changeStatus(instance: InstanceDto, data: any) {
|
public async changeStatus(instance: InstanceDto, data: any) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.changeStatus(instance, data);
|
try {
|
||||||
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const defaultSettingCheck = await this.settingsRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const remoteJid = data.remoteJid;
|
||||||
|
const status = data.status;
|
||||||
|
|
||||||
|
if (status === 'delete') {
|
||||||
|
await this.sessionRepository.deleteMany({
|
||||||
|
where: {
|
||||||
|
remoteJid: remoteJid,
|
||||||
|
botId: { not: null },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { bot: { remoteJid: remoteJid, status: status } };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'closed') {
|
||||||
|
if (defaultSettingCheck?.keepOpen) {
|
||||||
|
await this.sessionRepository.updateMany({
|
||||||
|
where: {
|
||||||
|
remoteJid: remoteJid,
|
||||||
|
botId: { not: null },
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: 'closed',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await this.sessionRepository.deleteMany({
|
||||||
|
where: {
|
||||||
|
remoteJid: remoteJid,
|
||||||
|
botId: { not: null },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { bot: { ...instance, bot: { remoteJid: remoteJid, status: status } } };
|
||||||
|
} else {
|
||||||
|
const session = await this.sessionRepository.updateMany({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
remoteJid: remoteJid,
|
||||||
|
botId: { not: null },
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: status,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const botData = {
|
||||||
|
remoteJid: remoteJid,
|
||||||
|
status: status,
|
||||||
|
session,
|
||||||
|
};
|
||||||
|
|
||||||
|
return { bot: { ...instance, bot: botData } };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error changing status');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchSessions(instance: InstanceDto, difyId: string) {
|
public async fetchSessions(instance: InstanceDto, botId: string, remoteJid?: string) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.fetchSessions(instance, difyId);
|
try {
|
||||||
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const bot = await this.botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
id: botId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (bot && bot.instanceId !== instanceId) {
|
||||||
|
throw new Error('Dify not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.sessionRepository.findMany({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
remoteJid,
|
||||||
|
botId: bot ? botId : { not: null },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error fetching sessions');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ignoreJid(instance: InstanceDto, data: DifyIgnoreJidDto) {
|
public async ignoreJid(instance: InstanceDto, data: IgnoreJidDto) {
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) throw new BadRequestException('Dify is disabled');
|
if (!this.integrationEnabled) throw new BadRequestException('Dify is disabled');
|
||||||
|
|
||||||
return this.difyService.ignoreJid(instance, data);
|
try {
|
||||||
|
const instanceId = await this.prismaRepository.instance
|
||||||
|
.findFirst({
|
||||||
|
where: {
|
||||||
|
name: instance.instanceName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
|
const settings = await this.settingsRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!settings) {
|
||||||
|
throw new Error('Settings not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
let ignoreJids: any = settings?.ignoreJids || [];
|
||||||
|
|
||||||
|
if (data.action === 'add') {
|
||||||
|
if (ignoreJids.includes(data.remoteJid)) return { ignoreJids: ignoreJids };
|
||||||
|
|
||||||
|
ignoreJids.push(data.remoteJid);
|
||||||
|
} else {
|
||||||
|
ignoreJids = ignoreJids.filter((jid) => jid !== data.remoteJid);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateSettings = await this.settingsRepository.update({
|
||||||
|
where: {
|
||||||
|
id: settings.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
ignoreJids: ignoreJids,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
ignoreJids: updateSettings.ignoreJids,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
throw new Error('Error setting default settings');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async emit({
|
// Emit
|
||||||
instance,
|
public async emit({ instance, remoteJid, msg }: EmitData) {
|
||||||
remoteJid,
|
if (!this.integrationEnabled) return;
|
||||||
msg,
|
|
||||||
}: {
|
|
||||||
instance: InstanceDto;
|
|
||||||
remoteJid: string;
|
|
||||||
msg: any;
|
|
||||||
pushName?: string;
|
|
||||||
}) {
|
|
||||||
if (!configService.get<Dify>('DIFY').ENABLED) return;
|
|
||||||
|
|
||||||
await this.difyService.sendDify(instance, remoteJid, msg);
|
try {
|
||||||
|
const settings = await this.prismaRepository.difySetting.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId: instance.instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.checkIgnoreJids(settings?.ignoreJids, remoteJid)) return;
|
||||||
|
|
||||||
|
const session = await this.getSession(remoteJid, instance);
|
||||||
|
|
||||||
|
const content = getConversationMessage(msg);
|
||||||
|
|
||||||
|
const findBot = await this.findBotTrigger(
|
||||||
|
this.botRepository,
|
||||||
|
this.settingsRepository,
|
||||||
|
content,
|
||||||
|
instance,
|
||||||
|
session,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!findBot) return;
|
||||||
|
|
||||||
|
let expire = findBot.expire;
|
||||||
|
let keywordFinish = findBot.keywordFinish;
|
||||||
|
let delayMessage = findBot.delayMessage;
|
||||||
|
let unknownMessage = findBot.unknownMessage;
|
||||||
|
let listeningFromMe = findBot.listeningFromMe;
|
||||||
|
let stopBotFromMe = findBot.stopBotFromMe;
|
||||||
|
let keepOpen = findBot.keepOpen;
|
||||||
|
let debounceTime = findBot.debounceTime;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!expire ||
|
||||||
|
!keywordFinish ||
|
||||||
|
!delayMessage ||
|
||||||
|
!unknownMessage ||
|
||||||
|
!listeningFromMe ||
|
||||||
|
!stopBotFromMe ||
|
||||||
|
!keepOpen ||
|
||||||
|
!debounceTime
|
||||||
|
) {
|
||||||
|
if (!expire) expire = settings.expire;
|
||||||
|
|
||||||
|
if (!keywordFinish) keywordFinish = settings.keywordFinish;
|
||||||
|
|
||||||
|
if (!delayMessage) delayMessage = settings.delayMessage;
|
||||||
|
|
||||||
|
if (!unknownMessage) unknownMessage = settings.unknownMessage;
|
||||||
|
|
||||||
|
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
|
||||||
|
|
||||||
|
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
|
||||||
|
|
||||||
|
if (!keepOpen) keepOpen = settings.keepOpen;
|
||||||
|
|
||||||
|
if (!debounceTime) debounceTime = settings.debounceTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = msg.key as {
|
||||||
|
id: string;
|
||||||
|
remoteJid: string;
|
||||||
|
fromMe: boolean;
|
||||||
|
participant: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (stopBotFromMe && key.fromMe && session) {
|
||||||
|
await this.prismaRepository.integrationSession.update({
|
||||||
|
where: {
|
||||||
|
id: session.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: 'paused',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!listeningFromMe && key.fromMe) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debounceTime && debounceTime > 0) {
|
||||||
|
this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {
|
||||||
|
await this.difyService.processDify(
|
||||||
|
this.waMonitor.waInstances[instance.instanceName],
|
||||||
|
remoteJid,
|
||||||
|
findBot,
|
||||||
|
session,
|
||||||
|
settings,
|
||||||
|
debouncedContent,
|
||||||
|
msg?.pushName,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await this.difyService.processDify(
|
||||||
|
this.waMonitor.waInstances[instance.instanceName],
|
||||||
|
remoteJid,
|
||||||
|
findBot,
|
||||||
|
session,
|
||||||
|
settings,
|
||||||
|
content,
|
||||||
|
msg?.pushName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
import { $Enums, TriggerOperator, TriggerType } from '@prisma/client';
|
import { $Enums, TriggerOperator, TriggerType } from '@prisma/client';
|
||||||
|
|
||||||
export class Session {
|
|
||||||
remoteJid?: string;
|
|
||||||
sessionId?: string;
|
|
||||||
status?: string;
|
|
||||||
createdAt?: number;
|
|
||||||
updateAt?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DifyDto {
|
export class DifyDto {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
description?: string;
|
description?: string;
|
||||||
@ -40,8 +32,3 @@ export class DifySettingDto {
|
|||||||
difyIdFallback?: string;
|
difyIdFallback?: string;
|
||||||
ignoreJids?: any;
|
ignoreJids?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DifyIgnoreJidDto {
|
|
||||||
remoteJid?: string;
|
|
||||||
action?: string;
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { RouterBroker } from '@api/abstract/abstract.router';
|
import { RouterBroker } from '@api/abstract/abstract.router';
|
||||||
|
import { IgnoreJidDto } from '@api/dto/chatbot.dto';
|
||||||
import { InstanceDto } from '@api/dto/instance.dto';
|
import { InstanceDto } from '@api/dto/instance.dto';
|
||||||
import { DifyDto, DifyIgnoreJidDto, DifySettingDto } from '@api/integrations/chatbot/dify/dto/dify.dto';
|
import { DifyDto, DifySettingDto } from '@api/integrations/chatbot/dify/dto/dify.dto';
|
||||||
import { HttpStatus } from '@api/routes/index.router';
|
import { HttpStatus } from '@api/routes/index.router';
|
||||||
import { difyController } from '@api/server.module';
|
import { difyController } from '@api/server.module';
|
||||||
import {
|
import {
|
||||||
@ -21,7 +22,7 @@ export class DifyRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: difySchema,
|
schema: difySchema,
|
||||||
ClassRef: DifyDto,
|
ClassRef: DifyDto,
|
||||||
execute: (instance, data) => difyController.createDify(instance, data),
|
execute: (instance, data) => difyController.createBot(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
@ -31,7 +32,7 @@ export class DifyRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => difyController.findDify(instance),
|
execute: (instance) => difyController.findBot(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -41,7 +42,7 @@ export class DifyRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => difyController.fetchDify(instance, req.params.difyId),
|
execute: (instance) => difyController.fetchBot(instance, req.params.difyId),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -51,7 +52,7 @@ export class DifyRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: difySchema,
|
schema: difySchema,
|
||||||
ClassRef: DifyDto,
|
ClassRef: DifyDto,
|
||||||
execute: (instance, data) => difyController.updateDify(instance, req.params.difyId, data),
|
execute: (instance, data) => difyController.updateBot(instance, req.params.difyId, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -61,7 +62,7 @@ export class DifyRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => difyController.deleteDify(instance, req.params.difyId),
|
execute: (instance) => difyController.deleteBot(instance, req.params.difyId),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -107,10 +108,10 @@ export class DifyRouter extends RouterBroker {
|
|||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {
|
.post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {
|
||||||
const response = await this.dataValidate<DifyIgnoreJidDto>({
|
const response = await this.dataValidate<IgnoreJidDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: difyIgnoreJidSchema,
|
schema: difyIgnoreJidSchema,
|
||||||
ClassRef: DifyIgnoreJidDto,
|
ClassRef: IgnoreJidDto,
|
||||||
execute: (instance, data) => difyController.ignoreJid(instance, data),
|
execute: (instance, data) => difyController.ignoreJid(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -10,9 +10,9 @@ import { BadRequestException } from '@exceptions';
|
|||||||
import { getConversationMessage } from '@utils/getConversationMessage';
|
import { getConversationMessage } from '@utils/getConversationMessage';
|
||||||
import OpenAI from 'openai';
|
import OpenAI from 'openai';
|
||||||
|
|
||||||
import { ChatbotController } from '../../chatbot.controller';
|
import { ChatbotController, ChatbotControllerInterface, EmitData } from '../../chatbot.controller';
|
||||||
|
|
||||||
export class OpenaiController extends ChatbotController {
|
export class OpenaiController extends ChatbotController implements ChatbotControllerInterface {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly openaiService: OpenaiService,
|
private readonly openaiService: OpenaiService,
|
||||||
prismaRepository: PrismaRepository,
|
prismaRepository: PrismaRepository,
|
||||||
@ -28,13 +28,13 @@ export class OpenaiController extends ChatbotController {
|
|||||||
|
|
||||||
public readonly logger = new Logger(OpenaiController.name);
|
public readonly logger = new Logger(OpenaiController.name);
|
||||||
|
|
||||||
private integrationEnabled = configService.get<Openai>('OPENAI').ENABLED;
|
integrationEnabled = configService.get<Openai>('OPENAI').ENABLED;
|
||||||
|
botRepository: any;
|
||||||
|
settingsRepository: any;
|
||||||
|
sessionRepository: any;
|
||||||
|
userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
|
||||||
private client: OpenAI;
|
private client: OpenAI;
|
||||||
private botRepository: any;
|
|
||||||
private settingsRepository: any;
|
|
||||||
private sessionRepository: any;
|
|
||||||
private credsRepository: any;
|
private credsRepository: any;
|
||||||
private userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
|
|
||||||
|
|
||||||
// Credentials
|
// Credentials
|
||||||
public async createOpenaiCreds(instance: InstanceDto, data: OpenaiCredsDto) {
|
public async createOpenaiCreds(instance: InstanceDto, data: OpenaiCredsDto) {
|
||||||
@ -311,7 +311,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const openaiBot = await this.botRepository.create({
|
const bot = await this.botRepository.create({
|
||||||
data: {
|
data: {
|
||||||
enabled: data.enabled,
|
enabled: data.enabled,
|
||||||
description: data.description,
|
description: data.description,
|
||||||
@ -340,7 +340,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return openaiBot;
|
return bot;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
throw new Error('Error creating openai bot');
|
throw new Error('Error creating openai bot');
|
||||||
@ -358,7 +358,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
})
|
})
|
||||||
.then((instance) => instance.id);
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
const openaiBots = await this.botRepository.findMany({
|
const bots = await this.botRepository.findMany({
|
||||||
where: {
|
where: {
|
||||||
instanceId,
|
instanceId,
|
||||||
},
|
},
|
||||||
@ -367,11 +367,11 @@ export class OpenaiController extends ChatbotController {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!openaiBots.length) {
|
if (!bots.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return openaiBots;
|
return bots;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchBot(instance: InstanceDto, botId: string) {
|
public async fetchBot(instance: InstanceDto, botId: string) {
|
||||||
@ -385,7 +385,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
})
|
})
|
||||||
.then((instance) => instance.id);
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
const openaiBot = await this.botRepository.findFirst({
|
const bot = await this.botRepository.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: botId,
|
id: botId,
|
||||||
},
|
},
|
||||||
@ -394,15 +394,15 @@ export class OpenaiController extends ChatbotController {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!openaiBot) {
|
if (!bot) {
|
||||||
throw new Error('Openai Bot not found');
|
throw new Error('Openai Bot not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openaiBot.instanceId !== instanceId) {
|
if (bot.instanceId !== instanceId) {
|
||||||
throw new Error('Openai Bot not found');
|
throw new Error('Openai Bot not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return openaiBot;
|
return bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateBot(instance: InstanceDto, botId: string, data: OpenaiDto) {
|
public async updateBot(instance: InstanceDto, botId: string, data: OpenaiDto) {
|
||||||
@ -416,17 +416,17 @@ export class OpenaiController extends ChatbotController {
|
|||||||
})
|
})
|
||||||
.then((instance) => instance.id);
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
const openaiBot = await this.botRepository.findFirst({
|
const bot = await this.botRepository.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: botId,
|
id: botId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!openaiBot) {
|
if (!bot) {
|
||||||
throw new Error('Openai Bot not found');
|
throw new Error('Openai Bot not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openaiBot.instanceId !== instanceId) {
|
if (bot.instanceId !== instanceId) {
|
||||||
throw new Error('Openai Bot not found');
|
throw new Error('Openai Bot not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +522,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const openaiBot = await this.botRepository.update({
|
const bot = await this.botRepository.update({
|
||||||
where: {
|
where: {
|
||||||
id: botId,
|
id: botId,
|
||||||
},
|
},
|
||||||
@ -553,7 +553,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return openaiBot;
|
return bot;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
throw new Error('Error updating openai bot');
|
throw new Error('Error updating openai bot');
|
||||||
@ -571,17 +571,17 @@ export class OpenaiController extends ChatbotController {
|
|||||||
})
|
})
|
||||||
.then((instance) => instance.id);
|
.then((instance) => instance.id);
|
||||||
|
|
||||||
const openaiBot = await this.botRepository.findFirst({
|
const bot = await this.botRepository.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: botId,
|
id: botId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!openaiBot) {
|
if (!bot) {
|
||||||
throw new Error('Openai bot not found');
|
throw new Error('Openai bot not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openaiBot.instanceId !== instanceId) {
|
if (bot.instanceId !== instanceId) {
|
||||||
throw new Error('Openai bot not found');
|
throw new Error('Openai bot not found');
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -597,7 +597,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return { openaiBot: { id: botId } };
|
return { bot: { id: botId } };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
throw new Error('Error deleting openai bot');
|
throw new Error('Error deleting openai bot');
|
||||||
@ -925,17 +925,7 @@ export class OpenaiController extends ChatbotController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit
|
// Emit
|
||||||
public async emit({
|
public async emit({ instance, remoteJid, msg, pushName }: EmitData) {
|
||||||
instance,
|
|
||||||
remoteJid,
|
|
||||||
msg,
|
|
||||||
pushName,
|
|
||||||
}: {
|
|
||||||
instance: InstanceDto;
|
|
||||||
remoteJid: string;
|
|
||||||
msg: any;
|
|
||||||
pushName?: string;
|
|
||||||
}) {
|
|
||||||
if (!this.integrationEnabled) return;
|
if (!this.integrationEnabled) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,5 @@
|
|||||||
import { TriggerOperator, TriggerType } from '@prisma/client';
|
import { TriggerOperator, TriggerType } from '@prisma/client';
|
||||||
|
|
||||||
export class Session {
|
|
||||||
remoteJid?: string;
|
|
||||||
sessionId?: string;
|
|
||||||
status?: string;
|
|
||||||
createdAt?: number;
|
|
||||||
updateAt?: number;
|
|
||||||
prefilledVariables?: PrefilledVariables;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PrefilledVariables {
|
export class PrefilledVariables {
|
||||||
remoteJid?: string;
|
remoteJid?: string;
|
||||||
pushName?: string;
|
pushName?: string;
|
||||||
@ -47,8 +38,3 @@ export class TypebotSettingDto {
|
|||||||
typebotIdFallback?: string;
|
typebotIdFallback?: string;
|
||||||
ignoreJids?: any;
|
ignoreJids?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TypebotIgnoreJidDto {
|
|
||||||
remoteJid?: string;
|
|
||||||
action?: string;
|
|
||||||
}
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { RouterBroker } from '@api/abstract/abstract.router';
|
import { RouterBroker } from '@api/abstract/abstract.router';
|
||||||
|
import { IgnoreJidDto } from '@api/dto/chatbot.dto';
|
||||||
import { InstanceDto } from '@api/dto/instance.dto';
|
import { InstanceDto } from '@api/dto/instance.dto';
|
||||||
import { TypebotDto, TypebotIgnoreJidDto, TypebotSettingDto } from '@api/integrations/chatbot/typebot/dto/typebot.dto';
|
import { TypebotDto, TypebotSettingDto } from '@api/integrations/chatbot/typebot/dto/typebot.dto';
|
||||||
import { typebotController } from '@api/server.module';
|
|
||||||
import { HttpStatus } from '@api/routes/index.router';
|
import { HttpStatus } from '@api/routes/index.router';
|
||||||
|
import { typebotController } from '@api/server.module';
|
||||||
import {
|
import {
|
||||||
instanceSchema,
|
instanceSchema,
|
||||||
typebotIgnoreJidSchema,
|
typebotIgnoreJidSchema,
|
||||||
@ -22,7 +23,7 @@ export class TypebotRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: typebotSchema,
|
schema: typebotSchema,
|
||||||
ClassRef: TypebotDto,
|
ClassRef: TypebotDto,
|
||||||
execute: (instance, data) => typebotController.createTypebot(instance, data),
|
execute: (instance, data) => typebotController.createBot(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
@ -32,7 +33,7 @@ export class TypebotRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => typebotController.findTypebot(instance),
|
execute: (instance) => typebotController.findBot(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -42,7 +43,7 @@ export class TypebotRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => typebotController.fetchTypebot(instance, req.params.typebotId),
|
execute: (instance) => typebotController.fetchBot(instance, req.params.typebotId),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -52,7 +53,7 @@ export class TypebotRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: typebotSchema,
|
schema: typebotSchema,
|
||||||
ClassRef: TypebotDto,
|
ClassRef: TypebotDto,
|
||||||
execute: (instance, data) => typebotController.updateTypebot(instance, req.params.typebotId, data),
|
execute: (instance, data) => typebotController.updateBot(instance, req.params.typebotId, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -62,7 +63,7 @@ export class TypebotRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => typebotController.deleteTypebot(instance, req.params.typebotId),
|
execute: (instance) => typebotController.deleteBot(instance, req.params.typebotId),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -92,7 +93,7 @@ export class TypebotRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: typebotStartSchema,
|
schema: typebotStartSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance, data) => typebotController.startTypebot(instance, data),
|
execute: (instance, data) => typebotController.startBot(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -118,10 +119,10 @@ export class TypebotRouter extends RouterBroker {
|
|||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {
|
.post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {
|
||||||
const response = await this.dataValidate<TypebotIgnoreJidDto>({
|
const response = await this.dataValidate<IgnoreJidDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: typebotIgnoreJidSchema,
|
schema: typebotIgnoreJidSchema,
|
||||||
ClassRef: TypebotIgnoreJidDto,
|
ClassRef: IgnoreJidDto,
|
||||||
execute: (instance, data) => typebotController.ignoreJid(instance, data),
|
execute: (instance, data) => typebotController.ignoreJid(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -108,12 +108,12 @@ export const webhookController = new WebhookController(prismaRepository, waMonit
|
|||||||
|
|
||||||
// chatbots
|
// chatbots
|
||||||
const typebotService = new TypebotService(waMonitor, configService, prismaRepository);
|
const typebotService = new TypebotService(waMonitor, configService, prismaRepository);
|
||||||
export const typebotController = new TypebotController(typebotService);
|
export const typebotController = new TypebotController(typebotService, prismaRepository, waMonitor);
|
||||||
|
|
||||||
const openaiService = new OpenaiService(waMonitor, configService, prismaRepository);
|
const openaiService = new OpenaiService(waMonitor, configService, prismaRepository);
|
||||||
export const openaiController = new OpenaiController(openaiService);
|
export const openaiController = new OpenaiController(openaiService, prismaRepository, waMonitor);
|
||||||
|
|
||||||
const difyService = new DifyService(waMonitor, configService, prismaRepository);
|
const difyService = new DifyService(waMonitor, configService, prismaRepository);
|
||||||
export const difyController = new DifyController(difyService);
|
export const difyController = new DifyController(difyService, prismaRepository, waMonitor);
|
||||||
|
|
||||||
logger.info('Module - ON');
|
logger.info('Module - ON');
|
||||||
|
Loading…
Reference in New Issue
Block a user