diff --git a/.DS_Store b/.DS_Store index f07b5fd4..caa91ed2 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 32e25fac..81a61127 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -983,11 +983,24 @@ export const typebotSchema: JSONSchema7 = { url: { type: 'string' }, typebot: { type: 'string' }, expire: { type: 'integer' }, + delay_message: { type: 'integer' }, + unknown_message: { type: 'string' }, }, required: ['enabled', 'url', 'typebot', 'expire'], ...isNotEmpty('enabled', 'url', 'typebot', 'expire'), }; +export const typebotStatusSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + remoteJid: { type: 'string' }, + status: { type: 'string', enum: ['opened', 'closed', 'paused'] }, + }, + required: ['remoteJid', 'status'], + ...isNotEmpty('remoteJid', 'status'), +}; + export const proxySchema: JSONSchema7 = { $id: v4(), type: 'object', diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index b5d99687..883e5431 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -64,6 +64,8 @@ export class InstanceController { typebot_url, typebot, typebot_expire, + typebot_delay_message, + typebot_unknown_message, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -241,6 +243,8 @@ export class InstanceController { url: typebot_url, typebot: typebot, expire: typebot_expire, + delay_message: typebot_delay_message, + unknown_message: typebot_unknown_message, }); } catch (error) { this.logger.log(error); @@ -295,6 +299,8 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + delay_message: typebot_delay_message, + unknown_message: typebot_unknown_message, }, settings, qrcode: getQrcode, @@ -384,6 +390,8 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + delay_message: typebot_delay_message, + unknown_message: typebot_unknown_message, }, settings, chatwoot: { diff --git a/src/whatsapp/controllers/typebot.controller.ts b/src/whatsapp/controllers/typebot.controller.ts index aff33511..0cda7d57 100644 --- a/src/whatsapp/controllers/typebot.controller.ts +++ b/src/whatsapp/controllers/typebot.controller.ts @@ -33,4 +33,9 @@ export class TypebotController { logger.verbose('requested findTypebot from ' + instance.instanceName + ' instance'); return this.typebotService.find(instance); } + + public async changeStatus(instance: InstanceDto, data: any) { + logger.verbose('requested changeStatus from ' + instance.instanceName + ' instance'); + return this.typebotService.changeStatus(instance, data); + } } diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index a58a20d5..a93fed73 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -25,6 +25,8 @@ export class InstanceDto { typebot_url?: string; typebot?: string; typebot_expire?: number; + typebot_delay_message?: number; + typebot_unknown_message?: string; proxy_enabled?: boolean; proxy_proxy?: string; } diff --git a/src/whatsapp/dto/typebot.dto.ts b/src/whatsapp/dto/typebot.dto.ts index 57798bdb..9c8759dc 100644 --- a/src/whatsapp/dto/typebot.dto.ts +++ b/src/whatsapp/dto/typebot.dto.ts @@ -1,6 +1,7 @@ export class Session { remoteJid?: string; sessionId?: string; + status?: string; createdAt?: number; updateAt?: number; } @@ -10,5 +11,7 @@ export class TypebotDto { url: string; typebot?: string; expire?: number; + delay_message?: number; + unknown_message?: string; sessions?: Session[]; } diff --git a/src/whatsapp/models/typebot.model.ts b/src/whatsapp/models/typebot.model.ts index bff7092c..5358d0c2 100644 --- a/src/whatsapp/models/typebot.model.ts +++ b/src/whatsapp/models/typebot.model.ts @@ -5,6 +5,7 @@ import { dbserver } from '../../libs/db.connect'; class Session { remoteJid?: string; sessionId?: string; + status?: string; createdAt?: number; updateAt?: number; } @@ -15,6 +16,8 @@ export class TypebotRaw { url: string; typebot?: string; expire?: number; + delay_message?: number; + unknown_message?: string; sessions?: Session[]; } @@ -24,10 +27,13 @@ const typebotSchema = new Schema({ url: { type: String, required: true }, typebot: { type: String, required: true }, expire: { type: Number, required: true }, + delay_message: { type: Number, required: true }, + unknown_message: { type: String, required: true }, sessions: [ { remoteJid: { type: String, required: true }, sessionId: { type: String, required: true }, + status: { type: String, required: true }, createdAt: { type: Number, required: true }, updateAt: { type: Number, required: true }, }, diff --git a/src/whatsapp/routers/typebot.router.ts b/src/whatsapp/routers/typebot.router.ts index 4d770444..68bb6395 100644 --- a/src/whatsapp/routers/typebot.router.ts +++ b/src/whatsapp/routers/typebot.router.ts @@ -1,7 +1,7 @@ import { RequestHandler, Router } from 'express'; import { Logger } from '../../config/logger.config'; -import { instanceNameSchema, typebotSchema } from '../../validate/validate.schema'; +import { instanceNameSchema, typebotSchema, typebotStatusSchema } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { TypebotDto } from '../dto/typebot.dto'; @@ -44,6 +44,22 @@ export class TypebotRouter extends RouterBroker { execute: (instance) => typebotController.findTypebot(instance), }); + res.status(HttpStatus.OK).json(response); + }) + .post(this.routerPath('changeStatus'), ...guards, async (req, res) => { + logger.verbose('request received in findTypebot'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + const response = await this.dataValidate({ + request: req, + schema: typebotStatusSchema, + ClassRef: InstanceDto, + execute: (instance, data) => typebotController.changeStatus(instance, data), + }); + res.status(HttpStatus.OK).json(response); }); } diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 2bae03cd..491459bb 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -33,23 +33,57 @@ export class TypebotService { } } + public async changeStatus(instance: InstanceDto, data: any) { + const remoteJid = data.remoteJid; + const status = data.status; + + const findData = await this.find(instance); + + const session = findData.sessions.find((session) => session.remoteJid === remoteJid); + + if (session) { + if (status === 'closed') { + findData.sessions.splice(findData.sessions.indexOf(session), 1); + + const typebotData = { + enabled: true, + url: findData.url, + typebot: findData.typebot, + expire: findData.expire, + sessions: findData.sessions, + }; + + this.create(instance, typebotData); + + return { typebot: { ...instance, typebot: typebotData } }; + } + + findData.sessions.map((session) => { + if (session.remoteJid === remoteJid) { + session.status = status; + } + }); + } + + const typebotData = { + enabled: true, + url: findData.url, + typebot: findData.typebot, + expire: findData.expire, + sessions: findData.sessions, + }; + + this.create(instance, typebotData); + + return { typebot: { ...instance, typebot: typebotData } }; + } + private getTypeMessage(msg: any) { this.logger.verbose('get type message'); const types = { conversation: msg.conversation, - imageMessage: msg.imageMessage?.caption, - videoMessage: msg.videoMessage?.caption, extendedTextMessage: msg.extendedTextMessage?.text, - messageContextInfo: msg.messageContextInfo?.stanzaId, - stickerMessage: undefined, - documentMessage: msg.documentMessage?.caption, - documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, - audioMessage: msg.audioMessage?.caption, - contactMessage: msg.contactMessage?.vcard, - contactsArrayMessage: msg.contactsArrayMessage, - locationMessage: msg.locationMessage, - liveLocationMessage: msg.liveLocationMessage, }; this.logger.verbose('type message: ' + types); @@ -86,6 +120,10 @@ export class TypebotService { sessionId: id, startParams: { typebot: data.typebot, + prefilledVariables: { + remoteJid: data.remoteJid, + pushName: data.pushName, + }, }, }; @@ -95,6 +133,7 @@ export class TypebotService { data.sessions.push({ remoteJid: data.remoteJid, sessionId: `${id}-${request.data.sessionId}`, + status: 'opened', createdAt: Date.now(), updateAt: Date.now(), }); @@ -114,23 +153,9 @@ export class TypebotService { } public async sendWAMessage(instance: InstanceDto, remoteJid: string, messages: any[], input: any[]) { - processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input) - .then(async () => { - if (!input) { - const typebotData = await this.find(instance); - - const session = typebotData.sessions.find((session) => session.remoteJid === remoteJid); - - if (session) { - typebotData.sessions.splice(typebotData.sessions.indexOf(session), 1); - - this.create(instance, typebotData); - } - } - }) - .catch((err) => { - console.error('Erro ao processar mensagens:', err); - }); + processMessages(this.waMonitor.waInstances[instance.instanceName], messages, input).catch((err) => { + console.error('Erro ao processar mensagens:', err); + }); async function processMessages(instance, messages, input) { for (const message of messages) { @@ -174,7 +199,7 @@ export class TypebotService { await instance.textMessage({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'composing', linkPreview: linkPreview, }, @@ -188,7 +213,7 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'composing', }, mediaMessage: { @@ -202,7 +227,7 @@ export class TypebotService { await instance.mediaMessage({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'composing', }, mediaMessage: { @@ -216,7 +241,7 @@ export class TypebotService { await instance.audioWhatsapp({ number: remoteJid.split('@')[0], options: { - delay: 1200, + delay: instance.localTypebot.delay_message || 1000, presence: 'recording', encoding: true, }, @@ -279,6 +304,7 @@ export class TypebotService { expire: expire, sessions: sessions, remoteJid: remoteJid, + pushName: msg.pushName, }); await this.sendWAMessage(instance, remoteJid, data.messages, data.input); @@ -287,6 +313,10 @@ export class TypebotService { } } + if (session && session.status !== 'opened') { + return; + } + if (!session) { const data = await this.createNewSession(instance, { url: url, @@ -294,6 +324,7 @@ export class TypebotService { expire: expire, sessions: sessions, remoteJid: remoteJid, + pushName: msg.pushName, }); await this.sendWAMessage(instance, remoteJid, data.messages, data.input); @@ -320,22 +351,18 @@ export class TypebotService { const content = this.getConversationMessage(msg.message); if (!content) { - return; - } - - if (content.toLowerCase() === 'sair') { - sessions.splice(sessions.indexOf(session), 1); - - const typebotData = { - enabled: true, - url: url, - typebot: typebot, - expire: expire, - sessions, - }; - - this.create(instance, typebotData); - + if (this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message) { + this.waMonitor.waInstances[instance.instanceName].textMessage({ + number: remoteJid.split('@')[0], + options: { + delay: this.waMonitor.waInstances[instance.instanceName].localTypebot.delay_message || 1000, + presence: 'composing', + }, + textMessage: { + text: this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message, + }, + }); + } return; } @@ -346,18 +373,6 @@ export class TypebotService { const request = await axios.post(url + '/api/v1/sendMessage', reqData); - if (!request.data.input) { - sessions.splice(sessions.indexOf(session), 1); - - await this.createNewSession(instance, { - url: url, - typebot: typebot, - expire: expire, - sessions: sessions, - remoteJid: remoteJid, - }); - } - await this.sendWAMessage(instance, remoteJid, request.data.messages, request.data.input); return; diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index f71300ea..241555ff 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -45,7 +45,6 @@ import { release } from 'os'; import { join } from 'path'; import P from 'pino'; import { ProxyAgent } from 'proxy-agent'; -// import { ProxyAgent } from 'proxy-agent'; import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; import qrcodeTerminal from 'qrcode-terminal'; import sharp from 'sharp'; @@ -149,7 +148,7 @@ export class WAStartupService { private readonly localSettings: wa.LocalSettings = {}; private readonly localWebsocket: wa.LocalWebsocket = {}; private readonly localRabbitmq: wa.LocalRabbitmq = {}; - private readonly localTypebot: wa.LocalTypebot = {}; + public readonly localTypebot: wa.LocalTypebot = {}; private readonly localProxy: wa.LocalProxy = {}; public stateConnection: wa.StateConnection = { state: 'close' }; public readonly storePath = join(ROOT_DIR, 'store'); @@ -506,6 +505,12 @@ export class WAStartupService { this.localTypebot.expire = data?.expire; this.logger.verbose(`Typebot expire: ${this.localTypebot.expire}`); + this.localTypebot.delay_message = data?.delay_message; + this.logger.verbose(`Typebot delay_message: ${this.localTypebot.delay_message}`); + + this.localTypebot.unknown_message = data?.unknown_message; + this.logger.verbose(`Typebot unknown_message: ${this.localTypebot.unknown_message}`); + this.localTypebot.sessions = data?.sessions; this.logger.verbose('Typebot loaded'); @@ -516,6 +521,8 @@ export class WAStartupService { await this.repository.typebot.create(data, this.instanceName); this.logger.verbose(`Typebot typebot: ${data.typebot}`); this.logger.verbose(`Typebot expire: ${data.expire}`); + this.logger.verbose(`Typebot sessions: ${data.delay_message}`); + this.logger.verbose(`Typebot sessions: ${data.unknown_message}`); Object.assign(this.localTypebot, data); this.logger.verbose('Typebot set'); } diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index 84113b42..b20165d9 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -91,6 +91,8 @@ export declare namespace wa { url?: string; typebot?: string; expire?: number; + delay_message?: number; + unknown_message?: string; sessions?: Session[]; };