mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-13 15:14:49 -06:00
feat: Now you can register several typebots with triggers
This commit is contained in:
parent
56df0caab0
commit
fe9803b828
@ -32,7 +32,7 @@ CLEAN_STORE_CHATS=true
|
||||
DATABASE_ENABLED=false
|
||||
DATABASE_PROVIDER=mongodb # postgresql, mysql, mongodb
|
||||
DATABASE_CONNECTION_URI='mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true'
|
||||
DATABASE_CONNECTION_DB_PREFIX_NAME=evolution
|
||||
DATABASE_CONNECTION_CLIENT_NAME=evolution
|
||||
DATABASE_SAVE_DATA_INSTANCE=true
|
||||
DATABASE_SAVE_DATA_NEW_MESSAGE=true
|
||||
DATABASE_SAVE_MESSAGE_UPDATE=true
|
||||
|
@ -34,7 +34,7 @@ CLEAN_STORE_CHATS=true
|
||||
# Permanent data storage
|
||||
DATABASE_ENABLED=false
|
||||
DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true
|
||||
DATABASE_CONNECTION_DB_PREFIX_NAME=evdocker
|
||||
DATABASE_CONNECTION_CLIENT_NAME=evdocker
|
||||
|
||||
# Choose the data you want to save in the application's database or store
|
||||
DATABASE_SAVE_DATA_INSTANCE=false
|
||||
|
@ -37,7 +37,7 @@ DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin &
|
||||
readPreference=primary &
|
||||
ssl=false &
|
||||
directConnection=true
|
||||
DATABASE_CONNECTION_DB_PREFIX_NAME=evolution
|
||||
DATABASE_CONNECTION_CLIENT_NAME=evolution
|
||||
|
||||
# Choose the data you want to save in the application's database or store
|
||||
DATABASE_SAVE_DATA_INSTANCE=false
|
||||
|
@ -50,7 +50,7 @@ ENV CLEAN_STORE_CHATS=true
|
||||
|
||||
ENV DATABASE_ENABLED=false
|
||||
ENV DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true
|
||||
ENV DATABASE_CONNECTION_DB_PREFIX_NAME=evolution
|
||||
ENV DATABASE_CONNECTION_CLIENT_NAME=evolution
|
||||
|
||||
ENV DATABASE_SAVE_DATA_INSTANCE=false
|
||||
ENV DATABASE_SAVE_DATA_NEW_MESSAGE=false
|
||||
|
@ -33,6 +33,18 @@ enum TypebotSessionStatus {
|
||||
paused
|
||||
}
|
||||
|
||||
enum TriggerType {
|
||||
all
|
||||
keyword
|
||||
}
|
||||
|
||||
enum TriggerOperator {
|
||||
contains
|
||||
equals
|
||||
startsWith
|
||||
endsWith
|
||||
}
|
||||
|
||||
model Instance {
|
||||
id String @id @default(cuid())
|
||||
name String @unique @db.VarChar(255)
|
||||
@ -42,6 +54,7 @@ model Instance {
|
||||
integration String? @db.VarChar(100)
|
||||
number String? @db.VarChar(100)
|
||||
token String? @unique @db.VarChar(255)
|
||||
clientName String? @db.VarChar(100)
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
updatedAt DateTime? @updatedAt @db.Timestamp
|
||||
Chat Chat[]
|
||||
@ -55,14 +68,15 @@ model Instance {
|
||||
Rabbitmq Rabbitmq?
|
||||
Sqs Sqs?
|
||||
Websocket Websocket?
|
||||
Typebot Typebot?
|
||||
Typebot Typebot[]
|
||||
Session Session?
|
||||
MessageUpdate MessageUpdate[]
|
||||
TypebotSession TypebotSession[]
|
||||
TypebotSetting TypebotSetting?
|
||||
}
|
||||
|
||||
model Session {
|
||||
id Int @id @unique @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
sessionId String @unique
|
||||
creds String? @db.Text
|
||||
createdAt DateTime @default(now()) @db.Timestamp
|
||||
@ -70,7 +84,7 @@ model Session {
|
||||
}
|
||||
|
||||
model Chat {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
remoteJid String @db.VarChar(100)
|
||||
labels Json? @db.JsonB
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
@ -80,7 +94,7 @@ model Chat {
|
||||
}
|
||||
|
||||
model Contact {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
remoteJid String @db.VarChar(100)
|
||||
pushName String? @db.VarChar(100)
|
||||
profilePicUrl String? @db.VarChar(500)
|
||||
@ -91,7 +105,7 @@ model Contact {
|
||||
}
|
||||
|
||||
model Message {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
key Json @db.JsonB
|
||||
pushName String? @db.VarChar(100)
|
||||
participant String? @db.VarChar(100)
|
||||
@ -107,13 +121,13 @@ model Message {
|
||||
chatwootIsRead Boolean? @db.Boolean
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String
|
||||
typebotSessionId Int?
|
||||
typebotSessionId String?
|
||||
MessageUpdate MessageUpdate[]
|
||||
TypebotSession TypebotSession? @relation(fields: [typebotSessionId], references: [id])
|
||||
}
|
||||
|
||||
model MessageUpdate {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
keyId String @db.VarChar(100)
|
||||
remoteJid String @db.VarChar(100)
|
||||
fromMe Boolean @db.Boolean
|
||||
@ -121,13 +135,13 @@ model MessageUpdate {
|
||||
pollUpdates Json? @db.JsonB
|
||||
status String @db.VarChar(30)
|
||||
Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
|
||||
messageId Int
|
||||
messageId String
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String
|
||||
}
|
||||
|
||||
model Webhook {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
url String @db.VarChar(500)
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
events Json? @db.JsonB
|
||||
@ -140,7 +154,7 @@ model Webhook {
|
||||
}
|
||||
|
||||
model Chatwoot {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
accountId String? @db.VarChar(100)
|
||||
token String? @db.VarChar(100)
|
||||
@ -162,7 +176,7 @@ model Chatwoot {
|
||||
}
|
||||
|
||||
model Label {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
labelId String? @unique @db.VarChar(100)
|
||||
name String @db.VarChar(100)
|
||||
color String @db.VarChar(100)
|
||||
@ -174,7 +188,7 @@ model Label {
|
||||
}
|
||||
|
||||
model Proxy {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean @default(false) @db.Boolean
|
||||
host String @db.VarChar(100)
|
||||
port String @db.VarChar(100)
|
||||
@ -188,7 +202,7 @@ model Proxy {
|
||||
}
|
||||
|
||||
model Setting {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
rejectCall Boolean @default(false) @db.Boolean
|
||||
msgCall String? @db.VarChar(100)
|
||||
groupsIgnore Boolean @default(false) @db.Boolean
|
||||
@ -203,7 +217,7 @@ model Setting {
|
||||
}
|
||||
|
||||
model Rabbitmq {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean @default(false) @db.Boolean
|
||||
events Json @db.JsonB
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
@ -213,7 +227,7 @@ model Rabbitmq {
|
||||
}
|
||||
|
||||
model Sqs {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean @default(false) @db.Boolean
|
||||
events Json @db.JsonB
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
@ -223,7 +237,7 @@ model Sqs {
|
||||
}
|
||||
|
||||
model Websocket {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean @default(false) @db.Boolean
|
||||
events Json @db.JsonB
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
@ -233,24 +247,29 @@ model Websocket {
|
||||
}
|
||||
|
||||
model Typebot {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
enabled Boolean @default(true) @db.Boolean
|
||||
url String @db.VarChar(500)
|
||||
typebot String @db.VarChar(100)
|
||||
expire Int @default(0) @db.Integer
|
||||
expire Int? @default(0) @db.Integer
|
||||
keywordFinish String? @db.VarChar(100)
|
||||
delayMessage Int? @db.Integer
|
||||
unknownMessage String? @db.VarChar(100)
|
||||
listeningFromMe Boolean @default(false) @db.Boolean
|
||||
listeningFromMe Boolean? @default(false) @db.Boolean
|
||||
stopBotFromMe Boolean? @default(false) @db.Boolean
|
||||
keepOpen Boolean? @default(false) @db.Boolean
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
updatedAt DateTime? @updatedAt @db.Timestamp
|
||||
triggerType TriggerType?
|
||||
triggerOperator TriggerOperator?
|
||||
triggerValue String?
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String @unique
|
||||
instanceId String
|
||||
sessions TypebotSession[]
|
||||
}
|
||||
|
||||
model TypebotSession {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
remoteJid String @db.VarChar(100)
|
||||
pushName String? @db.VarChar(100)
|
||||
sessionId String @db.VarChar(100)
|
||||
@ -260,8 +279,23 @@ model TypebotSession {
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
updatedAt DateTime @updatedAt @db.Timestamp
|
||||
Typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
|
||||
typebotId Int
|
||||
typebotId String
|
||||
Message Message[]
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String
|
||||
}
|
||||
|
||||
model TypebotSetting {
|
||||
id String @id @default(cuid())
|
||||
expire Int? @default(0) @db.Integer
|
||||
keywordFinish String? @db.VarChar(100)
|
||||
delayMessage Int? @db.Integer
|
||||
unknownMessage String? @db.VarChar(100)
|
||||
listeningFromMe Boolean? @default(false) @db.Boolean
|
||||
stopBotFromMe Boolean? @default(false) @db.Boolean
|
||||
keepOpen Boolean? @default(false) @db.Boolean
|
||||
createdAt DateTime? @default(now()) @db.Timestamp
|
||||
updatedAt DateTime @updatedAt @db.Timestamp
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String @unique
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { existsSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { CacheConf, configService, Database } from '../../config/env.config';
|
||||
import { INSTANCE_DIR } from '../../config/path.config';
|
||||
import {
|
||||
BadRequestException,
|
||||
ForbiddenException,
|
||||
@ -33,7 +30,7 @@ async function getInstance(instanceName: string) {
|
||||
return exists || (await prisma.instance.findMany({ where: { name: instanceName } })).length > 0;
|
||||
}
|
||||
|
||||
return exists || existsSync(join(INSTANCE_DIR, instanceName));
|
||||
return false;
|
||||
} catch (error) {
|
||||
throw new InternalServerErrorException(error?.toString());
|
||||
}
|
||||
@ -65,6 +62,7 @@ export async function instanceLoggedGuard(req: Request, _: Response, next: NextF
|
||||
|
||||
if (waMonitor.waInstances[instance.instanceName]) {
|
||||
waMonitor.waInstances[instance.instanceName]?.removeRabbitmqQueues();
|
||||
waMonitor.waInstances[instance.instanceName]?.removeSqsQueues();
|
||||
delete waMonitor.waInstances[instance.instanceName];
|
||||
}
|
||||
}
|
||||
|
@ -2198,14 +2198,14 @@ export class ChatwootService {
|
||||
where: {
|
||||
instanceId: instance.instanceId,
|
||||
id: {
|
||||
in: recentContacts.map((contact) => Number(contact.identifier)),
|
||||
in: recentContacts.map((contact) => contact.identifier),
|
||||
},
|
||||
profilePicUrl: {
|
||||
not: null,
|
||||
},
|
||||
},
|
||||
})
|
||||
).reduce((acc: Map<number, ContactModel>, contact: ContactModel) => acc.set(contact.id, contact), new Map());
|
||||
).reduce((acc: Map<string, ContactModel>, contact: ContactModel) => acc.set(contact.id, contact), new Map());
|
||||
|
||||
recentContacts.forEach(async (contact) => {
|
||||
if (contactsWithProfilePicture.has(contact.identifier)) {
|
||||
|
@ -10,19 +10,6 @@ export class TypebotController {
|
||||
public async createTypebot(instance: InstanceDto, data: TypebotDto) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
if (!data.enabled) {
|
||||
data.url = '';
|
||||
data.typebot = '';
|
||||
data.expire = 0;
|
||||
data.sessions = [];
|
||||
} else {
|
||||
const saveData = await this.typebotService.find(instance);
|
||||
|
||||
if (saveData?.typebot?.enabled) {
|
||||
data.sessions = saveData?.sessions;
|
||||
}
|
||||
}
|
||||
|
||||
return this.typebotService.create(instance, data);
|
||||
}
|
||||
|
||||
@ -32,10 +19,22 @@ export class TypebotController {
|
||||
return this.typebotService.find(instance);
|
||||
}
|
||||
|
||||
public async changeStatus(instance: InstanceDto, data: any) {
|
||||
public async fetchTypebot(instance: InstanceDto, typebotId: string) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
return this.typebotService.changeStatus(instance, data);
|
||||
return this.typebotService.fetch(instance, typebotId);
|
||||
}
|
||||
|
||||
public async updateTypebot(instance: InstanceDto, typebotId: string, data: TypebotDto) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
return this.typebotService.update(instance, typebotId, data);
|
||||
}
|
||||
|
||||
public async deleteTypebot(instance: InstanceDto, typebotId: string) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
return this.typebotService.delete(instance, typebotId);
|
||||
}
|
||||
|
||||
public async startTypebot(instance: InstanceDto, data: any) {
|
||||
@ -43,4 +42,28 @@ export class TypebotController {
|
||||
|
||||
return this.typebotService.startTypebot(instance, data);
|
||||
}
|
||||
|
||||
public async settings(instance: InstanceDto, data: any) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
return this.typebotService.setDefaultSettings(instance, data);
|
||||
}
|
||||
|
||||
public async fetchSettings(instance: InstanceDto) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
return this.typebotService.fetchDefaultSettings(instance);
|
||||
}
|
||||
|
||||
public async changeStatus(instance: InstanceDto, data: any) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
return this.typebotService.changeStatus(instance, data);
|
||||
}
|
||||
|
||||
public async fetchSessions(instance: InstanceDto, typebotId: string) {
|
||||
if (!configService.get<Typebot>('TYPEBOT').ENABLED) throw new BadRequestException('Typebot is disabled');
|
||||
|
||||
return this.typebotService.fetchSessions(instance, typebotId);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { TypebotSession } from '@prisma/client';
|
||||
import { TriggerOperator, TriggerType } from '@prisma/client';
|
||||
|
||||
export class Session {
|
||||
remoteJid?: string;
|
||||
@ -25,5 +25,19 @@ export class TypebotDto {
|
||||
delayMessage?: number;
|
||||
unknownMessage?: string;
|
||||
listeningFromMe?: boolean;
|
||||
sessions?: TypebotSession[];
|
||||
stopBotFromMe?: boolean;
|
||||
keepOpen?: boolean;
|
||||
triggerType?: TriggerType;
|
||||
triggerOperator?: TriggerOperator;
|
||||
triggerValue?: string;
|
||||
}
|
||||
|
||||
export class TypebotSettingDto {
|
||||
expire?: number;
|
||||
keywordFinish?: string;
|
||||
delayMessage?: number;
|
||||
unknownMessage?: string;
|
||||
listeningFromMe?: boolean;
|
||||
stopBotFromMe?: boolean;
|
||||
keepOpen?: boolean;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { RequestHandler, Router } from 'express';
|
||||
import {
|
||||
instanceSchema,
|
||||
typebotSchema,
|
||||
typebotSettingSchema,
|
||||
typebotStartSchema,
|
||||
typebotStatusSchema,
|
||||
} from '../../../../validate/validate.schema';
|
||||
@ -10,13 +11,13 @@ import { RouterBroker } from '../../../abstract/abstract.router';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { HttpStatus } from '../../../routes/index.router';
|
||||
import { typebotController } from '../../../server.module';
|
||||
import { TypebotDto } from '../dto/typebot.dto';
|
||||
import { TypebotDto, TypebotSettingDto } from '../dto/typebot.dto';
|
||||
|
||||
export class TypebotRouter extends RouterBroker {
|
||||
constructor(...guards: RequestHandler[]) {
|
||||
super();
|
||||
this.router
|
||||
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
||||
.post(this.routerPath('create'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<TypebotDto>({
|
||||
request: req,
|
||||
schema: typebotSchema,
|
||||
@ -36,12 +37,52 @@ export class TypebotRouter extends RouterBroker {
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.post(this.routerPath('changeStatus'), ...guards, async (req, res) => {
|
||||
.get(this.routerPath('fetch/:typebotId'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<InstanceDto>({
|
||||
request: req,
|
||||
schema: typebotStatusSchema,
|
||||
schema: instanceSchema,
|
||||
ClassRef: InstanceDto,
|
||||
execute: (instance, data) => typebotController.changeStatus(instance, data),
|
||||
execute: (instance) => typebotController.fetchTypebot(instance, req.params.typebotId),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.put(this.routerPath('update/:typebotId'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<TypebotDto>({
|
||||
request: req,
|
||||
schema: typebotSchema,
|
||||
ClassRef: TypebotDto,
|
||||
execute: (instance, data) => typebotController.updateTypebot(instance, req.params.typebotId, data),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.delete(this.routerPath('delete/:typebotId'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<InstanceDto>({
|
||||
request: req,
|
||||
schema: instanceSchema,
|
||||
ClassRef: InstanceDto,
|
||||
execute: (instance) => typebotController.deleteTypebot(instance, req.params.typebotId),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.post(this.routerPath('settings'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<TypebotSettingDto>({
|
||||
request: req,
|
||||
schema: typebotSettingSchema,
|
||||
ClassRef: TypebotSettingDto,
|
||||
execute: (instance, data) => typebotController.settings(instance, data),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<InstanceDto>({
|
||||
request: req,
|
||||
schema: instanceSchema,
|
||||
ClassRef: InstanceDto,
|
||||
execute: (instance) => typebotController.fetchSettings(instance),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
@ -54,6 +95,26 @@ export class TypebotRouter extends RouterBroker {
|
||||
execute: (instance, data) => typebotController.startTypebot(instance, data),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.post(this.routerPath('changeStatus'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<InstanceDto>({
|
||||
request: req,
|
||||
schema: typebotStatusSchema,
|
||||
ClassRef: InstanceDto,
|
||||
execute: (instance, data) => typebotController.changeStatus(instance, data),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.get(this.routerPath('fetchSessions/:typebotId'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<InstanceDto>({
|
||||
request: req,
|
||||
schema: instanceSchema,
|
||||
ClassRef: InstanceDto,
|
||||
execute: (instance) => typebotController.fetchSessions(instance, req.params.typebotId),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
});
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,13 +27,18 @@ export const typebotSchema: JSONSchema7 = {
|
||||
enabled: { type: 'boolean' },
|
||||
url: { type: 'string' },
|
||||
typebot: { type: 'string' },
|
||||
triggerType: { type: 'string', enum: ['all', 'keyword'] },
|
||||
triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith'] },
|
||||
triggerValue: { type: 'string' },
|
||||
expire: { type: 'integer' },
|
||||
keywordFinish: { type: 'string' },
|
||||
delayMessage: { type: 'integer' },
|
||||
unknownMessage: { type: 'string' },
|
||||
listeningFromMe: { type: 'boolean' },
|
||||
stopBotFromMe: { type: 'boolean' },
|
||||
},
|
||||
required: ['enabled', 'url', 'typebot', 'expire', 'delayMessage', 'unknownMessage', 'listeningFromMe'],
|
||||
...isNotEmpty('enabled', 'url', 'typebot', 'expire', 'delayMessage', 'unknownMessage', 'listeningFromMe'),
|
||||
required: ['enabled', 'url', 'typebot', 'triggerType'],
|
||||
...isNotEmpty('enabled', 'url', 'typebot', 'triggerType'),
|
||||
};
|
||||
|
||||
export const typebotStatusSchema: JSONSchema7 = {
|
||||
@ -58,3 +63,19 @@ export const typebotStartSchema: JSONSchema7 = {
|
||||
required: ['remoteJid', 'url', 'typebot'],
|
||||
...isNotEmpty('remoteJid', 'url', 'typebot'),
|
||||
};
|
||||
|
||||
export const typebotSettingSchema: JSONSchema7 = {
|
||||
$id: v4(),
|
||||
type: 'object',
|
||||
properties: {
|
||||
expire: { type: 'integer' },
|
||||
keywordFinish: { type: 'string' },
|
||||
delayMessage: { type: 'integer' },
|
||||
unknownMessage: { type: 'string' },
|
||||
listeningFromMe: { type: 'boolean' },
|
||||
stopBotFromMe: { type: 'boolean' },
|
||||
keepOpen: { type: 'boolean' },
|
||||
},
|
||||
required: ['expire', 'keywordFinish', 'delayMessage', 'unknownMessage', 'listeningFromMe', 'stopBotFromMe'],
|
||||
...isNotEmpty('expire', 'keywordFinish', 'delayMessage', 'unknownMessage', 'listeningFromMe', 'stopBotFromMe'),
|
||||
};
|
||||
|
@ -54,7 +54,7 @@ export const waMonitor = new WAMonitoringService(
|
||||
|
||||
const authService = new AuthService(prismaRepository);
|
||||
|
||||
const typebotService = new TypebotService(waMonitor, configService, prismaRepository, eventEmitter);
|
||||
const typebotService = new TypebotService(waMonitor, configService, prismaRepository);
|
||||
export const typebotController = new TypebotController(typebotService);
|
||||
|
||||
const webhookService = new WebhookService(waMonitor);
|
||||
|
@ -16,7 +16,6 @@ import {
|
||||
Log,
|
||||
Rabbitmq,
|
||||
Sqs,
|
||||
Typebot,
|
||||
Webhook,
|
||||
Websocket,
|
||||
} from '../../config/env.config';
|
||||
@ -33,7 +32,6 @@ import { RabbitmqDto } from '../integrations/rabbitmq/dto/rabbitmq.dto';
|
||||
import { getAMQP, removeQueues } from '../integrations/rabbitmq/libs/amqp.server';
|
||||
import { SqsDto } from '../integrations/sqs/dto/sqs.dto';
|
||||
import { getSQS, removeQueues as removeQueuesSQS } from '../integrations/sqs/libs/sqs.server';
|
||||
import { TypebotDto } from '../integrations/typebot/dto/typebot.dto';
|
||||
import { TypebotService } from '../integrations/typebot/services/typebot.service';
|
||||
import { WebsocketDto } from '../integrations/websocket/dto/websocket.dto';
|
||||
import { getIO } from '../integrations/websocket/libs/socket.server';
|
||||
@ -59,7 +57,6 @@ export class ChannelStartupService {
|
||||
public readonly localWebsocket: wa.LocalWebsocket = {};
|
||||
public readonly localRabbitmq: wa.LocalRabbitmq = {};
|
||||
public readonly localSqs: wa.LocalSqs = {};
|
||||
public readonly localTypebot: wa.LocalTypebot = {};
|
||||
public readonly localProxy: wa.LocalProxy = {};
|
||||
public readonly localSettings: wa.LocalSettings = {};
|
||||
public readonly storePath = join(ROOT_DIR, 'store');
|
||||
@ -71,7 +68,7 @@ export class ChannelStartupService {
|
||||
this.chatwootCache,
|
||||
);
|
||||
|
||||
public typebotService = new TypebotService(waMonitor, this.configService, this.prismaRepository, this.eventEmitter);
|
||||
public typebotService = new TypebotService(waMonitor, this.configService, this.prismaRepository);
|
||||
|
||||
public setInstance(instance: InstanceDto) {
|
||||
this.instance.name = instance.instanceName;
|
||||
@ -478,78 +475,6 @@ export class ChannelStartupService {
|
||||
}
|
||||
}
|
||||
|
||||
public async loadTypebot() {
|
||||
if (!this.configService.get<Typebot>('TYPEBOT').ENABLED) {
|
||||
return;
|
||||
}
|
||||
const data = await this.prismaRepository.typebot.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
include: {
|
||||
sessions: true,
|
||||
},
|
||||
});
|
||||
|
||||
this.localTypebot.enabled = data?.enabled;
|
||||
this.localTypebot.url = data?.url;
|
||||
this.localTypebot.typebot = data?.typebot;
|
||||
this.localTypebot.expire = data?.expire;
|
||||
this.localTypebot.keywordFinish = data?.keywordFinish;
|
||||
this.localTypebot.delayMessage = data?.delayMessage;
|
||||
this.localTypebot.unknownMessage = data?.unknownMessage;
|
||||
this.localTypebot.listeningFromMe = data?.listeningFromMe;
|
||||
this.localTypebot.sessions = data?.sessions;
|
||||
}
|
||||
|
||||
public async setTypebot(data: TypebotDto) {
|
||||
if (!this.configService.get<Typebot>('TYPEBOT').ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
const typebot = await this.prismaRepository.typebot.create({
|
||||
data: {
|
||||
enabled: data.enabled,
|
||||
url: data.url,
|
||||
typebot: data.typebot,
|
||||
expire: data.expire,
|
||||
keywordFinish: data.keywordFinish,
|
||||
delayMessage: data.delayMessage,
|
||||
unknownMessage: data.unknownMessage,
|
||||
listeningFromMe: data.listeningFromMe,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
await this.prismaRepository.typebotSession.deleteMany({
|
||||
where: {
|
||||
typebotId: typebot.id,
|
||||
},
|
||||
});
|
||||
|
||||
Object.assign(this.localTypebot, data);
|
||||
}
|
||||
|
||||
public async findTypebot() {
|
||||
if (!this.configService.get<Typebot>('TYPEBOT').ENABLED) {
|
||||
return;
|
||||
}
|
||||
const data = await this.prismaRepository.typebot.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
include: {
|
||||
sessions: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
throw new NotFoundException('Typebot not found');
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async loadProxy() {
|
||||
const data = await this.prismaRepository.proxy.findUnique({
|
||||
where: {
|
||||
|
@ -502,7 +502,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
this.loadWebsocket();
|
||||
this.loadRabbitmq();
|
||||
this.loadSqs();
|
||||
this.loadTypebot();
|
||||
this.loadProxy();
|
||||
|
||||
this.instance.authState = await this.defineAuthState();
|
||||
@ -1182,19 +1181,13 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
}
|
||||
|
||||
if (this.configService.get<Typebot>('TYPEBOT').ENABLED) {
|
||||
const typebotSessionRemoteJid = this.localTypebot.sessions?.find(
|
||||
(session) => session.remoteJid === received.key.remoteJid,
|
||||
);
|
||||
|
||||
if ((this.localTypebot.enabled && type === 'notify') || typebotSessionRemoteJid) {
|
||||
if (!(this.localTypebot.listeningFromMe === false && messageRaw.key.fromMe === true)) {
|
||||
if (messageRaw.messageType !== 'reactionMessage')
|
||||
await this.typebotService.sendTypebot(
|
||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
||||
messageRaw.key.remoteJid,
|
||||
messageRaw,
|
||||
);
|
||||
}
|
||||
if (type === 'notify') {
|
||||
if (messageRaw.messageType !== 'reactionMessage')
|
||||
await this.typebotService.sendTypebot(
|
||||
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
||||
messageRaw.key.remoteJid,
|
||||
messageRaw,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,6 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
this.loadWebsocket();
|
||||
this.loadRabbitmq();
|
||||
this.loadSqs();
|
||||
this.loadTypebot();
|
||||
|
||||
this.eventHandler(content);
|
||||
|
||||
@ -399,20 +398,12 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
}
|
||||
|
||||
if (this.configService.get<Typebot>('TYPEBOT').ENABLED) {
|
||||
const typebotSessionRemoteJid = this.localTypebot.sessions?.find(
|
||||
(session) => session.remoteJid === key.remoteJid,
|
||||
);
|
||||
|
||||
if (this.localTypebot.enabled || typebotSessionRemoteJid) {
|
||||
if (!(this.localTypebot.listeningFromMe === false && key.fromMe === true)) {
|
||||
if (messageRaw.messageType !== 'reactionMessage')
|
||||
await this.typebotService.sendTypebot(
|
||||
{ instanceName: this.instance.name },
|
||||
messageRaw.key.remoteJid,
|
||||
messageRaw,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (messageRaw.messageType !== 'reactionMessage')
|
||||
await this.typebotService.sendTypebot(
|
||||
{ instanceName: this.instance.name },
|
||||
messageRaw.key.remoteJid,
|
||||
messageRaw,
|
||||
);
|
||||
}
|
||||
|
||||
await this.prismaRepository.message.create({
|
||||
|
@ -262,6 +262,7 @@ export class WAMonitoringService {
|
||||
public async saveInstance(data: any) {
|
||||
try {
|
||||
if (this.db.ENABLED) {
|
||||
const clientName = await this.configService.get<Database>('DATABASE').CONNECTION.CLIENT_NAME;
|
||||
await this.prismaRepository.instance.create({
|
||||
data: {
|
||||
id: data.instanceId,
|
||||
@ -270,6 +271,7 @@ export class WAMonitoringService {
|
||||
number: data.number,
|
||||
integration: data.integration || Integration.WHATSAPP_BAILEYS,
|
||||
token: data.hash,
|
||||
clientName: clientName,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-namespace */
|
||||
import { TypebotSession } from '@prisma/client';
|
||||
import { JsonValue } from '@prisma/client/runtime/library';
|
||||
import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys';
|
||||
|
||||
@ -113,18 +112,6 @@ export declare namespace wa {
|
||||
createdAt?: number;
|
||||
};
|
||||
|
||||
export type LocalTypebot = {
|
||||
enabled?: boolean;
|
||||
url?: string;
|
||||
typebot?: string;
|
||||
expire?: number;
|
||||
keywordFinish?: string;
|
||||
delayMessage?: number;
|
||||
unknownMessage?: string;
|
||||
listeningFromMe?: boolean;
|
||||
sessions?: TypebotSession[];
|
||||
};
|
||||
|
||||
export type LocalProxy = {
|
||||
enabled?: boolean;
|
||||
host?: string;
|
||||
|
@ -62,7 +62,7 @@ export type CleanStoreConf = {
|
||||
|
||||
export type DBConnection = {
|
||||
URI: string;
|
||||
DB_PREFIX_NAME: string;
|
||||
CLIENT_NAME: string;
|
||||
};
|
||||
export type Database = {
|
||||
CONNECTION: DBConnection;
|
||||
@ -190,7 +190,7 @@ export type SslConf = { PRIVKEY: string; FULLCHAIN: string };
|
||||
export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook };
|
||||
export type ConfigSessionPhone = { CLIENT: string; NAME: string; VERSION: string };
|
||||
export type QrCode = { LIMIT: number; COLOR: string };
|
||||
export type Typebot = { ENABLED: boolean; API_VERSION: string; KEEP_OPEN: boolean };
|
||||
export type Typebot = { ENABLED: boolean; API_VERSION: string };
|
||||
export type Chatwoot = {
|
||||
ENABLED: boolean;
|
||||
MESSAGE_DELETE: boolean;
|
||||
@ -299,7 +299,7 @@ export class ConfigService {
|
||||
DATABASE: {
|
||||
CONNECTION: {
|
||||
URI: process.env.DATABASE_CONNECTION_URI || '',
|
||||
DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME || 'evolution',
|
||||
CLIENT_NAME: process.env.DATABASE_CONNECTION_CLIENT_NAME || 'evolution',
|
||||
},
|
||||
ENABLED: process.env?.DATABASE_ENABLED === 'true',
|
||||
PROVIDER: process.env.DATABASE_PROVIDER || 'postgresql',
|
||||
@ -433,7 +433,6 @@ export class ConfigService {
|
||||
TYPEBOT: {
|
||||
ENABLED: process.env?.TYPEBOT_ENABLED === 'true',
|
||||
API_VERSION: process.env?.TYPEBOT_API_VERSION || 'old',
|
||||
KEEP_OPEN: process.env.TYPEBOT_KEEP_OPEN === 'true',
|
||||
},
|
||||
CHATWOOT: {
|
||||
ENABLED: process.env?.CHATWOOT_ENABLED === 'true',
|
||||
|
Loading…
Reference in New Issue
Block a user