refactor: evolution bot

This commit is contained in:
Davidson Gomes
2024-08-25 10:22:22 -03:00
parent 8b7ff37261
commit d776770d09
22 changed files with 509 additions and 189 deletions

View File

@@ -2,8 +2,8 @@ import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service';
import {
difyController,
evolutionBotController,
flowiseController,
genericController,
openaiController,
typebotController,
} from '@api/server.module';
@@ -89,7 +89,7 @@ export class ChatbotController {
pushName,
isIntegration,
};
await genericController.emit(emitData);
await evolutionBotController.emit(emitData);
await typebotController.emit(emitData);

View File

@@ -4,8 +4,8 @@ import { OpenaiRouter } from '@api/integrations/chatbot/openai/routes/openai.rou
import { TypebotRouter } from '@api/integrations/chatbot/typebot/routes/typebot.router';
import { Router } from 'express';
import { EvolutionBotRouter } from './evolutionBot/routes/evolutionBot.router';
import { FlowiseRouter } from './flowise/routes/flowise.router';
import { GenericRouter } from './generic/routes/generic.router';
export class ChatbotRouter {
public readonly router: Router;
@@ -13,7 +13,7 @@ export class ChatbotRouter {
constructor(...guards: any[]) {
this.router = Router();
this.router.use('/generic', new GenericRouter(...guards).router);
this.router.use('/evolutionBot', new EvolutionBotRouter(...guards).router);
this.router.use('/chatwoot', new ChatwootRouter(...guards).router);
this.router.use('/typebot', new TypebotRouter(...guards).router);
this.router.use('/openai', new OpenaiRouter(...guards).router);

View File

@@ -1,6 +1,6 @@
export * from '@api/integrations/chatbot/chatwoot/validate/chatwoot.schema';
export * from '@api/integrations/chatbot/dify/validate/dify.schema';
export * from '@api/integrations/chatbot/evolutionBot/validate/evolutionBot.schema';
export * from '@api/integrations/chatbot/flowise/validate/flowise.schema';
export * from '@api/integrations/chatbot/generic/validate/generic.schema';
export * from '@api/integrations/chatbot/openai/validate/openai.schema';
export * from '@api/integrations/chatbot/typebot/validate/typebot.schema';

View File

@@ -1585,21 +1585,21 @@ export class ChatwootService {
private getMessageContent(types: any) {
const typeKey = Object.keys(types).find((key) => types[key] !== undefined);
let result = typeKey ? types[typeKey] : undefined;
// Remove externalAdReplyBody| in Chatwoot (Already Have)
if (result && typeof result === 'string' && result.includes('externalAdReplyBody|')) {
result = result.split('externalAdReplyBody|').filter(Boolean).join('');
}
if (typeKey === 'locationMessage' || typeKey === 'liveLocationMessage') {
const latitude = result.degreesLatitude;
const longitude = result.degreesLongitude;
const locationName = result?.name;
const locationAddress = result?.address;
const formattedLocation =
`*${i18next.t('cw.locationMessage.location')}:*\n\n` +
`_${i18next.t('cw.locationMessage.latitude')}:_ ${latitude} \n` +
@@ -1608,7 +1608,7 @@ export class ChatwootService {
(locationAddress ? `_${i18next.t('cw.locationMessage.locationAddress')}:_ ${locationAddress} \n` : '') +
`_${i18next.t('cw.locationMessage.locationUrl')}:_ ` +
`https://www.google.com/maps/search/?api=1&query=${latitude},${longitude}`;
return formattedLocation;
}

View File

@@ -771,6 +771,10 @@ export class DifyController extends ChatbotController implements ChatbotControll
return;
}
if (session && !session.awaitUser) {
return;
}
if (debounceTime && debounceTime > 0) {
this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {
await this.difyService.processDify(

View File

@@ -3,27 +3,27 @@ import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service';
import { Logger } from '@config/logger.config';
import { GenericBot } from '@prisma/client';
import { EvolutionBot } from '@prisma/client';
import { getConversationMessage } from '@utils/getConversationMessage';
import { ChatbotController, ChatbotControllerInterface, EmitData } from '../../chatbot.controller';
import { GenericBotDto } from '../dto/generic.dto';
import { GenericService } from '../services/generic.service';
import { EvolutionBotDto } from '../dto/evolutionBot.dto';
import { EvolutionBotService } from '../services/evolutionBot.service';
export class GenericController extends ChatbotController implements ChatbotControllerInterface {
export class EvolutionBotController extends ChatbotController implements ChatbotControllerInterface {
constructor(
private readonly genericService: GenericService,
private readonly evolutionBotService: EvolutionBotService,
prismaRepository: PrismaRepository,
waMonitor: WAMonitoringService,
) {
super(prismaRepository, waMonitor);
this.botRepository = this.prismaRepository.genericBot;
this.settingsRepository = this.prismaRepository.genericSetting;
this.botRepository = this.prismaRepository.evolutionBot;
this.settingsRepository = this.prismaRepository.evolutionBotSetting;
this.sessionRepository = this.prismaRepository.integrationSession;
}
public readonly logger = new Logger(GenericController.name);
public readonly logger = new Logger(EvolutionBotController.name);
integrationEnabled: boolean;
botRepository: any;
@@ -32,7 +32,7 @@ export class GenericController extends ChatbotController implements ChatbotContr
userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
// Bots
public async createBot(instance: InstanceDto, data: GenericBotDto) {
public async createBot(instance: InstanceDto, data: EvolutionBotDto) {
const instanceId = await this.prismaRepository.instance
.findFirst({
where: {
@@ -220,7 +220,7 @@ export class GenericController extends ChatbotController implements ChatbotContr
return bot;
}
public async updateBot(instance: InstanceDto, botId: string, data: GenericBotDto) {
public async updateBot(instance: InstanceDto, botId: string, data: EvolutionBotDto) {
const instanceId = await this.prismaRepository.instance
.findFirst({
where: {
@@ -626,7 +626,7 @@ export class GenericController extends ChatbotController implements ChatbotContr
instanceId: instanceId,
remoteJid,
botId: bot ? botId : { not: null },
type: 'generic',
type: 'evolution',
},
});
} catch (error) {
@@ -704,7 +704,7 @@ export class GenericController extends ChatbotController implements ChatbotContr
content,
instance,
session,
)) as GenericBot;
)) as EvolutionBot;
if (!findBot) return;
@@ -743,9 +743,13 @@ export class GenericController extends ChatbotController implements ChatbotContr
return;
}
if (session && !session.awaitUser) {
return;
}
if (debounceTime && debounceTime > 0) {
this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {
await this.genericService.processBot(
await this.evolutionBotService.processBot(
this.waMonitor.waInstances[instance.instanceName],
remoteJid,
findBot,
@@ -756,7 +760,7 @@ export class GenericController extends ChatbotController implements ChatbotContr
);
});
} else {
await this.genericService.processBot(
await this.evolutionBotService.processBot(
this.waMonitor.waInstances[instance.instanceName],
remoteJid,
findBot,

View File

@@ -1,6 +1,6 @@
import { TriggerOperator, TriggerType } from '@prisma/client';
export class GenericBotDto {
export class EvolutionBotDto {
enabled?: boolean;
description?: string;
apiUrl?: string;
@@ -19,7 +19,7 @@ export class GenericBotDto {
ignoreJids?: any;
}
export class GenericBotSettingDto {
export class EvolutionBotSettingDto {
expire?: number;
keywordFinish?: string;
delayMessage?: number;

View File

@@ -2,28 +2,28 @@ import { RouterBroker } from '@api/abstract/abstract.router';
import { IgnoreJidDto } from '@api/dto/chatbot.dto';
import { InstanceDto } from '@api/dto/instance.dto';
import { HttpStatus } from '@api/routes/index.router';
import { genericController } from '@api/server.module';
import { evolutionBotController } from '@api/server.module';
import { instanceSchema } from '@validate/instance.schema';
import { RequestHandler, Router } from 'express';
import { GenericBotDto, GenericBotSettingDto } from '../dto/generic.dto';
import { EvolutionBotDto, EvolutionBotSettingDto } from '../dto/evolutionBot.dto';
import {
genericIgnoreJidSchema,
genericSchema,
genericSettingSchema,
genericStatusSchema,
} from '../validate/generic.schema';
evolutionBotIgnoreJidSchema,
evolutionBotSchema,
evolutionBotSettingSchema,
evolutionBotStatusSchema,
} from '../validate/evolutionBot.schema';
export class GenericRouter extends RouterBroker {
export class EvolutionBotRouter extends RouterBroker {
constructor(...guards: RequestHandler[]) {
super();
this.router
.post(this.routerPath('create'), ...guards, async (req, res) => {
const response = await this.dataValidate<GenericBotDto>({
const response = await this.dataValidate<EvolutionBotDto>({
request: req,
schema: genericSchema,
ClassRef: GenericBotDto,
execute: (instance, data) => genericController.createBot(instance, data),
schema: evolutionBotSchema,
ClassRef: EvolutionBotDto,
execute: (instance, data) => evolutionBotController.createBot(instance, data),
});
res.status(HttpStatus.CREATED).json(response);
@@ -33,47 +33,47 @@ export class GenericRouter extends RouterBroker {
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => genericController.findBot(instance),
execute: (instance) => evolutionBotController.findBot(instance),
});
res.status(HttpStatus.OK).json(response);
})
.get(this.routerPath('fetch/:genericId'), ...guards, async (req, res) => {
.get(this.routerPath('fetch/:evolutionBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => genericController.fetchBot(instance, req.params.genericId),
execute: (instance) => evolutionBotController.fetchBot(instance, req.params.evolutionBotId),
});
res.status(HttpStatus.OK).json(response);
})
.put(this.routerPath('update/:genericId'), ...guards, async (req, res) => {
const response = await this.dataValidate<GenericBotDto>({
.put(this.routerPath('update/:evolutionBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<EvolutionBotDto>({
request: req,
schema: genericSchema,
ClassRef: GenericBotDto,
execute: (instance, data) => genericController.updateBot(instance, req.params.genericId, data),
schema: evolutionBotSchema,
ClassRef: EvolutionBotDto,
execute: (instance, data) => evolutionBotController.updateBot(instance, req.params.evolutionBotId, data),
});
res.status(HttpStatus.OK).json(response);
})
.delete(this.routerPath('delete/:genericId'), ...guards, async (req, res) => {
.delete(this.routerPath('delete/:evolutionBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => genericController.deleteBot(instance, req.params.genericId),
execute: (instance) => evolutionBotController.deleteBot(instance, req.params.evolutionBotId),
});
res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('settings'), ...guards, async (req, res) => {
const response = await this.dataValidate<GenericBotSettingDto>({
const response = await this.dataValidate<EvolutionBotSettingDto>({
request: req,
schema: genericSettingSchema,
ClassRef: GenericBotSettingDto,
execute: (instance, data) => genericController.settings(instance, data),
schema: evolutionBotSettingSchema,
ClassRef: EvolutionBotSettingDto,
execute: (instance, data) => evolutionBotController.settings(instance, data),
});
res.status(HttpStatus.OK).json(response);
@@ -83,7 +83,7 @@ export class GenericRouter extends RouterBroker {
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => genericController.fetchSettings(instance),
execute: (instance) => evolutionBotController.fetchSettings(instance),
});
res.status(HttpStatus.OK).json(response);
@@ -91,19 +91,19 @@ export class GenericRouter extends RouterBroker {
.post(this.routerPath('changeStatus'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: genericStatusSchema,
schema: evolutionBotStatusSchema,
ClassRef: InstanceDto,
execute: (instance, data) => genericController.changeStatus(instance, data),
execute: (instance, data) => evolutionBotController.changeStatus(instance, data),
});
res.status(HttpStatus.OK).json(response);
})
.get(this.routerPath('fetchSessions/:genericId'), ...guards, async (req, res) => {
.get(this.routerPath('fetchSessions/:evolutionBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => genericController.fetchSessions(instance, req.params.genericId),
execute: (instance) => evolutionBotController.fetchSessions(instance, req.params.evolutionBotId),
});
res.status(HttpStatus.OK).json(response);
@@ -111,9 +111,9 @@ export class GenericRouter extends RouterBroker {
.post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {
const response = await this.dataValidate<IgnoreJidDto>({
request: req,
schema: genericIgnoreJidSchema,
schema: evolutionBotIgnoreJidSchema,
ClassRef: IgnoreJidDto,
execute: (instance, data) => genericController.ignoreJid(instance, data),
execute: (instance, data) => evolutionBotController.ignoreJid(instance, data),
});
res.status(HttpStatus.OK).json(response);

View File

@@ -4,18 +4,18 @@ import { WAMonitoringService } from '@api/services/monitor.service';
import { Integration } from '@api/types/wa.types';
import { Auth, ConfigService, HttpServer } from '@config/env.config';
import { Logger } from '@config/logger.config';
import { GenericBot, GenericSetting, IntegrationSession } from '@prisma/client';
import { EvolutionBot, EvolutionBotSetting, IntegrationSession } from '@prisma/client';
import { sendTelemetry } from '@utils/sendTelemetry';
import axios from 'axios';
export class GenericService {
export class EvolutionBotService {
constructor(
private readonly waMonitor: WAMonitoringService,
private readonly configService: ConfigService,
private readonly prismaRepository: PrismaRepository,
) {}
private readonly logger = new Logger('GenericService');
private readonly logger = new Logger('EvolutionBotService');
public async createNewSession(instance: InstanceDto, data: any) {
try {
@@ -28,7 +28,7 @@ export class GenericService {
awaitUser: false,
botId: data.botId,
instanceId: instance.instanceId,
type: 'generic',
type: 'evolution',
},
});
@@ -46,13 +46,14 @@ export class GenericService {
private async sendMessageToBot(
instance: any,
session: IntegrationSession,
bot: GenericBot,
bot: EvolutionBot,
remoteJid: string,
pushName: string,
content: string,
) {
const payload: any = {
inputs: {
sessionId: session.id,
remoteJid: remoteJid,
pushName: pushName,
instanceName: instance.instanceName,
@@ -108,7 +109,7 @@ export class GenericService {
instance: any,
remoteJid: string,
session: IntegrationSession,
settings: GenericSetting,
settings: EvolutionBotSetting,
message: string,
) {
const regex = /!?\[(.*?)\]\((.*?)\)/g;
@@ -175,8 +176,8 @@ export class GenericService {
private async initNewSession(
instance: any,
remoteJid: string,
bot: GenericBot,
settings: GenericSetting,
bot: EvolutionBot,
settings: EvolutionBotSetting,
session: IntegrationSession,
content: string,
pushName?: string,
@@ -201,9 +202,9 @@ export class GenericService {
public async processBot(
instance: any,
remoteJid: string,
bot: GenericBot,
bot: EvolutionBot,
session: IntegrationSession,
settings: GenericSetting,
settings: EvolutionBotSetting,
content: string,
pushName?: string,
) {

View File

@@ -20,7 +20,7 @@ const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
};
};
export const genericSchema: JSONSchema7 = {
export const evolutionBotSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
@@ -45,7 +45,7 @@ export const genericSchema: JSONSchema7 = {
...isNotEmpty('enabled', 'apiUrl', 'triggerType'),
};
export const genericStatusSchema: JSONSchema7 = {
export const evolutionBotStatusSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
@@ -56,7 +56,7 @@ export const genericStatusSchema: JSONSchema7 = {
...isNotEmpty('remoteJid', 'status'),
};
export const genericSettingSchema: JSONSchema7 = {
export const evolutionBotSettingSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
@@ -95,7 +95,7 @@ export const genericSettingSchema: JSONSchema7 = {
),
};
export const genericIgnoreJidSchema: JSONSchema7 = {
export const evolutionBotIgnoreJidSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {

View File

@@ -743,6 +743,10 @@ export class FlowiseController extends ChatbotController implements ChatbotContr
return;
}
if (session && !session.awaitUser) {
return;
}
if (debounceTime && debounceTime > 0) {
this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {
await this.flowiseService.processBot(

View File

@@ -980,6 +980,10 @@ export class OpenaiController extends ChatbotController implements ChatbotContro
return;
}
if (session && !session.awaitUser) {
return;
}
if (debounceTime && debounceTime > 0) {
this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {
if (findBot.botType === 'assistant') {

View File

@@ -1056,6 +1056,10 @@ export class TypebotController extends ChatbotController implements ChatbotContr
return;
}
if (session && !session.awaitUser) {
return;
}
if (debounceTime && debounceTime > 0) {
this.processDebounce(this.userMessageDebounce, content, remoteJid, debounceTime, async (debouncedContent) => {
await this.typebotService.processTypebot(

View File

@@ -19,10 +19,10 @@ import { ChatwootController } from './integrations/chatbot/chatwoot/controllers/
import { ChatwootService } from './integrations/chatbot/chatwoot/services/chatwoot.service';
import { DifyController } from './integrations/chatbot/dify/controllers/dify.controller';
import { DifyService } from './integrations/chatbot/dify/services/dify.service';
import { EvolutionBotController } from './integrations/chatbot/evolutionBot/controllers/evolutionBot.controller';
import { EvolutionBotService } from './integrations/chatbot/evolutionBot/services/evolutionBot.service';
import { FlowiseController } from './integrations/chatbot/flowise/controllers/flowise.controller';
import { FlowiseService } from './integrations/chatbot/flowise/services/flowise.service';
import { GenericController } from './integrations/chatbot/generic/controllers/generic.controller';
import { GenericService } from './integrations/chatbot/generic/services/generic.service';
import { OpenaiController } from './integrations/chatbot/openai/controllers/openai.controller';
import { OpenaiService } from './integrations/chatbot/openai/services/openai.service';
import { TypebotController } from './integrations/chatbot/typebot/controllers/typebot.controller';
@@ -116,8 +116,8 @@ export const openaiController = new OpenaiController(openaiService, prismaReposi
const difyService = new DifyService(waMonitor, configService, prismaRepository);
export const difyController = new DifyController(difyService, prismaRepository, waMonitor);
const genericService = new GenericService(waMonitor, configService, prismaRepository);
export const genericController = new GenericController(genericService, prismaRepository, waMonitor);
const evolutionBotService = new EvolutionBotService(waMonitor, configService, prismaRepository);
export const evolutionBotController = new EvolutionBotController(evolutionBotService, prismaRepository, waMonitor);
const flowiseService = new FlowiseService(waMonitor, configService, prismaRepository);
export const flowiseController = new FlowiseController(flowiseService, prismaRepository, waMonitor);