feat: send media with form-data

This commit is contained in:
Davidson Gomes
2024-10-04 14:45:16 -03:00
parent 44e152bea2
commit ec2d7e349f
12 changed files with 197 additions and 48 deletions

View File

@@ -7,6 +7,7 @@ import { ChannelStartupService } from '@api/services/channel.service';
import { Events, wa } from '@api/types/wa.types';
import { Chatwoot, ConfigService, Openai } from '@config/env.config';
import { BadRequestException, InternalServerErrorException } from '@exceptions';
import { deleteTempFile, getTempFile } from '@utils/getTempFile';
import { isURL } from 'class-validator';
import EventEmitter2 from 'eventemitter2';
import mime from 'mime';
@@ -164,7 +165,7 @@ export class EvolutionStartupService extends ChannelStartupService {
await this.updateContact({
remoteJid: messageRaw.key.remoteJid,
pushName: messageRaw.key.fromMe ? '' : (messageRaw.key.fromMe == null ? '' : received.pushName),
pushName: messageRaw.key.fromMe ? '' : messageRaw.key.fromMe == null ? '' : received.pushName,
profilePicUrl: received.profilePicUrl,
});
}
@@ -433,11 +434,14 @@ export class EvolutionStartupService extends ChannelStartupService {
}
}
public async mediaMessage(data: SendMediaDto, isIntegration = false) {
const message = await this.prepareMediaMessage(data);
public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {
const mediaData: SendMediaDto = { ...data };
console.log('message', message);
return await this.sendMessageWithTyping(
if (file) mediaData.media = await getTempFile(file, this.instanceId);
const message = await this.prepareMediaMessage(mediaData);
const mediaSent = await this.sendMessageWithTyping(
data.number,
{ ...message },
{
@@ -450,6 +454,10 @@ export class EvolutionStartupService extends ChannelStartupService {
},
isIntegration,
);
if (file) await deleteTempFile(file, this.instanceId);
return mediaSent;
}
public async processAudio(audio: string, number: string) {
@@ -475,10 +483,14 @@ export class EvolutionStartupService extends ChannelStartupService {
return prepareMedia;
}
public async audioWhatsapp(data: SendAudioDto, isIntegration = false) {
const message = await this.processAudio(data.audio, data.number);
public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {
const mediaData: SendAudioDto = { ...data };
return await this.sendMessageWithTyping(
if (file) mediaData.audio = await getTempFile(file, this.instanceId);
const message = await this.processAudio(mediaData.audio, data.number);
const audioSent = await this.sendMessageWithTyping(
data.number,
{ ...message },
{
@@ -491,6 +503,10 @@ export class EvolutionStartupService extends ChannelStartupService {
},
isIntegration,
);
if (file) await deleteTempFile(file, this.instanceId);
return audioSent;
}
public async buttonMessage() {

View File

@@ -22,6 +22,7 @@ import { ChannelStartupService } from '@api/services/channel.service';
import { Events, wa } from '@api/types/wa.types';
import { Chatwoot, ConfigService, Database, Openai, S3, WaBusiness } from '@config/env.config';
import { BadRequestException, InternalServerErrorException } from '@exceptions';
import { deleteTempFile, getTempFile } from '@utils/getTempFile';
import axios from 'axios';
import { arrayUnique, isURL } from 'class-validator';
import EventEmitter2 from 'eventemitter2';
@@ -1026,10 +1027,14 @@ export class BusinessStartupService extends ChannelStartupService {
}
}
public async mediaMessage(data: SendMediaDto, isIntegration = false) {
const message = await this.prepareMediaMessage(data);
public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {
const mediaData: SendMediaDto = { ...data };
return await this.sendMessageWithTyping(
if (file) mediaData.media = await getTempFile(file, this.instanceId);
const message = await this.prepareMediaMessage(mediaData);
const mediaSent = await this.sendMessageWithTyping(
data.number,
{ ...message },
{
@@ -1042,6 +1047,10 @@ export class BusinessStartupService extends ChannelStartupService {
},
isIntegration,
);
if (file) await deleteTempFile(file, this.instanceId);
return mediaSent;
}
public async processAudio(audio: string, number: string) {
@@ -1072,10 +1081,14 @@ export class BusinessStartupService extends ChannelStartupService {
return prepareMedia;
}
public async audioWhatsapp(data: SendAudioDto, isIntegration = false) {
const message = await this.processAudio(data.audio, data.number);
public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {
const mediaData: SendAudioDto = { ...data };
return await this.sendMessageWithTyping(
if (file) mediaData.audio = await getTempFile(file, this.instanceId);
const message = await this.processAudio(mediaData.audio, data.number);
const audioSent = await this.sendMessageWithTyping(
data.number,
{ ...message },
{
@@ -1088,6 +1101,10 @@ export class BusinessStartupService extends ChannelStartupService {
},
isIntegration,
);
if (file) await deleteTempFile(file, this.instanceId);
return audioSent;
}
public async buttonMessage(data: SendButtonDto) {

View File

@@ -70,6 +70,7 @@ import { BadRequestException, InternalServerErrorException, NotFoundException }
import ffmpegPath from '@ffmpeg-installer/ffmpeg';
import { Boom } from '@hapi/boom';
import { Instance } from '@prisma/client';
import { deleteTempFile, getTempFile } from '@utils/getTempFile';
import { makeProxyAgent } from '@utils/makeProxyAgent';
import { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache';
import useMultiFileAuthStatePrisma from '@utils/use-multi-file-auth-state-prisma';
@@ -2266,12 +2267,20 @@ export class BaileysStartupService extends ChannelStartupService {
throw new BadRequestException('Type not found');
}
public async statusMessage(data: SendStatusDto) {
const status = await this.formatStatusMessage(data);
public async statusMessage(data: SendStatusDto, file?: any) {
const mediaData: SendStatusDto = { ...data };
return await this.sendMessageWithTyping('status@broadcast', {
if (file) mediaData.content = await getTempFile(file, this.instanceId);
const status = await this.formatStatusMessage(mediaData);
const statusSent = await this.sendMessageWithTyping('status@broadcast', {
status,
});
if (file) await deleteTempFile(file, this.instanceId);
return statusSent;
}
private async prepareMediaMessage(mediaMessage: MediaMessage) {
@@ -2395,7 +2404,11 @@ export class BaileysStartupService extends ChannelStartupService {
}
}
public async mediaSticker(data: SendStickerDto) {
public async mediaSticker(data: SendStickerDto, file?: any) {
const mediaData: SendStickerDto = { ...data };
if (file) mediaData.sticker = await getTempFile(file, this.instanceId);
const convert = await this.convertToWebP(data.sticker);
const gifPlayback = data.sticker.includes('.gif');
const result = await this.sendMessageWithTyping(
@@ -2413,13 +2426,19 @@ export class BaileysStartupService extends ChannelStartupService {
},
);
if (file) await deleteTempFile(file, this.instanceId);
return result;
}
public async mediaMessage(data: SendMediaDto, isIntegration = false) {
const generate = await this.prepareMediaMessage(data);
public async mediaMessage(data: SendMediaDto, file?: any, isIntegration = false) {
const mediaData: SendMediaDto = { ...data };
return await this.sendMessageWithTyping(
if (file) mediaData.media = await getTempFile(file, this.instanceId);
const generate = await this.prepareMediaMessage(mediaData);
const mediaSent = await this.sendMessageWithTyping(
data.number,
{ ...generate.message },
{
@@ -2431,6 +2450,10 @@ export class BaileysStartupService extends ChannelStartupService {
},
isIntegration,
);
if (file) await deleteTempFile(file, this.instanceId);
return mediaSent;
}
public async processAudioMp4(audio: string) {
@@ -2534,13 +2557,17 @@ export class BaileysStartupService extends ChannelStartupService {
});
}
public async audioWhatsapp(data: SendAudioDto, isIntegration = false) {
public async audioWhatsapp(data: SendAudioDto, file?: any, isIntegration = false) {
const mediaData: SendAudioDto = { ...data };
if (file) mediaData.audio = await getTempFile(file, this.instanceId);
if (!data?.encoding && data?.encoding !== false) {
data.encoding = true;
}
if (data?.encoding) {
const convert = await this.processAudio(data.audio);
const convert = await this.processAudio(mediaData.audio);
if (Buffer.isBuffer(convert)) {
const result = this.sendMessageWithTyping<AnyMessageContent>(
@@ -2554,6 +2581,8 @@ export class BaileysStartupService extends ChannelStartupService {
isIntegration,
);
if (file) await deleteTempFile(file, this.instanceId);
return result;
} else {
throw new InternalServerErrorException('Failed to convert audio');

View File

@@ -105,4 +105,35 @@ const getObjectUrl = async (fileName: string, expiry?: number) => {
}
};
export { BUCKET, getObjectUrl, uploadFile };
const uploadTempFile = async (
folder: string,
fileName: string,
file: Buffer | Transform | Readable,
size: number,
metadata: Metadata,
) => {
if (minioClient) {
const objectName = join(folder, fileName);
try {
metadata['custom-header-application'] = 'evolution-api';
return await minioClient.putObject(bucketName, objectName, file, size, metadata);
} catch (error) {
logger.error(error);
return error;
}
}
};
const deleteFile = async (folder: string, fileName: string) => {
if (minioClient) {
const objectName = join(folder, fileName);
try {
return await minioClient.removeObject(bucketName, objectName);
} catch (error) {
logger.error(error);
return error;
}
}
};
export { BUCKET, deleteFile, getObjectUrl, uploadFile, uploadTempFile };