feat: Added debounce time for typebot messages

This commit is contained in:
Davidson Gomes
2024-06-11 17:56:20 -03:00
parent 0bf8e55144
commit 2776f113cb
21 changed files with 756 additions and 255 deletions

View File

@@ -7,7 +7,6 @@ import { v4 } from 'uuid';
import { Auth, Chatwoot, ConfigService, HttpServer, WaBusiness } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { BadRequestException, InternalServerErrorException, UnauthorizedException } from '../../exceptions';
import { Events as EventsArray } from '../../validate/validate.schema';
import { InstanceDto, SetPresenceDto } from '../dto/instance.dto';
import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service';
import { RabbitmqService } from '../integrations/rabbitmq/services/rabbitmq.service';
@@ -154,7 +153,33 @@ export class InstanceController {
try {
let newEvents: string[] = [];
if (webhookEvents.length === 0) {
newEvents = EventsArray;
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = webhookEvents;
}
@@ -180,7 +205,33 @@ export class InstanceController {
try {
let newEvents: string[] = [];
if (websocketEvents.length === 0) {
newEvents = EventsArray;
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = websocketEvents;
}
@@ -205,7 +256,33 @@ export class InstanceController {
try {
let newEvents: string[] = [];
if (rabbitmqEvents.length === 0) {
newEvents = EventsArray;
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = rabbitmqEvents;
}
@@ -228,7 +305,33 @@ export class InstanceController {
try {
let newEvents: string[] = [];
if (sqsEvents.length === 0) {
newEvents = EventsArray;
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = sqsEvents;
}

View File

@@ -1,7 +1,6 @@
import { isURL } from 'class-validator';
import { BadRequestException } from '../../exceptions';
import { Events } from '../../validate/validate.schema';
import { InstanceDto } from '../dto/instance.dto';
import { WebhookDto } from '../dto/webhook.dto';
import { WAMonitoringService } from '../services/monitor.service';
@@ -21,7 +20,33 @@ export class WebhookController {
data.url = '';
data.events = [];
} else if (data.events.length === 0) {
data.events = Events;
data.events = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
}
return this.webhookService.create(instance, data);

View File

@@ -1,6 +1,5 @@
import { configService, Rabbitmq } from '../../../../config/env.config';
import { BadRequestException } from '../../../../exceptions';
import { Events } from '../../../../validate/validate.schema';
import { InstanceDto } from '../../../dto/instance.dto';
import { RabbitmqDto } from '../dto/rabbitmq.dto';
import { RabbitmqService } from '../services/rabbitmq.service';
@@ -16,7 +15,33 @@ export class RabbitmqController {
}
if (data.events.length === 0) {
data.events = Events;
data.events = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
}
return this.rabbitmqService.create(instance, data);

View File

@@ -12,6 +12,7 @@ export class RabbitmqRouter extends RouterBroker {
super();
this.router
.post(this.routerPath('set'), ...guards, async (req, res) => {
console.log('RabbitmqRouter -> constructor -> req', req.body);
const response = await this.dataValidate<RabbitmqDto>({
request: req,
schema: rabbitmqSchema,

View File

@@ -1,8 +1,6 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
import { Events } from '../../../../validate/validate.schema';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
@@ -32,7 +30,33 @@ export const rabbitmqSchema: JSONSchema7 = {
minItems: 0,
items: {
type: 'string',
enum: Events,
enum: [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
],
},
},
},

View File

@@ -1,6 +1,5 @@
import { configService, Sqs } from '../../../../config/env.config';
import { BadRequestException } from '../../../../exceptions';
import { Events } from '../../../../validate/validate.schema';
import { InstanceDto } from '../../../dto/instance.dto';
import { SqsDto } from '../dto/sqs.dto';
import { SqsService } from '../services/sqs.service';
@@ -16,7 +15,33 @@ export class SqsController {
}
if (data.events.length === 0) {
data.events = Events;
data.events = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
}
return this.sqsService.create(instance, data);

View File

@@ -1,8 +1,6 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
import { Events } from '../../../../validate/validate.schema';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
@@ -32,7 +30,33 @@ export const sqsSchema: JSONSchema7 = {
minItems: 0,
items: {
type: 'string',
enum: Events,
enum: [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
],
},
},
},

View File

@@ -27,6 +27,7 @@ export class TypebotDto {
listeningFromMe?: boolean;
stopBotFromMe?: boolean;
keepOpen?: boolean;
debounceTime?: number;
triggerType?: TriggerType;
triggerOperator?: TriggerOperator;
triggerValue?: string;
@@ -40,4 +41,5 @@ export class TypebotSettingDto {
listeningFromMe?: boolean;
stopBotFromMe?: boolean;
keepOpen?: boolean;
debounceTime?: number;
}

View File

@@ -1,4 +1,4 @@
import { Message, TypebotSession } from '@prisma/client';
import { Message, Typebot as TypebotModel, TypebotSession } from '@prisma/client';
import axios from 'axios';
import { ConfigService, Typebot } from '../../../../config/env.config';
@@ -16,6 +16,8 @@ export class TypebotService {
private readonly prismaRepository: PrismaRepository,
) {}
private userMessageDebounce: { [key: string]: { message: string; timeoutId: NodeJS.Timeout } } = {};
private readonly logger = new Logger(TypebotService.name);
public async create(instance: InstanceDto, data: TypebotDto) {
@@ -34,7 +36,8 @@ export class TypebotService {
!data.unknownMessage ||
!data.listeningFromMe ||
!data.stopBotFromMe ||
!data.keepOpen
!data.keepOpen ||
!data.debounceTime
) {
const defaultSettingCheck = await this.prismaRepository.typebotSetting.findFirst({
where: {
@@ -53,6 +56,7 @@ export class TypebotService {
if (!data.listeningFromMe) data.listeningFromMe = defaultSettingCheck.listeningFromMe;
if (!data.stopBotFromMe) data.stopBotFromMe = defaultSettingCheck.stopBotFromMe;
if (!data.keepOpen) data.keepOpen = defaultSettingCheck.keepOpen;
if (!data.debounceTime) data.debounceTime = defaultSettingCheck.debounceTime;
}
const checkTriggerAll = await this.prismaRepository.typebot.findFirst({
@@ -106,6 +110,8 @@ export class TypebotService {
unknownMessage: data.unknownMessage,
listeningFromMe: data.listeningFromMe,
stopBotFromMe: data.stopBotFromMe,
keepOpen: data.keepOpen,
debounceTime: data.debounceTime,
instanceId: instanceId,
triggerType: data.triggerType,
triggerOperator: data.triggerOperator,
@@ -238,6 +244,8 @@ export class TypebotService {
unknownMessage: data.unknownMessage,
listeningFromMe: data.listeningFromMe,
stopBotFromMe: data.stopBotFromMe,
keepOpen: data.keepOpen,
debounceTime: data.debounceTime,
triggerType: data.triggerType,
triggerOperator: data.triggerOperator,
triggerValue: data.triggerValue,
@@ -349,6 +357,7 @@ export class TypebotService {
listeningFromMe: data.listeningFromMe,
stopBotFromMe: data.stopBotFromMe,
keepOpen: data.keepOpen,
debounceTime: data.debounceTime,
},
});
@@ -360,6 +369,7 @@ export class TypebotService {
listeningFromMe: updateSettings.listeningFromMe,
stopBotFromMe: updateSettings.stopBotFromMe,
keepOpen: updateSettings.keepOpen,
debounceTime: updateSettings.debounceTime,
};
}
@@ -372,6 +382,7 @@ export class TypebotService {
listeningFromMe: data.listeningFromMe,
stopBotFromMe: data.stopBotFromMe,
keepOpen: data.keepOpen,
debounceTime: data.debounceTime,
instanceId: instanceId,
},
});
@@ -384,6 +395,7 @@ export class TypebotService {
listeningFromMe: newSetttings.listeningFromMe,
stopBotFromMe: newSetttings.stopBotFromMe,
keepOpen: newSetttings.keepOpen,
debounceTime: newSetttings.debounceTime,
};
} catch (error) {
this.logger.error(error);
@@ -1119,9 +1131,30 @@ export class TypebotService {
return typebot;
}
private processDebounce(content: string, remoteJid: string, debounceTime: number, callback: any) {
if (this.userMessageDebounce[remoteJid]) {
this.userMessageDebounce[remoteJid].message += ` ${content}`;
this.logger.log('message debounced: ' + this.userMessageDebounce[remoteJid].message);
clearTimeout(this.userMessageDebounce[remoteJid].timeoutId);
} else {
this.userMessageDebounce[remoteJid] = {
message: content,
timeoutId: null,
};
}
this.userMessageDebounce[remoteJid].timeoutId = setTimeout(() => {
const myQuestion = this.userMessageDebounce[remoteJid].message;
this.logger.log('Debounce complete. Processing message: ' + myQuestion);
delete this.userMessageDebounce[remoteJid];
callback(myQuestion);
}, debounceTime * 1000);
}
public async sendTypebot(instance: InstanceDto, remoteJid: string, msg: Message) {
try {
let session = await this.prismaRepository.typebotSession.findFirst({
const session = await this.prismaRepository.typebotSession.findFirst({
where: {
remoteJid: remoteJid,
},
@@ -1154,6 +1187,7 @@ export class TypebotService {
let listeningFromMe = findTypebot?.listeningFromMe;
let stopBotFromMe = findTypebot?.stopBotFromMe;
let keepOpen = findTypebot?.keepOpen;
let debounceTime = findTypebot?.debounceTime;
if (
!expire ||
@@ -1183,6 +1217,8 @@ export class TypebotService {
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!keepOpen) keepOpen = settings.keepOpen;
if (!debounceTime) debounceTime = settings.debounceTime;
}
const key = msg.key as {
@@ -1206,141 +1242,107 @@ export class TypebotService {
return;
}
if (session && !session.awaitUser) return;
if (session && expire && expire > 0) {
const now = Date.now();
const sessionUpdatedAt = new Date(session.updatedAt).getTime();
const diff = now - sessionUpdatedAt;
const diffInMinutes = Math.floor(diff / 1000 / 60);
if (diffInMinutes > expire) {
await this.prismaRepository.typebotSession.deleteMany({
where: {
typebotId: findTypebot.id,
remoteJid: remoteJid,
},
});
const data = await this.createNewSession(instance, {
enabled: findTypebot.enabled,
url: url,
typebot: typebot,
expire: expire,
keywordFinish: keywordFinish,
delayMessage: delayMessage,
unknownMessage: unknownMessage,
listeningFromMe: listeningFromMe,
remoteJid: remoteJid,
pushName: msg.pushName,
typebotId: findTypebot.id,
});
if (data.session) {
session = data.session;
}
await this.sendWAMessage(
if (debounceTime && debounceTime > 0) {
this.processDebounce(content, remoteJid, debounceTime, async (debouncedContent) => {
await this.processTypebot(
instance,
session,
{
expire: expire,
keywordFinish: keywordFinish,
delayMessage: delayMessage,
unknownMessage: unknownMessage,
listeningFromMe: listeningFromMe,
stopBotFromMe: stopBotFromMe,
keepOpen: keepOpen,
},
remoteJid,
data.messages,
data.input,
data.clientSideActions,
msg,
session,
findTypebot,
url,
expire,
typebot,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debouncedContent,
);
if (data.messages.length === 0) {
const content = this.getConversationMessage(msg.message);
if (!content) {
if (unknownMessage) {
this.waMonitor.waInstances[instance.instanceName].textMessage(
{
number: remoteJid.split('@')[0],
delay: delayMessage || 1000,
text: unknownMessage,
},
true,
);
}
return;
}
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
await this.prismaRepository.typebotSession.deleteMany({
where: {
typebotId: findTypebot.id,
remoteJid: remoteJid,
},
});
return;
}
try {
const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;
let urlTypebot: string;
let reqData: {};
if (version === 'latest') {
urlTypebot = `${url}/api/v1/sessions/${data.sessionId}/continueChat`;
reqData = {
message: content,
};
} else {
urlTypebot = `${url}/api/v1/sendMessage`;
reqData = {
message: content,
sessionId: data.sessionId,
};
}
const request = await axios.post(urlTypebot, reqData);
await this.sendWAMessage(
instance,
session,
{
expire: expire,
keywordFinish: keywordFinish,
delayMessage: delayMessage,
unknownMessage: unknownMessage,
listeningFromMe: listeningFromMe,
stopBotFromMe: stopBotFromMe,
keepOpen: keepOpen,
},
remoteJid,
request.data.messages,
request.data.input,
request.data.clientSideActions,
);
} catch (error) {
this.logger.error(error);
return;
}
}
return;
}
});
} else {
await this.processTypebot(
instance,
remoteJid,
msg,
session,
findTypebot,
url,
expire,
typebot,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
content,
);
}
if (session && session.status !== 'opened') {
return;
}
// await this.processTypebot(
// instance,
// remoteJid,
// msg,
// session,
// findTypebot,
// url,
// expire,
// typebot,
// keywordFinish,
// delayMessage,
// unknownMessage,
// listeningFromMe,
// stopBotFromMe,
// keepOpen,
// content,
// );
if (session && !session.awaitUser) return;
} catch (error) {
this.logger.error(error);
return;
}
}
private async processTypebot(
instance: InstanceDto,
remoteJid: string,
msg: Message,
session: TypebotSession,
findTypebot: TypebotModel,
url: string,
expire: number,
typebot: string,
keywordFinish: string,
delayMessage: number,
unknownMessage: string,
listeningFromMe: boolean,
stopBotFromMe: boolean,
keepOpen: boolean,
content: string,
) {
if (session && expire && expire > 0) {
const now = Date.now();
const sessionUpdatedAt = new Date(session.updatedAt).getTime();
const diff = now - sessionUpdatedAt;
const diffInMinutes = Math.floor(diff / 1000 / 60);
if (diffInMinutes > expire) {
await this.prismaRepository.typebotSession.deleteMany({
where: {
typebotId: findTypebot.id,
remoteJid: remoteJid,
},
});
if (!session) {
const data = await this.createNewSession(instance, {
enabled: findTypebot?.enabled,
enabled: findTypebot.enabled,
url: url,
typebot: typebot,
expire: expire,
@@ -1370,12 +1372,14 @@ export class TypebotService {
keepOpen: keepOpen,
},
remoteJid,
data?.messages,
data?.input,
data?.clientSideActions,
data.messages,
data.input,
data.clientSideActions,
);
if (data.messages.length === 0) {
const content = this.getConversationMessage(msg.message);
if (!content) {
if (unknownMessage) {
this.waMonitor.waInstances[instance.instanceName].textMessage(
@@ -1397,11 +1401,9 @@ export class TypebotService {
remoteJid: remoteJid,
},
});
return;
}
let request: any;
try {
const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;
let urlTypebot: string;
@@ -1418,7 +1420,8 @@ export class TypebotService {
sessionId: data.sessionId,
};
}
request = await axios.post(urlTypebot, reqData);
const request = await axios.post(urlTypebot, reqData);
await this.sendWAMessage(
instance,
@@ -1442,60 +1445,34 @@ export class TypebotService {
return;
}
}
return;
}
}
await this.prismaRepository.typebotSession.update({
where: {
id: session.id,
},
data: {
status: 'opened',
awaitUser: false,
},
if (session && session.status !== 'opened') {
return;
}
if (!session) {
const data = await this.createNewSession(instance, {
enabled: findTypebot?.enabled,
url: url,
typebot: typebot,
expire: expire,
keywordFinish: keywordFinish,
delayMessage: delayMessage,
unknownMessage: unknownMessage,
listeningFromMe: listeningFromMe,
remoteJid: remoteJid,
pushName: msg.pushName,
typebotId: findTypebot.id,
});
if (!content) {
if (unknownMessage) {
this.waMonitor.waInstances[instance.instanceName].textMessage(
{
number: remoteJid.split('@')[0],
delay: delayMessage || 1000,
text: unknownMessage,
},
true,
);
}
return;
if (data.session) {
session = data.session;
}
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
await this.prismaRepository.typebotSession.deleteMany({
where: {
typebotId: findTypebot.id,
remoteJid: remoteJid,
},
});
return;
}
const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;
let urlTypebot: string;
let reqData: {};
if (version === 'latest') {
urlTypebot = `${url}/api/v1/sessions/${session.sessionId.split('-')[1]}/continueChat`;
reqData = {
message: content,
};
} else {
urlTypebot = `${url}/api/v1/sendMessage`;
reqData = {
message: content,
sessionId: session.sessionId.split('-')[1],
};
}
const request = await axios.post(urlTypebot, reqData);
await this.sendWAMessage(
instance,
session,
@@ -1509,15 +1486,150 @@ export class TypebotService {
keepOpen: keepOpen,
},
remoteJid,
request?.data?.messages,
request?.data?.input,
request?.data?.clientSideActions,
data?.messages,
data?.input,
data?.clientSideActions,
);
return;
} catch (error) {
this.logger.error(error);
if (data.messages.length === 0) {
if (!content) {
if (unknownMessage) {
this.waMonitor.waInstances[instance.instanceName].textMessage(
{
number: remoteJid.split('@')[0],
delay: delayMessage || 1000,
text: unknownMessage,
},
true,
);
}
return;
}
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
await this.prismaRepository.typebotSession.deleteMany({
where: {
typebotId: findTypebot.id,
remoteJid: remoteJid,
},
});
return;
}
let request: any;
try {
const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;
let urlTypebot: string;
let reqData: {};
if (version === 'latest') {
urlTypebot = `${url}/api/v1/sessions/${data.sessionId}/continueChat`;
reqData = {
message: content,
};
} else {
urlTypebot = `${url}/api/v1/sendMessage`;
reqData = {
message: content,
sessionId: data.sessionId,
};
}
request = await axios.post(urlTypebot, reqData);
await this.sendWAMessage(
instance,
session,
{
expire: expire,
keywordFinish: keywordFinish,
delayMessage: delayMessage,
unknownMessage: unknownMessage,
listeningFromMe: listeningFromMe,
stopBotFromMe: stopBotFromMe,
keepOpen: keepOpen,
},
remoteJid,
request.data.messages,
request.data.input,
request.data.clientSideActions,
);
} catch (error) {
this.logger.error(error);
return;
}
}
return;
}
await this.prismaRepository.typebotSession.update({
where: {
id: session.id,
},
data: {
status: 'opened',
awaitUser: false,
},
});
if (!content) {
if (unknownMessage) {
this.waMonitor.waInstances[instance.instanceName].textMessage(
{
number: remoteJid.split('@')[0],
delay: delayMessage || 1000,
text: unknownMessage,
},
true,
);
}
return;
}
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
await this.prismaRepository.typebotSession.deleteMany({
where: {
typebotId: findTypebot.id,
remoteJid: remoteJid,
},
});
return;
}
const version = this.configService.get<Typebot>('TYPEBOT').API_VERSION;
let urlTypebot: string;
let reqData: {};
if (version === 'latest') {
urlTypebot = `${url}/api/v1/sessions/${session.sessionId.split('-')[1]}/continueChat`;
reqData = {
message: content,
};
} else {
urlTypebot = `${url}/api/v1/sendMessage`;
reqData = {
message: content,
sessionId: session.sessionId.split('-')[1],
};
}
const request = await axios.post(urlTypebot, reqData);
await this.sendWAMessage(
instance,
session,
{
expire: expire,
keywordFinish: keywordFinish,
delayMessage: delayMessage,
unknownMessage: unknownMessage,
listeningFromMe: listeningFromMe,
stopBotFromMe: stopBotFromMe,
keepOpen: keepOpen,
},
remoteJid,
request?.data?.messages,
request?.data?.input,
request?.data?.clientSideActions,
);
return;
}
}

View File

@@ -75,6 +75,7 @@ export const typebotSettingSchema: JSONSchema7 = {
listeningFromMe: { type: 'boolean' },
stopBotFromMe: { type: 'boolean' },
keepOpen: { type: 'boolean' },
debounceTime: { type: 'integer' },
},
required: ['expire', 'keywordFinish', 'delayMessage', 'unknownMessage', 'listeningFromMe', 'stopBotFromMe'],
...isNotEmpty('expire', 'keywordFinish', 'delayMessage', 'unknownMessage', 'listeningFromMe', 'stopBotFromMe'),

View File

@@ -1,4 +1,3 @@
import { Events } from '../../../../validate/validate.schema';
import { InstanceDto } from '../../../dto/instance.dto';
import { WebsocketDto } from '../dto/websocket.dto';
import { WebsocketService } from '../services/websocket.service';
@@ -12,7 +11,33 @@ export class WebsocketController {
}
if (data.events.length === 0) {
data.events = Events;
data.events = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
}
return this.websocketService.create(instance, data);

View File

@@ -1,8 +1,6 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
import { Events } from '../../../../validate/validate.schema';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
@@ -32,7 +30,33 @@ export const websocketSchema: JSONSchema7 = {
minItems: 0,
items: {
type: 'string',
enum: Events,
enum: [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
],
},
},
},