From be65b93d5921491a5eb1d90c584782dae154587a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Sat, 8 Jun 2024 13:41:44 -0300 Subject: [PATCH] fix: Correction of variables breaking lines in typebot --- CHANGELOG.md | 1 + prisma/postgresql-schema.prisma | 55 +++--- .../typebot/services/typebot.service.ts | 170 ++++++++---------- .../channels/whatsapp.baileys.service.ts | 10 +- src/api/services/monitor.service.ts | 2 + 5 files changed, 117 insertions(+), 121 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b6a433d..82b3b318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixed * Removed excessive verbose logs * Optimization in instance registration +* Correction of variables breaking lines in typebot ### Break changes * jwt authentication removed diff --git a/prisma/postgresql-schema.prisma b/prisma/postgresql-schema.prisma index 21302be3..b8e5335f 100644 --- a/prisma/postgresql-schema.prisma +++ b/prisma/postgresql-schema.prisma @@ -42,8 +42,8 @@ model Instance { integration String? @db.VarChar(100) number String? @db.VarChar(100) token String? @unique @db.VarChar(255) - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime? @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp Chat Chat[] Contact Contact[] Message Message[] @@ -65,7 +65,7 @@ model Session { id Int @id @unique @default(autoincrement()) sessionId String @unique creds String? @db.Text - createdAt DateTime @default(now()) + createdAt DateTime @default(now()) @db.Timestamp Instance Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade) } @@ -73,8 +73,8 @@ model Chat { id Int @id @default(autoincrement()) remoteJid String @db.VarChar(100) labels Json? @db.JsonB - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime? @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String } @@ -84,8 +84,8 @@ model Contact { remoteJid String @db.VarChar(100) pushName String? @db.VarChar(100) profilePicUrl String? @db.VarChar(500) - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime? @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String } @@ -118,7 +118,6 @@ model MessageUpdate { remoteJid String @db.VarChar(100) fromMe Boolean @db.Boolean participant String? @db.VarChar(100) - dateTime Int @db.Integer pollUpdates Json? @db.JsonB status String @db.VarChar(30) Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade) @@ -134,8 +133,8 @@ model Webhook { events Json? @db.JsonB webhookByEvents Boolean? @default(false) @db.Boolean webhookBase64 Boolean? @default(false) @db.Boolean - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } @@ -156,8 +155,8 @@ model Chatwoot { importContacts Boolean? @default(false) @db.Boolean importMessages Boolean? @default(false) @db.Boolean daysLimitImportMessages Int? @db.Integer - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } @@ -168,8 +167,8 @@ model Label { name String @db.VarChar(100) color String @db.VarChar(100) predefinedId String? @db.VarChar(100) - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String } @@ -182,8 +181,8 @@ model Proxy { protocol String @db.VarChar(100) username String @db.VarChar(100) password String @db.VarChar(100) - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } @@ -197,8 +196,8 @@ model Setting { readMessages Boolean @default(false) @db.Boolean readStatus Boolean @default(false) @db.Boolean syncFullHistory Boolean @default(false) @db.Boolean - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } @@ -207,8 +206,8 @@ model Rabbitmq { id Int @id @default(autoincrement()) enabled Boolean @default(false) @db.Boolean events Json @db.JsonB - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } @@ -217,8 +216,8 @@ model Sqs { id Int @id @default(autoincrement()) enabled Boolean @default(false) @db.Boolean events Json @db.JsonB - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } @@ -227,8 +226,8 @@ model Websocket { id Int @id @default(autoincrement()) enabled Boolean @default(false) @db.Boolean events Json @db.JsonB - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique } @@ -243,8 +242,8 @@ model Typebot { delayMessage Int? @db.Integer unknownMessage String? @db.VarChar(100) listeningFromMe Boolean @default(false) @db.Boolean - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime? @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime? @updatedAt @db.Timestamp Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) instanceId String @unique sessions TypebotSession[] @@ -257,8 +256,8 @@ model TypebotSession { sessionId String @db.VarChar(100) status String @db.VarChar(100) prefilledVariables Json? @db.JsonB - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime @updatedAt @db.Date + createdAt DateTime? @default(now()) @db.Timestamp + updatedAt DateTime @updatedAt @db.Timestamp Typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade) typebotId Int Message Message[] diff --git a/src/api/integrations/typebot/services/typebot.service.ts b/src/api/integrations/typebot/services/typebot.service.ts index 92a1fc9f..b88c6af7 100644 --- a/src/api/integrations/typebot/services/typebot.service.ts +++ b/src/api/integrations/typebot/services/typebot.service.ts @@ -1,4 +1,4 @@ -import { Message } from '@prisma/client'; +import { Message, TypebotSession } from '@prisma/client'; import axios from 'axios'; import EventEmitter2 from 'eventemitter2'; @@ -21,7 +21,11 @@ export class TypebotService { const keep_open = this.configService.get('TYPEBOT').KEEP_OPEN; if (keep_open) return; - await this.clearSessions(data.instance, data.remoteJid); + await this.prismaRepository.typebotSession.deleteMany({ + where: { + id: data.sessionId, + }, + }); }); } @@ -85,43 +89,6 @@ export class TypebotService { return { typebot: { ...instance, typebot: typebotData } }; } - public async clearSessions(instance: InstanceDto, remoteJid: string) { - const findTypebot = await this.find(instance); - const sessions = await this.prismaRepository.typebotSession.findMany({ - where: { - typebotId: findTypebot?.typebot?.id, - remoteJid: remoteJid, - }, - }); - - if (sessions.length > 0) { - await this.prismaRepository.typebotSession.deleteMany({ - where: { - typebotId: findTypebot?.typebot?.id, - remoteJid: remoteJid, - }, - }); - - const typebotData = { - enabled: findTypebot?.typebot?.enabled, - url: findTypebot?.typebot?.url, - typebot: findTypebot?.typebot?.typebot, - expire: findTypebot?.typebot?.expire, - keywordFinish: findTypebot?.typebot?.keywordFinish, - delayMessage: findTypebot?.typebot?.delayMessage, - unknownMessage: findTypebot?.typebot?.unknownMessage, - listeningFromMe: findTypebot?.typebot?.listeningFromMe, - sessions, - }; - - this.create(instance, typebotData); - - return sessions; - } - - return sessions; - } - public async startTypebot(instance: InstanceDto, data: any) { if (data.remoteJid === 'status@broadcast') return; @@ -174,7 +141,14 @@ export class TypebotService { }); if (response.sessionId) { - await this.sendWAMessage(instance, remoteJid, response.messages, response.input, response.clientSideActions); + await this.sendWAMessage( + instance, + response.session, + remoteJid, + response.messages, + response.input, + response.clientSideActions, + ); this.waMonitor.waInstances[instance.instanceName].sendDataWebhook(Events.TYPEBOT_START, { remoteJid: remoteJid, @@ -213,6 +187,7 @@ export class TypebotService { await this.sendWAMessage( instance, + null, remoteJid, request.data.messages, request.data.input, @@ -320,8 +295,9 @@ export class TypebotService { } const request = await axios.post(url, reqData); + let session = null; if (request?.data?.sessionId) { - await this.prismaRepository.typebotSession.create({ + session = await this.prismaRepository.typebotSession.create({ data: { remoteJid: data.remoteJid, pushName: data.pushName || '', @@ -338,7 +314,7 @@ export class TypebotService { }, }); } - return request.data; + return { ...request.data, session }; } catch (error) { this.logger.error(error); return; @@ -347,6 +323,7 @@ export class TypebotService { public async sendWAMessage( instance: InstanceDto, + session: TypebotSession, remoteJid: string, messages: any[], input: any[], @@ -354,6 +331,7 @@ export class TypebotService { ) { processMessages( this.waMonitor.waInstances[instance.instanceName], + session, messages, input, clientSideActions, @@ -387,10 +365,14 @@ export class TypebotService { } } - if (element.type === 'p') { + if (element.type === 'p' && element.type !== 'inline-variable') { text = text.trim() + '\n'; } + if (element.type === 'inline-variable') { + text = text.trim(); + } + if (element.type === 'ol') { text = '\n' + @@ -430,9 +412,18 @@ export class TypebotService { return formattedText; } - async function processMessages(instance, messages, input, clientSideActions, eventEmitter, applyFormatting) { + async function processMessages( + instance, + session, + messages, + input, + clientSideActions, + eventEmitter, + applyFormatting, + ) { for (const message of messages) { if (message.type === 'text') { + console.log('message.content.richText', message.content.richText); let formattedText = ''; for (const richText of message.content.richText) { @@ -444,60 +435,43 @@ export class TypebotService { formattedText = formattedText.replace(/\*\*/g, '').replace(/__/, '').replace(/~~/, '').replace(/\n$/, ''); + formattedText = formattedText.replace(/\n$/, ''); + await instance.textMessage({ number: remoteJid.split('@')[0], - options: { - delay: instance.localTypebot.delayMessage || 1000, - presence: 'composing', - }, - textMessage: { - text: formattedText, - }, + delay: instance.localTypebot.delayMessage || 1000, + text: formattedText, }); } if (message.type === 'image') { await instance.mediaMessage({ number: remoteJid.split('@')[0], - options: { - delay: instance.localTypebot.delayMessage || 1000, - presence: 'composing', - }, - mediaMessage: { - mediatype: 'image', - media: message.content.url, - }, + delay: instance.localTypebot.delayMessage || 1000, + mediatype: 'image', + media: message.content.url, }); } if (message.type === 'video') { await instance.mediaMessage({ number: remoteJid.split('@')[0], - options: { - delay: instance.localTypebot.delayMessage || 1000, - presence: 'composing', - }, - mediaMessage: { - mediatype: 'video', - media: message.content.url, - }, + delay: instance.localTypebot.delayMessage || 1000, + mediatype: 'video', + media: message.content.url, }); } if (message.type === 'audio') { await instance.audioWhatsapp({ number: remoteJid.split('@')[0], - options: { - delay: instance.localTypebot.delayMessage || 1000, - presence: 'recording', - encoding: true, - }, - audioMessage: { - audio: message.content.url, - }, + delay: instance.localTypebot.delayMessage || 1000, + encoding: true, + audio: message.content.url, }); } + console.log(clientSideActions); const wait = findItemAndGetSecondsToWait(clientSideActions, message.id); if (wait) { @@ -519,19 +493,13 @@ export class TypebotService { await instance.textMessage({ number: remoteJid.split('@')[0], - options: { - delay: instance.localTypebot.delayMessage || 1000, - presence: 'composing', - }, - textMessage: { - text: formattedText, - }, + delay: instance.localTypebot.delayMessage || 1000, + text: formattedText, }); } } else { eventEmitter.emit('typebot:end', { - instance: instance, - remoteJid: remoteJid, + sessionId: session.id, }); } } @@ -541,14 +509,18 @@ export class TypebotService { const findTypebot = await this.find(instance); const url = findTypebot.typebot?.url; const typebot = findTypebot.typebot?.typebot; - const sessions = findTypebot.sessions; const expire = findTypebot.typebot?.expire; const keywordFinish = findTypebot.typebot?.keywordFinish; const delayMessage = findTypebot.typebot?.delayMessage; const unknownMessage = findTypebot.typebot?.unknownMessage; const listeningFromMe = findTypebot.typebot?.listeningFromMe; - const session = sessions.find((session) => session.remoteJid === remoteJid); + let session = await this.prismaRepository.typebotSession.findFirst({ + where: { + typebotId: findTypebot.typebot.id, + remoteJid: remoteJid, + }, + }); try { if (session && expire && expire > 0) { @@ -582,7 +554,11 @@ export class TypebotService { typebotId: findTypebot.typebot.id, }); - await this.sendWAMessage(instance, remoteJid, data.messages, data.input, data.clientSideActions); + if (data.session) { + session = data.session; + } + + await this.sendWAMessage(instance, session, remoteJid, data.messages, data.input, data.clientSideActions); if (data.messages.length === 0) { const content = this.getConversationMessage(msg.message); @@ -629,6 +605,7 @@ export class TypebotService { await this.sendWAMessage( instance, + session, remoteJid, request.data.messages, request.data.input, @@ -663,7 +640,11 @@ export class TypebotService { typebotId: findTypebot.typebot.id, }); - await this.sendWAMessage(instance, remoteJid, data?.messages, data?.input, data?.clientSideActions); + if (data.session) { + session = data.session; + } + + await this.sendWAMessage(instance, session, remoteJid, data?.messages, data?.input, data?.clientSideActions); if (data.messages.length === 0) { const content = this.getConversationMessage(msg.message); @@ -711,6 +692,7 @@ export class TypebotService { await this.sendWAMessage( instance, + session, remoteJid, request.data.messages, request.data.input, @@ -735,6 +717,8 @@ export class TypebotService { const content = this.getConversationMessage(msg.message); + console.log('content', content); + if (!content) { if (unknownMessage) { this.waMonitor.waInstances[instance.instanceName].textMessage({ @@ -771,14 +755,18 @@ export class TypebotService { sessionId: session.sessionId.split('-')[1], }; } + console.log('reqData', reqData); const request = await axios.post(urlTypebot, reqData); + console.log('request', request.data); + await this.sendWAMessage( instance, + session, remoteJid, - request.data.messages, - request.data.input, - request.data.clientSideActions, + request?.data?.messages, + request?.data?.input, + request?.data?.clientSideActions, ); return; diff --git a/src/api/services/channels/whatsapp.baileys.service.ts b/src/api/services/channels/whatsapp.baileys.service.ts index 2e414b18..0e7362b9 100644 --- a/src/api/services/channels/whatsapp.baileys.service.ts +++ b/src/api/services/channels/whatsapp.baileys.service.ts @@ -1312,7 +1312,6 @@ export class BaileysStartupService extends ChannelStartupService { fromMe: key.fromMe, participant: key?.remoteJid, status: 'DELETED', - dateTime: parseInt(new Date().getTime().toString()).toString(), instanceId: this.instanceId, }; @@ -1338,7 +1337,6 @@ export class BaileysStartupService extends ChannelStartupService { fromMe: key.fromMe, participant: key?.remoteJid, status: status[update.status], - dateTime: parseInt(new Date().getTime().toString()).toString(), pollUpdates, instanceId: this.instanceId, }; @@ -1778,6 +1776,8 @@ export class BaileysStartupService extends ChannelStartupService { } } + console.log('message', message); + const messageSent = await (async () => { const option = { quoted, @@ -1974,6 +1974,12 @@ export class BaileysStartupService extends ChannelStartupService { // Send Message Controller public async textMessage(data: SendTextDto, isChatwoot = false) { + const text = data.text; + + if (!text || text.trim().length === 0) { + throw new BadRequestException('Text is required'); + } + return await this.sendMessageWithTyping( data.number, { diff --git a/src/api/services/monitor.service.ts b/src/api/services/monitor.service.ts index 4136ca95..6cacc2f9 100644 --- a/src/api/services/monitor.service.ts +++ b/src/api/services/monitor.service.ts @@ -199,6 +199,8 @@ export class WAMonitoringService { if (!instance) this.logger.error('Instance not found'); + rmSync(join(INSTANCE_DIR, instance.id), { recursive: true, force: true }); + await this.prismaRepository.session.deleteMany({ where: { sessionId: instance.id } }); return; }