mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-20 04:12:23 -06:00
feat: send media with form-data
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user