diff --git a/Docker/.env.example b/Docker/.env.example index 0f4f2972..bf21a71c 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -31,7 +31,7 @@ CLEAN_STORE_CONTACTS=true CLEAN_STORE_CHATS=true # Permanent data storage -DATABASE_ENABLED=true +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 @@ -42,13 +42,15 @@ DATABASE_SAVE_MESSAGE_UPDATE=false DATABASE_SAVE_DATA_CONTACTS=false DATABASE_SAVE_DATA_CHATS=false -REDIS_ENABLED=true +REDIS_ENABLED=false REDIS_URI=redis://redis:6379 REDIS_PREFIX_KEY=evdocker -RABBITMQ_ENABLED=true +RABBITMQ_ENABLED=false RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672 +WEBSOCKET_ENABLED=false + # Global Webhook Settings # Each instance's Webhook URL and events will be requested at the time it is created ## Define a global webhook that will listen for enabled events from all instances diff --git a/Dockerfile b/Dockerfile index 4484b8b8..c9975782 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,6 +54,8 @@ ENV REDIS_PREFIX_KEY=evolution ENV RABBITMQ_ENABLED=false ENV RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672 +ENV WEBSOCKET_ENABLED=false + ENV WEBHOOK_GLOBAL_URL= ENV WEBHOOK_GLOBAL_ENABLED=false diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 8ddb4e2c..4f28dbd5 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -66,6 +66,10 @@ export type Rabbitmq = { URI: string; }; +export type Websocket = { + ENABLED: boolean; +}; + export type EventsWebhook = { APPLICATION_STARTUP: boolean; QRCODE_UPDATED: boolean; @@ -122,6 +126,7 @@ export interface Env { DATABASE: Database; REDIS: Redis; RABBITMQ: Rabbitmq; + WEBSOCKET: Websocket; LOG: Log; DEL_INSTANCE: DelInstance; WEBHOOK: Webhook; @@ -211,6 +216,9 @@ export class ConfigService { ENABLED: process.env?.RABBITMQ_ENABLED === 'true', URI: process.env.RABBITMQ_URI, }, + WEBSOCKET: { + ENABLED: process.env?.WEBSOCKET_ENABLED === 'true', + }, LOG: { LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[], COLOR: process.env?.LOG_COLOR === 'true', diff --git a/src/dev-env.yml b/src/dev-env.yml index 02cb0730..235ec1b7 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -83,6 +83,9 @@ RABBITMQ: ENABLED: false URI: "amqp://guest:guest@localhost:5672" +WEBSOCKET: + ENABLED: false + # Global Webhook Settings # Each instance's Webhook URL and events will be requested at the time it is created WEBHOOK: diff --git a/src/libs/socket.server.ts b/src/libs/socket.server.ts index 367a3933..9da11b0a 100644 --- a/src/libs/socket.server.ts +++ b/src/libs/socket.server.ts @@ -1,7 +1,7 @@ import { Server } from 'http'; import { Server as SocketIO } from 'socket.io'; -import { configService, Cors } from '../config/env.config'; +import { configService, Cors, Websocket } from '../config/env.config'; import { Logger } from '../config/logger.config'; const logger = new Logger('Socket'); @@ -11,22 +11,25 @@ let io: SocketIO; const cors = configService.get('CORS').ORIGIN; export const initIO = (httpServer: Server) => { - io = new SocketIO(httpServer, { - cors: { - origin: cors, - }, - }); - - io.on('connection', (socket) => { - logger.info('User connected'); - - socket.on('disconnect', () => { - logger.info('User disconnected'); + if (configService.get('WEBSOCKET').ENABLED) { + io = new SocketIO(httpServer, { + cors: { + origin: cors, + }, }); - }); - logger.info('Socket.io initialized'); - return io; + io.on('connection', (socket) => { + logger.info('User connected'); + + socket.on('disconnect', () => { + logger.info('User disconnected'); + }); + }); + + logger.info('Socket.io initialized'); + return io; + } + return null; }; export const getIO = (): SocketIO => { diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index 883e5431..2a904761 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -64,6 +64,7 @@ export class InstanceController { typebot_url, typebot, typebot_expire, + typebot_keyword_finish, typebot_delay_message, typebot_unknown_message, }: InstanceDto) { @@ -243,6 +244,7 @@ export class InstanceController { url: typebot_url, typebot: typebot, expire: typebot_expire, + keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, }); @@ -286,7 +288,7 @@ export class InstanceController { webhook_by_events, events: webhookEvents, }, - websocker: { + websocket: { enabled: websocket_enabled, events: websocketEvents, }, @@ -299,6 +301,7 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, }, @@ -377,7 +380,7 @@ export class InstanceController { webhook_by_events, events: webhookEvents, }, - websocker: { + websocket: { enabled: websocket_enabled, events: websocketEvents, }, @@ -390,6 +393,7 @@ export class InstanceController { url: typebot_url, typebot, expire: typebot_expire, + keyword_finish: typebot_keyword_finish, delay_message: typebot_delay_message, unknown_message: typebot_unknown_message, }, diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index a93fed73..cffe0303 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -25,6 +25,7 @@ export class InstanceDto { typebot_url?: string; typebot?: string; typebot_expire?: number; + typebot_keyword_finish?: string; typebot_delay_message?: number; typebot_unknown_message?: string; proxy_enabled?: boolean; diff --git a/src/whatsapp/dto/typebot.dto.ts b/src/whatsapp/dto/typebot.dto.ts index 9c8759dc..cda5ae58 100644 --- a/src/whatsapp/dto/typebot.dto.ts +++ b/src/whatsapp/dto/typebot.dto.ts @@ -11,6 +11,7 @@ export class TypebotDto { url: string; typebot?: string; expire?: number; + keyword_finish?: string; 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 5358d0c2..5b005294 100644 --- a/src/whatsapp/models/typebot.model.ts +++ b/src/whatsapp/models/typebot.model.ts @@ -16,6 +16,7 @@ export class TypebotRaw { url: string; typebot?: string; expire?: number; + keyword_finish?: string; delay_message?: number; unknown_message?: string; sessions?: Session[]; @@ -27,6 +28,7 @@ const typebotSchema = new Schema({ url: { type: String, required: true }, typebot: { type: String, required: true }, expire: { type: Number, required: true }, + keyword_finish: { type: String, required: true }, delay_message: { type: Number, required: true }, unknown_message: { type: String, required: true }, sessions: [ diff --git a/src/whatsapp/services/typebot.service.ts b/src/whatsapp/services/typebot.service.ts index 491459bb..22cdd9b8 100644 --- a/src/whatsapp/services/typebot.service.ts +++ b/src/whatsapp/services/typebot.service.ts @@ -50,6 +50,9 @@ export class TypebotService { url: findData.url, typebot: findData.typebot, expire: findData.expire, + keyword_finish: findData.keyword_finish, + delay_message: findData.delay_message, + unknown_message: findData.unknown_message, sessions: findData.sessions, }; @@ -70,6 +73,9 @@ export class TypebotService { url: findData.url, typebot: findData.typebot, expire: findData.expire, + keyword_finish: findData.keyword_finish, + delay_message: findData.delay_message, + unknown_message: findData.unknown_message, sessions: findData.sessions, }; @@ -143,6 +149,9 @@ export class TypebotService { url: data.url, typebot: data.typebot, expire: data.expire, + keyword_finish: data.keyword_finish, + delay_message: data.delay_message, + unknown_message: data.unknown_message, sessions: data.sessions, }; @@ -285,6 +294,9 @@ export class TypebotService { const typebot = (await this.find(instance)).typebot; const sessions = ((await this.find(instance)).sessions as Session[]) ?? []; const expire = (await this.find(instance)).expire; + const keyword_finish = (await this.find(instance)).keyword_finish; + const delay_message = (await this.find(instance)).delay_message; + const unknown_message = (await this.find(instance)).unknown_message; const session = sessions.find((session) => session.remoteJid === remoteJid); @@ -302,6 +314,9 @@ export class TypebotService { url: url, typebot: typebot, expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, sessions: sessions, remoteJid: remoteJid, pushName: msg.pushName, @@ -322,6 +337,9 @@ export class TypebotService { url: url, typebot: typebot, expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, sessions: sessions, remoteJid: remoteJid, pushName: msg.pushName, @@ -343,6 +361,9 @@ export class TypebotService { url: url, typebot: typebot, expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, sessions, }; @@ -351,21 +372,40 @@ export class TypebotService { const content = this.getConversationMessage(msg.message); if (!content) { - if (this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message) { + if (unknown_message) { this.waMonitor.waInstances[instance.instanceName].textMessage({ number: remoteJid.split('@')[0], options: { - delay: this.waMonitor.waInstances[instance.instanceName].localTypebot.delay_message || 1000, + delay: delay_message || 1000, presence: 'composing', }, textMessage: { - text: this.waMonitor.waInstances[instance.instanceName].localTypebot.unknown_message, + text: unknown_message, }, }); } return; } + if (content.toLowerCase() === keyword_finish.toLowerCase()) { + sessions.splice(sessions.indexOf(session), 1); + + const typebotData = { + enabled: true, + url: url, + typebot: typebot, + expire: expire, + keyword_finish: keyword_finish, + delay_message: delay_message, + unknown_message: unknown_message, + sessions, + }; + + this.create(instance, typebotData); + + return; + } + const reqData = { message: content, sessionId: session.sessionId.split('-')[1], diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 241555ff..6d24b61d 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -61,6 +61,7 @@ import { QrCode, Redis, Webhook, + Websocket, } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; @@ -505,6 +506,9 @@ export class WAStartupService { this.localTypebot.expire = data?.expire; this.logger.verbose(`Typebot expire: ${this.localTypebot.expire}`); + this.localTypebot.keyword_finish = data?.keyword_finish; + this.logger.verbose(`Typebot keyword_finish: ${this.localTypebot.keyword_finish}`); + this.localTypebot.delay_message = data?.delay_message; this.logger.verbose(`Typebot delay_message: ${this.localTypebot.delay_message}`); @@ -521,8 +525,9 @@ 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}`); + this.logger.verbose(`Typebot keyword_finish: ${data.keyword_finish}`); + this.logger.verbose(`Typebot delay_message: ${data.delay_message}`); + this.logger.verbose(`Typebot unknown_message: ${data.unknown_message}`); Object.assign(this.localTypebot, data); this.logger.verbose('Typebot set'); } @@ -618,7 +623,7 @@ export class WAStartupService { } } - if (this.localWebsocket.enabled) { + if (this.configService.get('WEBSOCKET').ENABLED && this.localWebsocket.enabled) { this.logger.verbose('Sending data to websocket on channel: ' + this.instance.name); if (Array.isArray(websocketLocal) && websocketLocal.includes(we)) { this.logger.verbose('Sending data to websocket on event: ' + event); diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index b20165d9..893b5f87 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -91,6 +91,7 @@ export declare namespace wa { url?: string; typebot?: string; expire?: number; + keyword_finish?: string; delay_message?: number; unknown_message?: string; sessions?: Session[];