mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-14 01:41:24 -06:00
Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0
This commit is contained in:
commit
070840d364
@ -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
|
||||||
|
|
||||||
|
@ -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])
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Message" ALTER COLUMN "status" SET DATA TYPE VARCHAR(30);
|
@ -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])
|
||||||
|
@ -48,10 +48,13 @@ 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) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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',
|
||||||
|
@ -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, {
|
||||||
|
@ -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
10
src/utils/renderStatus.ts
Normal 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',
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user