mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-14 09:51:24 -06:00
refactor: openai integration
This commit is contained in:
parent
b58ad83c12
commit
8876797172
@ -285,29 +285,28 @@ model Websocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Typebot {
|
model Typebot {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
enabled Boolean @default(true) @db.Boolean
|
enabled Boolean @default(true) @db.Boolean
|
||||||
description String? @db.VarChar(255)
|
description String? @db.VarChar(255)
|
||||||
url String @db.VarChar(500)
|
url String @db.VarChar(500)
|
||||||
typebot String @db.VarChar(100)
|
typebot String @db.VarChar(100)
|
||||||
expire Int? @default(0) @db.Integer
|
expire Int? @default(0) @db.Integer
|
||||||
keywordFinish String? @db.VarChar(100)
|
keywordFinish String? @db.VarChar(100)
|
||||||
delayMessage Int? @db.Integer
|
delayMessage Int? @db.Integer
|
||||||
unknownMessage String? @db.VarChar(100)
|
unknownMessage String? @db.VarChar(100)
|
||||||
listeningFromMe Boolean? @default(false) @db.Boolean
|
listeningFromMe Boolean? @default(false) @db.Boolean
|
||||||
stopBotFromMe Boolean? @default(false) @db.Boolean
|
stopBotFromMe Boolean? @default(false) @db.Boolean
|
||||||
keepOpen Boolean? @default(false) @db.Boolean
|
keepOpen Boolean? @default(false) @db.Boolean
|
||||||
debounceTime Int? @db.Integer
|
debounceTime Int? @db.Integer
|
||||||
createdAt DateTime? @default(now()) @db.Timestamp
|
createdAt DateTime? @default(now()) @db.Timestamp
|
||||||
updatedAt DateTime? @updatedAt @db.Timestamp
|
updatedAt DateTime? @updatedAt @db.Timestamp
|
||||||
ignoreJids Json?
|
ignoreJids Json?
|
||||||
triggerType TriggerType?
|
triggerType TriggerType?
|
||||||
triggerOperator TriggerOperator?
|
triggerOperator TriggerOperator?
|
||||||
triggerValue String?
|
triggerValue String?
|
||||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
instanceId String
|
instanceId String
|
||||||
TypebotSetting TypebotSetting[]
|
TypebotSetting TypebotSetting[]
|
||||||
sessions IntegrationSession[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model TypebotSetting {
|
model TypebotSetting {
|
||||||
@ -354,37 +353,36 @@ model OpenaiCreds {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model OpenaiBot {
|
model OpenaiBot {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
enabled Boolean @default(true) @db.Boolean
|
enabled Boolean @default(true) @db.Boolean
|
||||||
description String? @db.VarChar(255)
|
description String? @db.VarChar(255)
|
||||||
botType OpenaiBotType
|
botType OpenaiBotType
|
||||||
assistantId String? @db.VarChar(255)
|
assistantId String? @db.VarChar(255)
|
||||||
functionUrl String? @db.VarChar(500)
|
functionUrl String? @db.VarChar(500)
|
||||||
model String? @db.VarChar(100)
|
model String? @db.VarChar(100)
|
||||||
systemMessages Json? @db.JsonB
|
systemMessages Json? @db.JsonB
|
||||||
assistantMessages Json? @db.JsonB
|
assistantMessages Json? @db.JsonB
|
||||||
userMessages Json? @db.JsonB
|
userMessages Json? @db.JsonB
|
||||||
maxTokens Int? @db.Integer
|
maxTokens Int? @db.Integer
|
||||||
expire Int? @default(0) @db.Integer
|
expire Int? @default(0) @db.Integer
|
||||||
keywordFinish String? @db.VarChar(100)
|
keywordFinish String? @db.VarChar(100)
|
||||||
delayMessage Int? @db.Integer
|
delayMessage Int? @db.Integer
|
||||||
unknownMessage String? @db.VarChar(100)
|
unknownMessage String? @db.VarChar(100)
|
||||||
listeningFromMe Boolean? @default(false) @db.Boolean
|
listeningFromMe Boolean? @default(false) @db.Boolean
|
||||||
stopBotFromMe Boolean? @default(false) @db.Boolean
|
stopBotFromMe Boolean? @default(false) @db.Boolean
|
||||||
keepOpen Boolean? @default(false) @db.Boolean
|
keepOpen Boolean? @default(false) @db.Boolean
|
||||||
debounceTime Int? @db.Integer
|
debounceTime Int? @db.Integer
|
||||||
ignoreJids Json?
|
ignoreJids Json?
|
||||||
triggerType TriggerType?
|
triggerType TriggerType?
|
||||||
triggerOperator TriggerOperator?
|
triggerOperator TriggerOperator?
|
||||||
triggerValue String?
|
triggerValue String?
|
||||||
createdAt DateTime? @default(now()) @db.Timestamp
|
createdAt DateTime? @default(now()) @db.Timestamp
|
||||||
updatedAt DateTime @updatedAt @db.Timestamp
|
updatedAt DateTime @updatedAt @db.Timestamp
|
||||||
OpenaiCreds OpenaiCreds @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade)
|
OpenaiCreds OpenaiCreds @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade)
|
||||||
openaiCredsId String
|
openaiCredsId String
|
||||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
instanceId String
|
instanceId String
|
||||||
OpenaiSetting OpenaiSetting[]
|
OpenaiSetting OpenaiSetting[]
|
||||||
sessions IntegrationSession[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model IntegrationSession {
|
model IntegrationSession {
|
||||||
@ -402,14 +400,7 @@ model IntegrationSession {
|
|||||||
instanceId String
|
instanceId String
|
||||||
parameters Json? @db.JsonB
|
parameters Json? @db.JsonB
|
||||||
|
|
||||||
OpenaiBot OpenaiBot? @relation(fields: [openaiBotId], references: [id], onDelete: Cascade)
|
botId String?
|
||||||
openaiBotId String?
|
|
||||||
|
|
||||||
DifyBot Dify? @relation(fields: [difyId], references: [id], onDelete: Cascade)
|
|
||||||
difyId String?
|
|
||||||
|
|
||||||
Typebot Typebot? @relation(fields: [typebotId], references: [id], onDelete: Cascade)
|
|
||||||
typebotId String?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model OpenaiSetting {
|
model OpenaiSetting {
|
||||||
@ -447,30 +438,29 @@ model Template {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Dify {
|
model Dify {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
enabled Boolean @default(true) @db.Boolean
|
enabled Boolean @default(true) @db.Boolean
|
||||||
description String? @db.VarChar(255)
|
description String? @db.VarChar(255)
|
||||||
botType DifyBotType
|
botType DifyBotType
|
||||||
apiUrl String? @db.VarChar(255)
|
apiUrl String? @db.VarChar(255)
|
||||||
apiKey String? @db.VarChar(255)
|
apiKey String? @db.VarChar(255)
|
||||||
expire Int? @default(0) @db.Integer
|
expire Int? @default(0) @db.Integer
|
||||||
keywordFinish String? @db.VarChar(100)
|
keywordFinish String? @db.VarChar(100)
|
||||||
delayMessage Int? @db.Integer
|
delayMessage Int? @db.Integer
|
||||||
unknownMessage String? @db.VarChar(100)
|
unknownMessage String? @db.VarChar(100)
|
||||||
listeningFromMe Boolean? @default(false) @db.Boolean
|
listeningFromMe Boolean? @default(false) @db.Boolean
|
||||||
stopBotFromMe Boolean? @default(false) @db.Boolean
|
stopBotFromMe Boolean? @default(false) @db.Boolean
|
||||||
keepOpen Boolean? @default(false) @db.Boolean
|
keepOpen Boolean? @default(false) @db.Boolean
|
||||||
debounceTime Int? @db.Integer
|
debounceTime Int? @db.Integer
|
||||||
ignoreJids Json?
|
ignoreJids Json?
|
||||||
triggerType TriggerType?
|
triggerType TriggerType?
|
||||||
triggerOperator TriggerOperator?
|
triggerOperator TriggerOperator?
|
||||||
triggerValue String?
|
triggerValue String?
|
||||||
createdAt DateTime? @default(now()) @db.Timestamp
|
createdAt DateTime? @default(now()) @db.Timestamp
|
||||||
updatedAt DateTime @updatedAt @db.Timestamp
|
updatedAt DateTime @updatedAt @db.Timestamp
|
||||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
instanceId String
|
instanceId String
|
||||||
DifySetting DifySetting[]
|
DifySetting DifySetting[]
|
||||||
sessions IntegrationSession[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model DifySetting {
|
model DifySetting {
|
||||||
|
12
src/api/dto/chatbot.dto.ts
Normal file
12
src/api/dto/chatbot.dto.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export class Session {
|
||||||
|
remoteJid?: string;
|
||||||
|
sessionId?: string;
|
||||||
|
status?: string;
|
||||||
|
createdAt?: number;
|
||||||
|
updateAt?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IgnoreJidDto {
|
||||||
|
remoteJid?: string;
|
||||||
|
action?: string;
|
||||||
|
}
|
@ -2,11 +2,16 @@ import { InstanceDto } from '@api/dto/instance.dto';
|
|||||||
import { PrismaRepository } from '@api/repository/repository.service';
|
import { PrismaRepository } from '@api/repository/repository.service';
|
||||||
import { difyController, openaiController, typebotController, websocketController } from '@api/server.module';
|
import { difyController, openaiController, typebotController, websocketController } from '@api/server.module';
|
||||||
import { WAMonitoringService } from '@api/services/monitor.service';
|
import { WAMonitoringService } from '@api/services/monitor.service';
|
||||||
|
import { Logger } from '@config/logger.config';
|
||||||
|
import { IntegrationSession } from '@prisma/client';
|
||||||
|
import { findBotByTrigger } from '@utils/findBotByTrigger';
|
||||||
|
|
||||||
export class ChatbotController {
|
export class ChatbotController {
|
||||||
public prismaRepository: PrismaRepository;
|
public prismaRepository: PrismaRepository;
|
||||||
public waMonitor: WAMonitoringService;
|
public waMonitor: WAMonitoringService;
|
||||||
|
|
||||||
|
public readonly logger = new Logger(ChatbotController.name);
|
||||||
|
|
||||||
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
|
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
|
||||||
this.prisma = prismaRepository;
|
this.prisma = prismaRepository;
|
||||||
this.monitor = waMonitor;
|
this.monitor = waMonitor;
|
||||||
@ -63,4 +68,112 @@ export class ChatbotController {
|
|||||||
events: data.websocketEvents,
|
events: data.websocketEvents,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public processDebounce(
|
||||||
|
userMessageDebounce: any,
|
||||||
|
content: string,
|
||||||
|
remoteJid: string,
|
||||||
|
debounceTime: number,
|
||||||
|
callback: any,
|
||||||
|
) {
|
||||||
|
if (userMessageDebounce[remoteJid]) {
|
||||||
|
userMessageDebounce[remoteJid].message += ` ${content}`;
|
||||||
|
this.logger.log('message debounced: ' + userMessageDebounce[remoteJid].message);
|
||||||
|
clearTimeout(userMessageDebounce[remoteJid].timeoutId);
|
||||||
|
} else {
|
||||||
|
userMessageDebounce[remoteJid] = {
|
||||||
|
message: content,
|
||||||
|
timeoutId: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
userMessageDebounce[remoteJid].timeoutId = setTimeout(() => {
|
||||||
|
const myQuestion = userMessageDebounce[remoteJid].message;
|
||||||
|
this.logger.log('Debounce complete. Processing message: ' + myQuestion);
|
||||||
|
|
||||||
|
delete userMessageDebounce[remoteJid];
|
||||||
|
callback(myQuestion);
|
||||||
|
}, debounceTime * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public checkIgnoreJids(ignoreJids: any, remoteJid: string) {
|
||||||
|
if (ignoreJids && ignoreJids.length > 0) {
|
||||||
|
let ignoreGroups = false;
|
||||||
|
let ignoreContacts = false;
|
||||||
|
|
||||||
|
if (ignoreJids.includes('@g.us')) {
|
||||||
|
ignoreGroups = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreJids.includes('@s.whatsapp.net')) {
|
||||||
|
ignoreContacts = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreGroups && remoteJid.endsWith('@g.us')) {
|
||||||
|
this.logger.warn('Ignoring message from group: ' + remoteJid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreContacts && remoteJid.endsWith('@s.whatsapp.net')) {
|
||||||
|
this.logger.warn('Ignoring message from contact: ' + remoteJid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreJids.includes(remoteJid)) {
|
||||||
|
this.logger.warn('Ignoring message from jid: ' + remoteJid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getSession(remoteJid: string, instance: InstanceDto) {
|
||||||
|
let session = await this.prismaRepository.integrationSession.findFirst({
|
||||||
|
where: {
|
||||||
|
remoteJid: remoteJid,
|
||||||
|
instanceId: instance.instanceId,
|
||||||
|
},
|
||||||
|
orderBy: { createdAt: 'desc' },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
if (session.status !== 'closed' && !session.botId) {
|
||||||
|
this.logger.warn('Session is already opened in another integration');
|
||||||
|
return;
|
||||||
|
} else if (!session.botId) {
|
||||||
|
session = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async findBotTrigger(
|
||||||
|
botRepository: any,
|
||||||
|
settingsRepository: any,
|
||||||
|
content: string,
|
||||||
|
instance: InstanceDto,
|
||||||
|
session?: IntegrationSession,
|
||||||
|
) {
|
||||||
|
let findBot = null;
|
||||||
|
|
||||||
|
if (!session) {
|
||||||
|
findBot = await findBotByTrigger(botRepository, settingsRepository, content, instance.instanceId);
|
||||||
|
|
||||||
|
if (!findBot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
findBot = await botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
id: session.botId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return findBot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +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;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class OpenaiCredsDto {
|
export class OpenaiCredsDto {
|
||||||
name: string;
|
name: string;
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
@ -53,8 +45,3 @@ export class OpenaiSettingDto {
|
|||||||
ignoreJids?: any;
|
ignoreJids?: any;
|
||||||
speechToText?: boolean;
|
speechToText?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OpenaiIgnoreJidDto {
|
|
||||||
remoteJid?: string;
|
|
||||||
action?: string;
|
|
||||||
}
|
|
||||||
|
@ -1,11 +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 {
|
import { OpenaiCredsDto, OpenaiDto, OpenaiSettingDto } from '@api/integrations/chatbot/openai/dto/openai.dto';
|
||||||
OpenaiCredsDto,
|
|
||||||
OpenaiDto,
|
|
||||||
OpenaiIgnoreJidDto,
|
|
||||||
OpenaiSettingDto,
|
|
||||||
} from '@api/integrations/chatbot/openai/dto/openai.dto';
|
|
||||||
import { HttpStatus } from '@api/routes/index.router';
|
import { HttpStatus } from '@api/routes/index.router';
|
||||||
import { openaiController } from '@api/server.module';
|
import { openaiController } from '@api/server.module';
|
||||||
import {
|
import {
|
||||||
@ -57,7 +53,7 @@ export class OpenaiRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: openaiSchema,
|
schema: openaiSchema,
|
||||||
ClassRef: OpenaiDto,
|
ClassRef: OpenaiDto,
|
||||||
execute: (instance, data) => openaiController.createOpenai(instance, data),
|
execute: (instance, data) => openaiController.createBot(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
@ -67,7 +63,7 @@ export class OpenaiRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => openaiController.findOpenai(instance),
|
execute: (instance) => openaiController.findBot(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -77,7 +73,7 @@ export class OpenaiRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => openaiController.fetchOpenai(instance, req.params.openaiBotId),
|
execute: (instance) => openaiController.fetchBot(instance, req.params.openaiBotId),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -87,7 +83,7 @@ export class OpenaiRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: openaiSchema,
|
schema: openaiSchema,
|
||||||
ClassRef: OpenaiDto,
|
ClassRef: OpenaiDto,
|
||||||
execute: (instance, data) => openaiController.updateOpenai(instance, req.params.openaiBotId, data),
|
execute: (instance, data) => openaiController.updateBot(instance, req.params.openaiBotId, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -97,7 +93,7 @@ export class OpenaiRouter extends RouterBroker {
|
|||||||
request: req,
|
request: req,
|
||||||
schema: instanceSchema,
|
schema: instanceSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => openaiController.deleteOpenai(instance, req.params.openaiBotId),
|
execute: (instance) => openaiController.deleteBot(instance, req.params.openaiBotId),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
@ -143,10 +139,10 @@ export class OpenaiRouter 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<OpenaiIgnoreJidDto>({
|
const response = await this.dataValidate<IgnoreJidDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: openaiIgnoreJidSchema,
|
schema: openaiIgnoreJidSchema,
|
||||||
ClassRef: OpenaiIgnoreJidDto,
|
ClassRef: IgnoreJidDto,
|
||||||
execute: (instance, data) => openaiController.ignoreJid(instance, data),
|
execute: (instance, data) => openaiController.ignoreJid(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
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 { wa } from '@api/types/wa.types';
|
import { wa } from '@api/types/wa.types';
|
||||||
import { configService, Log, Webhook, Websocket } from '@config/env.config';
|
import { configService, Log, Webhook } from '@config/env.config';
|
||||||
import { Logger } from '@config/logger.config';
|
import { Logger } from '@config/logger.config';
|
||||||
import { BadRequestException, NotFoundException } from '@exceptions';
|
import { BadRequestException, NotFoundException } from '@exceptions';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
@ -31,7 +31,7 @@ export class WebhookController extends EventController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.get(instanceName);
|
await this.get(instanceName);
|
||||||
|
|
||||||
return this.prisma.webhook.upsert({
|
return this.prisma.webhook.upsert({
|
||||||
where: {
|
where: {
|
||||||
instanceId: this.monitor.waInstances[instanceName].instanceId,
|
instanceId: this.monitor.waInstances[instanceName].instanceId,
|
||||||
@ -89,10 +89,6 @@ export class WebhookController extends EventController {
|
|||||||
apiKey?: string;
|
apiKey?: string;
|
||||||
local?: boolean;
|
local?: boolean;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
if (!configService.get<Websocket>('WEBSOCKET')?.ENABLED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const instanceWebhook = await this.get(instanceName);
|
const instanceWebhook = await this.get(instanceName);
|
||||||
const webhookGlobal = configService.get<Webhook>('WEBHOOK');
|
const webhookGlobal = configService.get<Webhook>('WEBHOOK');
|
||||||
const webhookLocal = instanceWebhook?.events;
|
const webhookLocal = instanceWebhook?.events;
|
||||||
@ -110,6 +106,7 @@ export class WebhookController extends EventController {
|
|||||||
server_url: serverUrl,
|
server_url: serverUrl,
|
||||||
apikey: apiKey,
|
apikey: apiKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) {
|
if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) {
|
||||||
let baseURL: string;
|
let baseURL: string;
|
||||||
|
149
src/utils/findBotByTrigger.ts
Normal file
149
src/utils/findBotByTrigger.ts
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import { advancedOperatorsSearch } from './advancedOperatorsSearch';
|
||||||
|
|
||||||
|
export const findBotByTrigger = async (
|
||||||
|
botRepository: any,
|
||||||
|
settingsRepository: any,
|
||||||
|
content: string,
|
||||||
|
instanceId: string,
|
||||||
|
) => {
|
||||||
|
// Check for triggerType 'all'
|
||||||
|
const findTriggerAll = await botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'all',
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (findTriggerAll) return findTriggerAll;
|
||||||
|
|
||||||
|
const findTriggerAdvanced = await botRepository.findMany({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'advanced',
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
for (const advanced of findTriggerAdvanced) {
|
||||||
|
if (advancedOperatorsSearch(content, advanced.triggerValue)) {
|
||||||
|
return advanced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for exact match
|
||||||
|
const findTriggerEquals = await botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'keyword',
|
||||||
|
triggerOperator: 'equals',
|
||||||
|
triggerValue: content,
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (findTriggerEquals) return findTriggerEquals;
|
||||||
|
|
||||||
|
// Check for regex match
|
||||||
|
const findRegex = await botRepository.findMany({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'keyword',
|
||||||
|
triggerOperator: 'regex',
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let findTriggerRegex = null;
|
||||||
|
|
||||||
|
for (const regex of findRegex) {
|
||||||
|
const regexValue = new RegExp(regex.triggerValue);
|
||||||
|
|
||||||
|
if (regexValue.test(content)) {
|
||||||
|
findTriggerRegex = regex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findTriggerRegex) return findTriggerRegex;
|
||||||
|
|
||||||
|
// Check for startsWith match
|
||||||
|
const findStartsWith = await botRepository.findMany({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'keyword',
|
||||||
|
triggerOperator: 'startsWith',
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let findTriggerStartsWith = null;
|
||||||
|
|
||||||
|
for (const startsWith of findStartsWith) {
|
||||||
|
if (content.startsWith(startsWith.triggerValue)) {
|
||||||
|
findTriggerStartsWith = startsWith;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findTriggerStartsWith) return findTriggerStartsWith;
|
||||||
|
|
||||||
|
// Check for endsWith match
|
||||||
|
const findEndsWith = await botRepository.findMany({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'keyword',
|
||||||
|
triggerOperator: 'endsWith',
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let findTriggerEndsWith = null;
|
||||||
|
|
||||||
|
for (const endsWith of findEndsWith) {
|
||||||
|
if (content.endsWith(endsWith.triggerValue)) {
|
||||||
|
findTriggerEndsWith = endsWith;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findTriggerEndsWith) return findTriggerEndsWith;
|
||||||
|
|
||||||
|
// Check for contains match
|
||||||
|
const findContains = await botRepository.findMany({
|
||||||
|
where: {
|
||||||
|
enabled: true,
|
||||||
|
triggerType: 'keyword',
|
||||||
|
triggerOperator: 'contains',
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let findTriggerContains = null;
|
||||||
|
|
||||||
|
for (const contains of findContains) {
|
||||||
|
if (content.includes(contains.triggerValue)) {
|
||||||
|
findTriggerContains = contains;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findTriggerContains) return findTriggerContains;
|
||||||
|
|
||||||
|
const fallback = await settingsRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
instanceId: instanceId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (fallback?.openaiIdFallback) {
|
||||||
|
const findFallback = await botRepository.findFirst({
|
||||||
|
where: {
|
||||||
|
id: fallback.openaiIdFallback,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (findFallback) return findFallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
65
src/utils/getConversationMessage.ts
Normal file
65
src/utils/getConversationMessage.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { configService, S3 } from '@config/env.config';
|
||||||
|
|
||||||
|
const getTypeMessage = (msg: any) => {
|
||||||
|
let mediaId: string;
|
||||||
|
|
||||||
|
if (configService.get<S3>('S3').ENABLE) mediaId = msg.message.mediaUrl;
|
||||||
|
else mediaId = msg.key.id;
|
||||||
|
|
||||||
|
const types = {
|
||||||
|
conversation: msg?.message?.conversation,
|
||||||
|
extendedTextMessage: msg?.message?.extendedTextMessage?.text,
|
||||||
|
contactMessage: msg?.message?.contactMessage?.displayName,
|
||||||
|
locationMessage: msg?.message?.locationMessage?.degreesLatitude,
|
||||||
|
viewOnceMessageV2:
|
||||||
|
msg?.message?.viewOnceMessageV2?.message?.imageMessage?.url ||
|
||||||
|
msg?.message?.viewOnceMessageV2?.message?.videoMessage?.url ||
|
||||||
|
msg?.message?.viewOnceMessageV2?.message?.audioMessage?.url,
|
||||||
|
listResponseMessage: msg?.message?.listResponseMessage?.singleSelectReply?.selectedRowId,
|
||||||
|
responseRowId: msg?.message?.listResponseMessage?.singleSelectReply?.selectedRowId,
|
||||||
|
// Medias
|
||||||
|
audioMessage: msg?.message?.speechToText
|
||||||
|
? msg?.message?.speechToText
|
||||||
|
: msg?.message?.audioMessage
|
||||||
|
? `audioMessage|${mediaId}`
|
||||||
|
: undefined,
|
||||||
|
imageMessage: msg?.message?.imageMessage
|
||||||
|
? `imageMessage|${mediaId}${msg?.message?.imageMessage?.caption ? `|${msg?.message?.imageMessage?.caption}` : ''}`
|
||||||
|
: undefined,
|
||||||
|
videoMessage: msg?.message?.videoMessage
|
||||||
|
? `videoMessage|${mediaId}${msg?.message?.videoMessage?.caption ? `|${msg?.message?.videoMessage?.caption}` : ''}`
|
||||||
|
: undefined,
|
||||||
|
documentMessage: msg?.message?.documentMessage
|
||||||
|
? `documentMessage|${mediaId}${
|
||||||
|
msg?.message?.documentMessage?.caption ? `|${msg?.message?.documentMessage?.caption}` : ''
|
||||||
|
}`
|
||||||
|
: undefined,
|
||||||
|
documentWithCaptionMessage: msg?.message?.documentWithCaptionMessage?.message?.documentMessage
|
||||||
|
? `documentWithCaptionMessage|${mediaId}${
|
||||||
|
msg?.message?.documentWithCaptionMessage?.message?.documentMessage?.caption
|
||||||
|
? `|${msg?.message?.documentWithCaptionMessage?.message?.documentMessage?.caption}`
|
||||||
|
: ''
|
||||||
|
}`
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
const messageType = Object.keys(types).find((key) => types[key] !== undefined) || 'unknown';
|
||||||
|
|
||||||
|
return { ...types, messageType };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMessageContent = (types: any) => {
|
||||||
|
const typeKey = Object.keys(types).find((key) => types[key] !== undefined);
|
||||||
|
|
||||||
|
const result = typeKey ? types[typeKey] : undefined;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getConversationMessage = (msg: any) => {
|
||||||
|
const types = getTypeMessage(msg);
|
||||||
|
|
||||||
|
const messageContent = getMessageContent(types);
|
||||||
|
|
||||||
|
return messageContent;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user