Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0

This commit is contained in:
Felipe Medeiros 2024-10-07 01:33:13 -03:00 committed by GitHub
commit 070840d364
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 70 additions and 55 deletions

View File

@ -1,4 +1,10 @@
# 2.1.2 (develop) # 2.1.3 (develop)
### Fixed
* Fixed prefilledVariables in startTypebot
# 2.1.2 (2024-10-06 10:09)
### Features ### Features

View File

@ -159,7 +159,7 @@ model Message {
MessageUpdate MessageUpdate[] MessageUpdate MessageUpdate[]
Media Media? Media Media?
webhookUrl String? @db.VarChar(500) webhookUrl String? @db.VarChar(500)
status Int? @db.Int status String? @db.VarChar(30)
sessionId String? sessionId String?
session IntegrationSession? @relation(fields: [sessionId], references: [id]) session IntegrationSession? @relation(fields: [sessionId], references: [id])

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Message" ALTER COLUMN "status" SET DATA TYPE VARCHAR(30);

View File

@ -158,7 +158,7 @@ model Message {
MessageUpdate MessageUpdate[] MessageUpdate MessageUpdate[]
Media Media? Media Media?
webhookUrl String? @db.VarChar(500) webhookUrl String? @db.VarChar(500)
status Int? @db.Integer status String? @db.VarChar(30)
sessionId String? sessionId String?
session IntegrationSession? @relation(fields: [sessionId], references: [id]) session IntegrationSession? @relation(fields: [sessionId], references: [id])

View File

@ -48,11 +48,14 @@ export class SendMessageController {
} }
public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto, file?: any) { public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto, file?: any) {
if (file || isURL(data.audio) || isBase64(data.audio)) { if (file?.buffer || isURL(data.audio) || isBase64(data.audio)) {
// Si file existe y tiene buffer, o si es una URL o Base64, continúa
return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data, file); return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data, file);
} else {
console.error('El archivo no tiene buffer o el audio no es una URL o Base64 válida');
throw new BadRequestException('Owned media must be a url, base64, or valid file with buffer');
} }
throw new BadRequestException('Owned media must be a url or base64'); }
}
public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) { public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) {
return await this.waMonitor.waInstances[instanceName].buttonMessage(data); return await this.waMonitor.waInstances[instanceName].buttonMessage(data);

View File

@ -7,6 +7,7 @@ import { ChannelStartupService } from '@api/services/channel.service';
import { Events, wa } from '@api/types/wa.types'; import { Events, wa } from '@api/types/wa.types';
import { Chatwoot, ConfigService, Openai } from '@config/env.config'; import { Chatwoot, ConfigService, Openai } from '@config/env.config';
import { BadRequestException, InternalServerErrorException } from '@exceptions'; import { BadRequestException, InternalServerErrorException } from '@exceptions';
import { status } from '@utils/renderStatus';
import { isURL } from 'class-validator'; import { isURL } from 'class-validator';
import EventEmitter2 from 'eventemitter2'; import EventEmitter2 from 'eventemitter2';
import mime from 'mime'; import mime from 'mime';
@ -273,72 +274,59 @@ export class EvolutionStartupService extends ChannelStartupService {
const messageId = v4(); const messageId = v4();
let messageRaw: any; let messageRaw: any = {
key: { fromMe: true, id: messageId, remoteJid: number },
messageTimestamp: Math.round(new Date().getTime() / 1000),
webhookUrl,
source: 'unknown',
instanceId: this.instanceId,
status: status[1],
};
if (message?.mediaType === 'image') { if (message?.mediaType === 'image') {
messageRaw = { messageRaw = {
key: { fromMe: true, id: messageId, remoteJid: number }, ...messageRaw,
message: { message: {
mediaUrl: message.media, mediaUrl: message.media,
quoted, quoted,
}, },
messageType: 'imageMessage', messageType: 'imageMessage',
messageTimestamp: Math.round(new Date().getTime() / 1000),
webhookUrl,
source: 'unknown',
instanceId: this.instanceId,
}; };
} else if (message?.mediaType === 'video') { } else if (message?.mediaType === 'video') {
messageRaw = { messageRaw = {
key: { fromMe: true, id: messageId, remoteJid: number }, ...messageRaw,
message: { message: {
mediaUrl: message.media, mediaUrl: message.media,
quoted, quoted,
}, },
messageType: 'videoMessage', messageType: 'videoMessage',
messageTimestamp: Math.round(new Date().getTime() / 1000),
webhookUrl,
source: 'unknown',
instanceId: this.instanceId,
}; };
} else if (message?.mediaType === 'audio') { } else if (message?.mediaType === 'audio') {
messageRaw = { messageRaw = {
key: { fromMe: true, id: messageId, remoteJid: number }, ...messageRaw,
message: { message: {
mediaUrl: message.media, mediaUrl: message.media,
quoted, quoted,
}, },
messageType: 'audioMessage', messageType: 'audioMessage',
messageTimestamp: Math.round(new Date().getTime() / 1000),
webhookUrl,
source: 'unknown',
instanceId: this.instanceId,
}; };
} else if (message?.mediaType === 'document') { } else if (message?.mediaType === 'document') {
messageRaw = { messageRaw = {
key: { fromMe: true, id: messageId, remoteJid: number }, ...messageRaw,
message: { message: {
mediaUrl: message.media, mediaUrl: message.media,
quoted, quoted,
}, },
messageType: 'documentMessage', messageType: 'documentMessage',
messageTimestamp: Math.round(new Date().getTime() / 1000),
webhookUrl,
source: 'unknown',
instanceId: this.instanceId,
}; };
} else { } else {
messageRaw = { messageRaw = {
key: { fromMe: true, id: messageId, remoteJid: number }, ...messageRaw,
message: { message: {
...message, ...message,
quoted, quoted,
}, },
messageType: 'conversation', messageType: 'conversation',
messageTimestamp: Math.round(new Date().getTime() / 1000),
webhookUrl,
source: 'unknown',
instanceId: this.instanceId,
}; };
} }
@ -483,7 +471,12 @@ export class EvolutionStartupService extends ChannelStartupService {
public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) { public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {
const mediaData: SendAudioDto = { ...data }; const mediaData: SendAudioDto = { ...data };
if (file) mediaData.audio = file.buffer.toString('base64'); if (file?.buffer) {
mediaData.audio = file.buffer.toString('base64');
} else {
console.error('El archivo o buffer no est<73> definido correctamente.');
throw new Error('File or buffer is undefined.');
}
const message = await this.processAudio(mediaData.audio, data.number); const message = await this.processAudio(mediaData.audio, data.number);

View File

@ -22,6 +22,7 @@ import { ChannelStartupService } from '@api/services/channel.service';
import { Events, wa } from '@api/types/wa.types'; import { Events, wa } from '@api/types/wa.types';
import { Chatwoot, ConfigService, Database, Openai, S3, WaBusiness } from '@config/env.config'; import { Chatwoot, ConfigService, Database, Openai, S3, WaBusiness } from '@config/env.config';
import { BadRequestException, InternalServerErrorException } from '@exceptions'; import { BadRequestException, InternalServerErrorException } from '@exceptions';
import { status } from '@utils/renderStatus';
import axios from 'axios'; import axios from 'axios';
import { arrayUnique, isURL } from 'class-validator'; import { arrayUnique, isURL } from 'class-validator';
import EventEmitter2 from 'eventemitter2'; import EventEmitter2 from 'eventemitter2';
@ -895,12 +896,12 @@ export class BusinessStartupService extends ChannelStartupService {
const messageRaw: any = { const messageRaw: any = {
key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: this.createJid(number) }, key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: this.createJid(number) },
//pushName: messageSent.pushName,
message: this.convertMessageToRaw(message, content), message: this.convertMessageToRaw(message, content),
messageType: this.renderMessageType(content.type), messageType: this.renderMessageType(content.type),
messageTimestamp: (messageSent?.messages[0]?.timestamp as number) || Math.round(new Date().getTime() / 1000), messageTimestamp: (messageSent?.messages[0]?.timestamp as number) || Math.round(new Date().getTime() / 1000),
instanceId: this.instanceId, instanceId: this.instanceId,
webhookUrl, webhookUrl,
status: status[1],
source: 'unknown', source: 'unknown',
}; };
@ -1081,7 +1082,12 @@ export class BusinessStartupService extends ChannelStartupService {
public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) { public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {
const mediaData: SendAudioDto = { ...data }; const mediaData: SendAudioDto = { ...data };
if (file) mediaData.audio = file.buffer.toString('base64'); if (file?.buffer) {
mediaData.audio = file.buffer.toString('base64');
} else {
console.error('El archivo no tiene buffer o file es undefined');
throw new Error('File or buffer is undefined');
}
const message = await this.processAudio(mediaData.audio, data.number); const message = await this.processAudio(mediaData.audio, data.number);

View File

@ -73,6 +73,7 @@ import { Boom } from '@hapi/boom';
import { Instance } from '@prisma/client'; import { Instance } from '@prisma/client';
import { makeProxyAgent } from '@utils/makeProxyAgent'; import { makeProxyAgent } from '@utils/makeProxyAgent';
import { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache'; import { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache';
import { status } from '@utils/renderStatus';
import useMultiFileAuthStatePrisma from '@utils/use-multi-file-auth-state-prisma'; import useMultiFileAuthStatePrisma from '@utils/use-multi-file-auth-state-prisma';
import { AuthStateProvider } from '@utils/use-multi-file-auth-state-provider-files'; import { AuthStateProvider } from '@utils/use-multi-file-auth-state-provider-files';
import { useMultiFileAuthStateRedisDb } from '@utils/use-multi-file-auth-state-redis-db'; import { useMultiFileAuthStateRedisDb } from '@utils/use-multi-file-auth-state-redis-db';
@ -570,7 +571,6 @@ export class BaileysStartupService extends ChannelStartupService {
const isGroupJid = this.localSettings.groupsIgnore && isJidGroup(jid); const isGroupJid = this.localSettings.groupsIgnore && isJidGroup(jid);
const isBroadcast = !this.localSettings.readStatus && isJidBroadcast(jid); const isBroadcast = !this.localSettings.readStatus && isJidBroadcast(jid);
const isNewsletter = isJidNewsletter(jid); const isNewsletter = isJidNewsletter(jid);
// const isNewsletter = jid && jid.includes('newsletter');
return isGroupJid || isBroadcast || isNewsletter; return isGroupJid || isBroadcast || isNewsletter;
}, },
@ -1231,14 +1231,6 @@ export class BaileysStartupService extends ChannelStartupService {
}, },
'messages.update': async (args: WAMessageUpdate[], settings: any) => { 'messages.update': async (args: WAMessageUpdate[], settings: any) => {
const status: Record<number, wa.StatusMessage> = {
0: 'ERROR',
1: 'PENDING',
2: 'SERVER_ACK',
3: 'DELIVERY_ACK',
4: 'READ',
5: 'PLAYED',
};
for await (const { key, update } of args) { for await (const { key, update } of args) {
if (settings?.groupsIgnore && key.remoteJid?.includes('@g.us')) { if (settings?.groupsIgnore && key.remoteJid?.includes('@g.us')) {
return; return;
@ -2590,7 +2582,12 @@ export class BaileysStartupService extends ChannelStartupService {
public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) { public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {
const mediaData: SendAudioDto = { ...data }; const mediaData: SendAudioDto = { ...data };
if (file) mediaData.audio = file.buffer.toString('base64'); if (file?.buffer) {
mediaData.audio = file.buffer.toString('base64');
} else if (!isURL(data.audio) && !isBase64(data.audio)) {
console.error('Invalid file or audio source');
throw new BadRequestException('File buffer, URL, or base64 audio is required');
}
if (!data?.encoding && data?.encoding !== false) { if (!data?.encoding && data?.encoding !== false) {
data.encoding = true; data.encoding = true;
@ -3670,7 +3667,7 @@ export class BaileysStartupService extends ChannelStartupService {
const messageRaw = { const messageRaw = {
key: message.key, key: message.key,
pushName: message.pushName, pushName: message.pushName,
status: message.status, status: status[message.status],
message: { ...message.message }, message: { ...message.message },
contextInfo: contentMsg?.contextInfo, contextInfo: contentMsg?.contextInfo,
messageType: contentType || 'unknown', messageType: contentType || 'unknown',

View File

@ -5,7 +5,7 @@ import { TypebotService } from '@api/integrations/chatbot/typebot/services/typeb
import { PrismaRepository } from '@api/repository/repository.service'; import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service'; import { WAMonitoringService } from '@api/services/monitor.service';
import { Events } from '@api/types/wa.types'; import { Events } from '@api/types/wa.types';
import { Auth, configService, HttpServer, Typebot } from '@config/env.config'; import { configService, Typebot } from '@config/env.config';
import { Logger } from '@config/logger.config'; import { Logger } from '@config/logger.config';
import { BadRequestException } from '@exceptions'; import { BadRequestException } from '@exceptions';
import { Typebot as TypebotModel } from '@prisma/client'; import { Typebot as TypebotModel } from '@prisma/client';
@ -609,13 +609,7 @@ export class TypebotController extends ChatbotController implements ChatbotContr
} }
} }
const prefilledVariables = { const prefilledVariables: any = {};
remoteJid: remoteJid,
instanceName: instance.instanceName,
serverUrl: configService.get<HttpServer>('SERVER').URL,
apiKey: configService.get<Auth>('AUTHENTICATION').API_KEY.KEY,
ownerJid: instanceData.number,
};
if (variables?.length) { if (variables?.length) {
variables.forEach((variable: { name: string | number; value: string }) => { variables.forEach((variable: { name: string | number; value: string }) => {
@ -674,6 +668,7 @@ export class TypebotController extends ChatbotController implements ChatbotContr
stopBotFromMe, stopBotFromMe,
keepOpen, keepOpen,
'init', 'init',
prefilledVariables,
); );
// const response = await this.typebotService.createNewSession(instanceData, { // const response = await this.typebotService.createNewSession(instanceData, {

View File

@ -356,6 +356,7 @@ export class TypebotService {
stopBotFromMe: boolean, stopBotFromMe: boolean,
keepOpen: boolean, keepOpen: boolean,
content: string, content: string,
prefilledVariables?: any,
) { ) {
if (session && expire && expire > 0) { if (session && expire && expire > 0) {
const now = Date.now(); const now = Date.now();
@ -397,6 +398,7 @@ export class TypebotService {
remoteJid: remoteJid, remoteJid: remoteJid,
pushName: msg.pushName, pushName: msg.pushName,
botId: findTypebot.id, botId: findTypebot.id,
prefilledVariables: prefilledVariables,
}); });
if (data.session) { if (data.session) {
@ -524,6 +526,7 @@ export class TypebotService {
remoteJid: remoteJid, remoteJid: remoteJid,
pushName: msg?.pushName, pushName: msg?.pushName,
botId: findTypebot.id, botId: findTypebot.id,
prefilledVariables: prefilledVariables,
}); });
if (data?.session) { if (data?.session) {

10
src/utils/renderStatus.ts Normal file
View File

@ -0,0 +1,10 @@
import { wa } from '@api/types/wa.types';
export const status: Record<number, wa.StatusMessage> = {
0: 'ERROR',
1: 'PENDING',
2: 'SERVER_ACK',
3: 'DELIVERY_ACK',
4: 'READ',
5: 'PLAYED',
};