feat: Now you can register several typebots with triggers

This commit is contained in:
Davidson Gomes
2024-06-08 19:04:57 -03:00
parent 56df0caab0
commit fe9803b828
19 changed files with 1023 additions and 282 deletions

View File

@@ -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)) {

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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'),
};