mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-27 15:47:45 -06:00
Merge branch 'develop' into feat/add-async-lock
This commit is contained in:
@@ -455,39 +455,46 @@ export class EvolutionStartupService extends ChannelStartupService {
|
||||
if (base64 || file || audioFile) {
|
||||
if (this.configService.get<S3>('S3').ENABLE) {
|
||||
try {
|
||||
const fileBuffer = audioFile?.buffer || file?.buffer;
|
||||
const buffer = base64 ? Buffer.from(base64, 'base64') : fileBuffer;
|
||||
// Verificação adicional para garantir que há conteúdo de mídia real
|
||||
const hasRealMedia = this.hasValidMediaContent(messageRaw);
|
||||
|
||||
let mediaType: string;
|
||||
let mimetype = audioFile?.mimetype || file.mimetype;
|
||||
if (!hasRealMedia) {
|
||||
this.logger.warn('Message detected as media but contains no valid media content');
|
||||
} else {
|
||||
const fileBuffer = audioFile?.buffer || file?.buffer;
|
||||
const buffer = base64 ? Buffer.from(base64, 'base64') : fileBuffer;
|
||||
|
||||
if (messageRaw.messageType === 'documentMessage') {
|
||||
mediaType = 'document';
|
||||
mimetype = !mimetype ? 'application/pdf' : mimetype;
|
||||
} else if (messageRaw.messageType === 'imageMessage') {
|
||||
mediaType = 'image';
|
||||
mimetype = !mimetype ? 'image/png' : mimetype;
|
||||
} else if (messageRaw.messageType === 'audioMessage') {
|
||||
mediaType = 'audio';
|
||||
mimetype = !mimetype ? 'audio/mp4' : mimetype;
|
||||
} else if (messageRaw.messageType === 'videoMessage') {
|
||||
mediaType = 'video';
|
||||
mimetype = !mimetype ? 'video/mp4' : mimetype;
|
||||
let mediaType: string;
|
||||
let mimetype = audioFile?.mimetype || file.mimetype;
|
||||
|
||||
if (messageRaw.messageType === 'documentMessage') {
|
||||
mediaType = 'document';
|
||||
mimetype = !mimetype ? 'application/pdf' : mimetype;
|
||||
} else if (messageRaw.messageType === 'imageMessage') {
|
||||
mediaType = 'image';
|
||||
mimetype = !mimetype ? 'image/png' : mimetype;
|
||||
} else if (messageRaw.messageType === 'audioMessage') {
|
||||
mediaType = 'audio';
|
||||
mimetype = !mimetype ? 'audio/mp4' : mimetype;
|
||||
} else if (messageRaw.messageType === 'videoMessage') {
|
||||
mediaType = 'video';
|
||||
mimetype = !mimetype ? 'video/mp4' : mimetype;
|
||||
}
|
||||
|
||||
const fileName = `${messageRaw.key.id}.${mimetype.split('/')[1]}`;
|
||||
|
||||
const size = buffer.byteLength;
|
||||
|
||||
const fullName = join(`${this.instance.id}`, messageRaw.key.remoteJid, mediaType, fileName);
|
||||
|
||||
await s3Service.uploadFile(fullName, buffer, size, {
|
||||
'Content-Type': mimetype,
|
||||
});
|
||||
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
}
|
||||
|
||||
const fileName = `${messageRaw.key.id}.${mimetype.split('/')[1]}`;
|
||||
|
||||
const size = buffer.byteLength;
|
||||
|
||||
const fullName = join(`${this.instance.id}`, messageRaw.key.remoteJid, mediaType, fileName);
|
||||
|
||||
await s3Service.uploadFile(fullName, buffer, size, {
|
||||
'Content-Type': mimetype,
|
||||
});
|
||||
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
} catch (error) {
|
||||
this.logger.error(['Error on upload file to minio', error?.message, error?.stack]);
|
||||
}
|
||||
|
||||
@@ -429,107 +429,114 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
try {
|
||||
const message: any = received;
|
||||
|
||||
const id = message.messages[0][message.messages[0].type].id;
|
||||
let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;
|
||||
const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;
|
||||
urlServer = `${urlServer}/${version}/${id}`;
|
||||
const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };
|
||||
const result = await axios.get(urlServer, { headers });
|
||||
// Verificação adicional para garantir que há conteúdo de mídia real
|
||||
const hasRealMedia = this.hasValidMediaContent(messageRaw);
|
||||
|
||||
const buffer = await axios.get(result.data.url, {
|
||||
headers: { Authorization: `Bearer ${this.token}` }, // Use apenas o token de autorização para download
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
|
||||
let mediaType;
|
||||
|
||||
if (message.messages[0].document) {
|
||||
mediaType = 'document';
|
||||
} else if (message.messages[0].image) {
|
||||
mediaType = 'image';
|
||||
} else if (message.messages[0].audio) {
|
||||
mediaType = 'audio';
|
||||
if (!hasRealMedia) {
|
||||
this.logger.warn('Message detected as media but contains no valid media content');
|
||||
} else {
|
||||
mediaType = 'video';
|
||||
}
|
||||
const id = message.messages[0][message.messages[0].type].id;
|
||||
let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;
|
||||
const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;
|
||||
urlServer = `${urlServer}/${version}/${id}`;
|
||||
const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };
|
||||
const result = await axios.get(urlServer, { headers });
|
||||
|
||||
const mimetype = result.data?.mime_type || result.headers['content-type'];
|
||||
const buffer = await axios.get(result.data.url, {
|
||||
headers: { Authorization: `Bearer ${this.token}` }, // Use apenas o token de autorização para download
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
|
||||
const contentDisposition = result.headers['content-disposition'];
|
||||
let fileName = `${message.messages[0].id}.${mimetype.split('/')[1]}`;
|
||||
if (contentDisposition) {
|
||||
const match = contentDisposition.match(/filename="(.+?)"/);
|
||||
if (match) {
|
||||
fileName = match[1];
|
||||
let mediaType;
|
||||
|
||||
if (message.messages[0].document) {
|
||||
mediaType = 'document';
|
||||
} else if (message.messages[0].image) {
|
||||
mediaType = 'image';
|
||||
} else if (message.messages[0].audio) {
|
||||
mediaType = 'audio';
|
||||
} else {
|
||||
mediaType = 'video';
|
||||
}
|
||||
}
|
||||
|
||||
// Para áudio, garantir extensão correta baseada no mimetype
|
||||
if (mediaType === 'audio') {
|
||||
if (mimetype.includes('ogg')) {
|
||||
fileName = `${message.messages[0].id}.ogg`;
|
||||
} else if (mimetype.includes('mp3')) {
|
||||
fileName = `${message.messages[0].id}.mp3`;
|
||||
} else if (mimetype.includes('m4a')) {
|
||||
fileName = `${message.messages[0].id}.m4a`;
|
||||
const mimetype = result.data?.mime_type || result.headers['content-type'];
|
||||
|
||||
const contentDisposition = result.headers['content-disposition'];
|
||||
let fileName = `${message.messages[0].id}.${mimetype.split('/')[1]}`;
|
||||
if (contentDisposition) {
|
||||
const match = contentDisposition.match(/filename="(.+?)"/);
|
||||
if (match) {
|
||||
fileName = match[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const size = result.headers['content-length'] || buffer.data.byteLength;
|
||||
// Para áudio, garantir extensão correta baseada no mimetype
|
||||
if (mediaType === 'audio') {
|
||||
if (mimetype.includes('ogg')) {
|
||||
fileName = `${message.messages[0].id}.ogg`;
|
||||
} else if (mimetype.includes('mp3')) {
|
||||
fileName = `${message.messages[0].id}.mp3`;
|
||||
} else if (mimetype.includes('m4a')) {
|
||||
fileName = `${message.messages[0].id}.m4a`;
|
||||
}
|
||||
}
|
||||
|
||||
const fullName = join(`${this.instance.id}`, key.remoteJid, mediaType, fileName);
|
||||
const size = result.headers['content-length'] || buffer.data.byteLength;
|
||||
|
||||
await s3Service.uploadFile(fullName, buffer.data, size, {
|
||||
'Content-Type': mimetype,
|
||||
});
|
||||
const fullName = join(`${this.instance.id}`, key.remoteJid, mediaType, fileName);
|
||||
|
||||
const createdMessage = await this.prismaRepository.message.create({
|
||||
data: messageRaw,
|
||||
});
|
||||
await s3Service.uploadFile(fullName, buffer.data, size, {
|
||||
'Content-Type': mimetype,
|
||||
});
|
||||
|
||||
await this.prismaRepository.media.create({
|
||||
data: {
|
||||
messageId: createdMessage.id,
|
||||
instanceId: this.instanceId,
|
||||
type: mediaType,
|
||||
fileName: fullName,
|
||||
mimetype,
|
||||
},
|
||||
});
|
||||
const createdMessage = await this.prismaRepository.message.create({
|
||||
data: messageRaw,
|
||||
});
|
||||
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
messageRaw.message.base64 = buffer.data.toString('base64');
|
||||
|
||||
// Processar OpenAI speech-to-text para áudio após o mediaUrl estar disponível
|
||||
if (this.configService.get<Openai>('OPENAI').ENABLED && mediaType === 'audio') {
|
||||
const openAiDefaultSettings = await this.prismaRepository.openaiSetting.findFirst({
|
||||
where: {
|
||||
await this.prismaRepository.media.create({
|
||||
data: {
|
||||
messageId: createdMessage.id,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
include: {
|
||||
OpenaiCreds: true,
|
||||
type: mediaType,
|
||||
fileName: fullName,
|
||||
mimetype,
|
||||
},
|
||||
});
|
||||
|
||||
if (
|
||||
openAiDefaultSettings &&
|
||||
openAiDefaultSettings.openaiCredsId &&
|
||||
openAiDefaultSettings.speechToText
|
||||
) {
|
||||
try {
|
||||
messageRaw.message.speechToText = `[audio] ${await this.openaiService.speechToText(
|
||||
openAiDefaultSettings.OpenaiCreds,
|
||||
{
|
||||
message: {
|
||||
mediaUrl: messageRaw.message.mediaUrl,
|
||||
...messageRaw,
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
messageRaw.message.base64 = buffer.data.toString('base64');
|
||||
|
||||
// Processar OpenAI speech-to-text para áudio após o mediaUrl estar disponível
|
||||
if (this.configService.get<Openai>('OPENAI').ENABLED && mediaType === 'audio') {
|
||||
const openAiDefaultSettings = await this.prismaRepository.openaiSetting.findFirst({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
include: {
|
||||
OpenaiCreds: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (
|
||||
openAiDefaultSettings &&
|
||||
openAiDefaultSettings.openaiCredsId &&
|
||||
openAiDefaultSettings.speechToText
|
||||
) {
|
||||
try {
|
||||
messageRaw.message.speechToText = `[audio] ${await this.openaiService.speechToText(
|
||||
openAiDefaultSettings.OpenaiCreds,
|
||||
{
|
||||
message: {
|
||||
mediaUrl: messageRaw.message.mediaUrl,
|
||||
...messageRaw,
|
||||
},
|
||||
},
|
||||
},
|
||||
)}`;
|
||||
} catch (speechError) {
|
||||
this.logger.error(`Error processing speech-to-text: ${speechError}`);
|
||||
)}`;
|
||||
} catch (speechError) {
|
||||
this.logger.error(`Error processing speech-to-text: ${speechError}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ import makeWASocket, {
|
||||
Contact,
|
||||
delay,
|
||||
DisconnectReason,
|
||||
downloadContentFromMessage,
|
||||
downloadMediaMessage,
|
||||
generateWAMessageFromContent,
|
||||
getAggregateVotesInPollMessage,
|
||||
@@ -122,7 +123,7 @@ import makeWASocket, {
|
||||
WABrowserDescription,
|
||||
WAMediaUpload,
|
||||
WAMessage,
|
||||
WAMessageUpdate,
|
||||
WAMessageKey,
|
||||
WAPresence,
|
||||
WASocket,
|
||||
} from 'baileys';
|
||||
@@ -894,7 +895,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
}: {
|
||||
chats: Chat[];
|
||||
contacts: Contact[];
|
||||
messages: proto.IWebMessageInfo[];
|
||||
messages: WAMessage[];
|
||||
isLatest?: boolean;
|
||||
progress?: number;
|
||||
syncType?: proto.HistorySync.HistorySyncType;
|
||||
@@ -980,6 +981,10 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m.key.remoteJid?.includes('@lid') && m.key.senderPn) {
|
||||
m.key.remoteJid = m.key.senderPn;
|
||||
}
|
||||
|
||||
if (Long.isLong(m?.messageTimestamp)) {
|
||||
m.messageTimestamp = m.messageTimestamp?.toNumber();
|
||||
}
|
||||
@@ -1037,11 +1042,29 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
},
|
||||
|
||||
'messages.upsert': async (
|
||||
{ messages, type, requestId }: { messages: proto.IWebMessageInfo[]; type: MessageUpsertType; requestId?: string },
|
||||
{ messages, type, requestId }: { messages: WAMessage[]; type: MessageUpsertType; requestId?: string },
|
||||
settings: any,
|
||||
) => {
|
||||
try {
|
||||
for (const received of messages) {
|
||||
if (received.key.remoteJid?.includes('@lid') && received.key.senderPn) {
|
||||
(received.key as { previousRemoteJid?: string | null }).previousRemoteJid = received.key.remoteJid;
|
||||
received.key.remoteJid = received.key.senderPn;
|
||||
}
|
||||
if (
|
||||
received?.messageStubParameters?.some?.((param) =>
|
||||
[
|
||||
'No matching sessions found for message',
|
||||
'Bad MAC',
|
||||
'failed to decrypt message',
|
||||
'SessionError',
|
||||
'Invalid PreKey ID',
|
||||
].some((err) => param?.includes?.(err)),
|
||||
)
|
||||
) {
|
||||
this.logger.warn(`Message ignored with messageStubParameters: ${JSON.stringify(received, null, 2)}`);
|
||||
continue;
|
||||
}
|
||||
if (received.message?.conversation || received.message?.extendedTextMessage?.text) {
|
||||
const text = received.message?.conversation || received.message?.extendedTextMessage?.text;
|
||||
|
||||
@@ -1233,33 +1256,41 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
if (this.configService.get<S3>('S3').ENABLE) {
|
||||
try {
|
||||
const message: any = received;
|
||||
const media = await this.getBase64FromMediaMessage({ message }, true);
|
||||
|
||||
const { buffer, mediaType, fileName, size } = media;
|
||||
const mimetype = mimeTypes.lookup(fileName).toString();
|
||||
const fullName = join(
|
||||
`${this.instance.id}`,
|
||||
received.key.remoteJid,
|
||||
mediaType,
|
||||
`${Date.now()}_${fileName}`,
|
||||
);
|
||||
await s3Service.uploadFile(fullName, buffer, size.fileLength?.low, { 'Content-Type': mimetype });
|
||||
// Verificação adicional para garantir que há conteúdo de mídia real
|
||||
const hasRealMedia = this.hasValidMediaContent(message);
|
||||
|
||||
await this.prismaRepository.media.create({
|
||||
data: {
|
||||
messageId: msg.id,
|
||||
instanceId: this.instanceId,
|
||||
type: mediaType,
|
||||
fileName: fullName,
|
||||
mimetype,
|
||||
},
|
||||
});
|
||||
if (!hasRealMedia) {
|
||||
this.logger.warn('Message detected as media but contains no valid media content');
|
||||
} else {
|
||||
const media = await this.getBase64FromMediaMessage({ message }, true);
|
||||
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
const { buffer, mediaType, fileName, size } = media;
|
||||
const mimetype = mimeTypes.lookup(fileName).toString();
|
||||
const fullName = join(
|
||||
`${this.instance.id}`,
|
||||
received.key.remoteJid,
|
||||
mediaType,
|
||||
`${Date.now()}_${fileName}`,
|
||||
);
|
||||
await s3Service.uploadFile(fullName, buffer, size.fileLength?.low, { 'Content-Type': mimetype });
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
await this.prismaRepository.media.create({
|
||||
data: {
|
||||
messageId: msg.id,
|
||||
instanceId: this.instanceId,
|
||||
type: mediaType,
|
||||
fileName: fullName,
|
||||
mimetype,
|
||||
},
|
||||
});
|
||||
|
||||
await this.prismaRepository.message.update({ where: { id: msg.id }, data: messageRaw });
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
|
||||
await this.prismaRepository.message.update({ where: { id: msg.id }, data: messageRaw });
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(['Error on upload file to minio', error?.message, error?.stack]);
|
||||
}
|
||||
@@ -1363,7 +1394,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
}
|
||||
},
|
||||
|
||||
'messages.update': async (args: WAMessageUpdate[], settings: any) => {
|
||||
'messages.update': async (args: { update: Partial<WAMessage>; key: WAMessageKey }[], settings: any) => {
|
||||
this.logger.log(`Update messages ${JSON.stringify(args, undefined, 2)}`);
|
||||
|
||||
const readChatToUpdate: Record<string, true> = {}; // {remoteJid: true}
|
||||
@@ -1373,6 +1404,10 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key.remoteJid?.includes('@lid') && key.senderPn) {
|
||||
key.remoteJid = key.senderPn;
|
||||
}
|
||||
|
||||
const updateKey = `${this.instance.id}_${key.id}_${update.status}`;
|
||||
|
||||
const cached = await this.baileysCache.get(updateKey);
|
||||
@@ -2130,31 +2165,39 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
if (isMedia && this.configService.get<S3>('S3').ENABLE) {
|
||||
try {
|
||||
const message: any = messageRaw;
|
||||
const media = await this.getBase64FromMediaMessage({ message }, true);
|
||||
|
||||
const { buffer, mediaType, fileName, size } = media;
|
||||
// Verificação adicional para garantir que há conteúdo de mídia real
|
||||
const hasRealMedia = this.hasValidMediaContent(message);
|
||||
|
||||
const mimetype = mimeTypes.lookup(fileName).toString();
|
||||
if (!hasRealMedia) {
|
||||
this.logger.warn('Message detected as media but contains no valid media content');
|
||||
} else {
|
||||
const media = await this.getBase64FromMediaMessage({ message }, true);
|
||||
|
||||
const fullName = join(
|
||||
`${this.instance.id}`,
|
||||
messageRaw.key.remoteJid,
|
||||
`${messageRaw.key.id}`,
|
||||
mediaType,
|
||||
fileName,
|
||||
);
|
||||
const { buffer, mediaType, fileName, size } = media;
|
||||
|
||||
await s3Service.uploadFile(fullName, buffer, size.fileLength?.low, { 'Content-Type': mimetype });
|
||||
const mimetype = mimeTypes.lookup(fileName).toString();
|
||||
|
||||
await this.prismaRepository.media.create({
|
||||
data: { messageId: msg.id, instanceId: this.instanceId, type: mediaType, fileName: fullName, mimetype },
|
||||
});
|
||||
const fullName = join(
|
||||
`${this.instance.id}`,
|
||||
messageRaw.key.remoteJid,
|
||||
`${messageRaw.key.id}`,
|
||||
mediaType,
|
||||
fileName,
|
||||
);
|
||||
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
await s3Service.uploadFile(fullName, buffer, size.fileLength?.low, { 'Content-Type': mimetype });
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
await this.prismaRepository.media.create({
|
||||
data: { messageId: msg.id, instanceId: this.instanceId, type: mediaType, fileName: fullName, mimetype },
|
||||
});
|
||||
|
||||
await this.prismaRepository.message.update({ where: { id: msg.id }, data: messageRaw });
|
||||
const mediaUrl = await s3Service.getObjectUrl(fullName);
|
||||
|
||||
messageRaw.message.mediaUrl = mediaUrl;
|
||||
|
||||
await this.prismaRepository.message.update({ where: { id: msg.id }, data: messageRaw });
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(['Error on upload file to minio', error?.message, error?.stack]);
|
||||
}
|
||||
@@ -3422,6 +3465,18 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
}
|
||||
}
|
||||
|
||||
public async mapMediaType(mediaType) {
|
||||
const map = {
|
||||
imageMessage: 'image',
|
||||
videoMessage: 'video',
|
||||
documentMessage: 'document',
|
||||
stickerMessage: 'sticker',
|
||||
audioMessage: 'audio',
|
||||
ptvMessage: 'video',
|
||||
};
|
||||
return map[mediaType] || null;
|
||||
}
|
||||
|
||||
public async getBase64FromMediaMessage(data: getBase64FromMediaMessageDto, getBuffer = false) {
|
||||
try {
|
||||
const m = data?.message;
|
||||
@@ -3446,28 +3501,76 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
let mediaMessage: any;
|
||||
let mediaType: string;
|
||||
|
||||
for (const type of TypeMediaMessage) {
|
||||
mediaMessage = msg.message[type];
|
||||
if (mediaMessage) {
|
||||
mediaType = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (msg.message?.templateMessage) {
|
||||
const template =
|
||||
msg.message.templateMessage.hydratedTemplate || msg.message.templateMessage.hydratedFourRowTemplate;
|
||||
|
||||
if (!mediaMessage) {
|
||||
throw 'The message is not of the media type';
|
||||
for (const type of TypeMediaMessage) {
|
||||
if (template[type]) {
|
||||
mediaMessage = template[type];
|
||||
mediaType = type;
|
||||
msg.message = { [type]: { ...template[type], url: template[type].staticUrl } };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mediaMessage) {
|
||||
throw 'Template message does not contain a supported media type';
|
||||
}
|
||||
} else {
|
||||
for (const type of TypeMediaMessage) {
|
||||
mediaMessage = msg.message[type];
|
||||
if (mediaMessage) {
|
||||
mediaType = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mediaMessage) {
|
||||
throw 'The message is not of the media type';
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof mediaMessage['mediaKey'] === 'object') {
|
||||
msg.message = JSON.parse(JSON.stringify(msg.message));
|
||||
}
|
||||
|
||||
const buffer = await downloadMediaMessage(
|
||||
{ key: msg?.key, message: msg?.message },
|
||||
'buffer',
|
||||
{},
|
||||
{ logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage },
|
||||
);
|
||||
let buffer: Buffer;
|
||||
|
||||
try {
|
||||
buffer = await downloadMediaMessage(
|
||||
{ key: msg?.key, message: msg?.message },
|
||||
'buffer',
|
||||
{},
|
||||
{ logger: P({ level: 'error' }) as any, reuploadRequest: this.client.updateMediaMessage },
|
||||
);
|
||||
} catch (err) {
|
||||
this.logger.error('Download Media failed, trying to retry in 5 seconds...');
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||
const mediaType = Object.keys(msg.message).find((key) => key.endsWith('Message'));
|
||||
if (!mediaType) throw new Error('Could not determine mediaType for fallback');
|
||||
|
||||
try {
|
||||
const media = await downloadContentFromMessage(
|
||||
{
|
||||
mediaKey: msg.message?.[mediaType]?.mediaKey,
|
||||
directPath: msg.message?.[mediaType]?.directPath,
|
||||
url: `https://mmg.whatsapp.net${msg?.message?.[mediaType]?.directPath}`,
|
||||
},
|
||||
await this.mapMediaType(mediaType),
|
||||
{},
|
||||
);
|
||||
const chunks = [];
|
||||
for await (const chunk of media) {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
buffer = Buffer.concat(chunks);
|
||||
this.logger.info('Download Media with downloadContentFromMessage was successful!');
|
||||
} catch (fallbackErr) {
|
||||
this.logger.error('Download Media with downloadContentFromMessage also failed!');
|
||||
throw fallbackErr;
|
||||
}
|
||||
}
|
||||
const typeMessage = getContentType(msg.message);
|
||||
|
||||
const ext = mimeTypes.extension(mediaMessage?.['mimetype']);
|
||||
|
||||
Reference in New Issue
Block a user