@@ -28,7 +28,6 @@ import axios from 'axios';
2828import { arrayUnique , isURL } from 'class-validator' ;
2929import EventEmitter2 from 'eventemitter2' ;
3030import FormData from 'form-data' ;
31- import { createReadStream } from 'fs' ;
3231import mimeTypes from 'mime-types' ;
3332import { join } from 'path' ;
3433
@@ -997,9 +996,10 @@ export class BusinessStartupService extends ChannelStartupService {
997996 to : number . replace ( / \D / g, '' ) ,
998997 [ message [ 'mediaType' ] ] : {
999998 [ message [ 'type' ] ] : message [ 'id' ] ,
1000- preview_url : Boolean ( options ?. linkPreview ) ,
1001- ...( message [ 'fileName' ] && ! isImage && { filename : message [ 'fileName' ] } ) ,
1002- caption : message [ 'caption' ] ,
999+ ...( message [ 'mediaType' ] !== 'audio' &&
1000+ message [ 'fileName' ] &&
1001+ ! isImage && { filename : message [ 'fileName' ] } ) ,
1002+ ...( message [ 'mediaType' ] !== 'audio' && message [ 'caption' ] && { caption : message [ 'caption' ] } ) ,
10031003 } ,
10041004 } ;
10051005 quoted ? ( content . context = { message_id : quoted . id } ) : content ;
@@ -1097,7 +1097,7 @@ export class BusinessStartupService extends ChannelStartupService {
10971097 }
10981098 } ) ( ) ;
10991099
1100- if ( messageSent ?. error_data ) {
1100+ if ( messageSent ?. error_data || messageSent . message ) {
11011101 this . logger . error ( messageSent ) ;
11021102 return messageSent ;
11031103 }
@@ -1164,28 +1164,50 @@ export class BusinessStartupService extends ChannelStartupService {
11641164 return res ;
11651165 }
11661166
1167- private async getIdMedia ( mediaMessage : any ) {
1168- const formData = new FormData ( ) ;
1169- const fileStream = createReadStream ( mediaMessage . media ) ;
1167+ private async getIdMedia ( mediaMessage : any , isFile = false ) {
1168+ try {
1169+ const formData = new FormData ( ) ;
1170+
1171+ if ( isFile === false ) {
1172+ if ( isURL ( mediaMessage . media ) ) {
1173+ const response = await axios . get ( mediaMessage . media , { responseType : 'arraybuffer' } ) ;
1174+ const buffer = Buffer . from ( response . data , 'base64' ) ;
1175+ formData . append ( 'file' , buffer , {
1176+ filename : mediaMessage . fileName || 'media' ,
1177+ contentType : mediaMessage . mimetype ,
1178+ } ) ;
1179+ } else {
1180+ const buffer = Buffer . from ( mediaMessage . media , 'base64' ) ;
1181+ formData . append ( 'file' , buffer , {
1182+ filename : mediaMessage . fileName || 'media' ,
1183+ contentType : mediaMessage . mimetype ,
1184+ } ) ;
1185+ }
1186+ } else {
1187+ formData . append ( 'file' , mediaMessage . media . buffer , {
1188+ filename : mediaMessage . media . originalname ,
1189+ contentType : mediaMessage . media . mimetype ,
1190+ } ) ;
1191+ }
11701192
1171- formData . append ( 'file' , fileStream , { filename : 'media' , contentType : mediaMessage . mimetype } ) ;
1172- formData . append ( 'typeFile' , mediaMessage . mimetype ) ;
1173- formData . append ( 'messaging_product' , 'whatsapp' ) ;
1193+ const mimetype = mediaMessage . mimetype || mediaMessage . media . mimetype ;
11741194
1175- // const fileBuffer = await fs.readFile(mediaMessage.media);
1195+ formData . append ( 'typeFile' , mimetype ) ;
1196+ formData . append ( 'messaging_product' , 'whatsapp' ) ;
11761197
1177- // const fileBlob = new Blob([fileBuffer], { type: mediaMessage.mimetype });
1178- // formData.append('file', fileBlob);
1179- // formData.append('typeFile', mediaMessage.mimetype);
1180- // formData.append('messaging_product', 'whatsapp');
1198+ const token = process . env . FACEBOOK_USER_TOKEN ;
11811199
1182- const headers = { Authorization : `Bearer ${ this . token } ` } ;
1183- const res = await axios . post (
1184- process . env . API_URL + '/' + process . env . VERSION + '/' + this . number + '/media' ,
1185- formData ,
1186- { headers } ,
1187- ) ;
1188- return res . data . id ;
1200+ const headers = { Authorization : `Bearer ${ token } ` } ;
1201+ const url = `${ this . configService . get < WaBusiness > ( 'WA_BUSINESS' ) . URL } /${
1202+ this . configService . get < WaBusiness > ( 'WA_BUSINESS' ) . VERSION
1203+ } /${ this . number } /media`;
1204+
1205+ const res = await axios . post ( url , formData , { headers } ) ;
1206+ return res . data . id ;
1207+ } catch ( error ) {
1208+ this . logger . error ( error . response . data ) ;
1209+ throw new InternalServerErrorException ( error ?. toString ( ) || error ) ;
1210+ }
11891211 }
11901212
11911213 protected async prepareMediaMessage ( mediaMessage : MediaMessage ) {
@@ -1258,48 +1280,87 @@ export class BusinessStartupService extends ChannelStartupService {
12581280 return mediaSent ;
12591281 }
12601282
1261- public async processAudio ( audio : string , number : string ) {
1283+ public async processAudio ( audio : string , number : string , file : any ) {
12621284 number = number . replace ( / \D / g, '' ) ;
12631285 const hash = `${ number } -${ new Date ( ) . getTime ( ) } ` ;
12641286
1265- let mimetype : string | false ;
1287+ if ( process . env . API_AUDIO_CONVERTER ) {
1288+ this . logger . verbose ( 'Using audio converter API' ) ;
1289+ const formData = new FormData ( ) ;
12661290
1267- const prepareMedia : any = {
1268- fileName : `${ hash } .mp3` ,
1269- mediaType : 'audio' ,
1270- media : audio ,
1271- } ;
1291+ if ( file ) {
1292+ formData . append ( 'file' , file . buffer , {
1293+ filename : file . originalname ,
1294+ contentType : file . mimetype ,
1295+ } ) ;
1296+ } else if ( isURL ( audio ) ) {
1297+ formData . append ( 'url' , audio ) ;
1298+ } else {
1299+ formData . append ( 'base64' , audio ) ;
1300+ }
1301+
1302+ formData . append ( 'format' , 'mp3' ) ;
1303+
1304+ const response = await axios . post ( process . env . API_AUDIO_CONVERTER , formData , {
1305+ headers : {
1306+ ...formData . getHeaders ( ) ,
1307+ apikey : process . env . API_AUDIO_CONVERTER_KEY ,
1308+ } ,
1309+ } ) ;
1310+
1311+ const audioConverter = response ?. data ?. audio || response ?. data ?. url ;
1312+
1313+ if ( ! audioConverter ) {
1314+ throw new InternalServerErrorException ( 'Failed to convert audio' ) ;
1315+ }
1316+
1317+ const prepareMedia : any = {
1318+ fileName : `${ hash } .mp3` ,
1319+ mediaType : 'audio' ,
1320+ media : audioConverter ,
1321+ mimetype : 'audio/mpeg' ,
1322+ } ;
12721323
1273- if ( isURL ( audio ) ) {
1274- mimetype = mimeTypes . lookup ( audio ) ;
1275- prepareMedia . id = audio ;
1276- prepareMedia . type = 'link' ;
1277- } else {
1278- mimetype = mimeTypes . lookup ( prepareMedia . fileName ) ;
12791324 const id = await this . getIdMedia ( prepareMedia ) ;
12801325 prepareMedia . id = id ;
12811326 prepareMedia . type = 'id' ;
1282- }
12831327
1284- prepareMedia . mimetype = mimetype ;
1328+ this . logger . verbose ( 'Audio converted' ) ;
1329+ return prepareMedia ;
1330+ } else {
1331+ let mimetype : string | false ;
12851332
1286- return prepareMedia ;
1287- }
1333+ const prepareMedia : any = {
1334+ fileName : `${ hash } .mp3` ,
1335+ mediaType : 'audio' ,
1336+ media : audio ,
1337+ } ;
12881338
1289- public async audioWhatsapp ( data : SendAudioDto , file ?: any , isIntegration = false ) {
1290- const mediaData : SendAudioDto = { ...data } ;
1339+ if ( isURL ( audio ) ) {
1340+ mimetype = mimeTypes . lookup ( audio ) ;
1341+ prepareMedia . id = audio ;
1342+ prepareMedia . type = 'link' ;
1343+ } else if ( audio && ! file ) {
1344+ mimetype = mimeTypes . lookup ( prepareMedia . fileName ) ;
1345+ const id = await this . getIdMedia ( prepareMedia ) ;
1346+ prepareMedia . id = id ;
1347+ prepareMedia . type = 'id' ;
1348+ } else if ( file ) {
1349+ prepareMedia . media = file ;
1350+ const id = await this . getIdMedia ( prepareMedia , true ) ;
1351+ prepareMedia . id = id ;
1352+ prepareMedia . type = 'id' ;
1353+ mimetype = file . mimetype ;
1354+ }
12911355
1292- if ( file ?. buffer ) {
1293- mediaData . audio = file . buffer . toString ( 'base64' ) ;
1294- } else if ( isURL ( mediaData . audio ) ) {
1295- // DO NOTHING
1296- // mediaData.audio = mediaData.audio;
1297- } else {
1298- console . error ( 'El archivo no tiene buffer o file es undefined' ) ;
1299- throw new Error ( 'File or buffer is undefined' ) ;
1356+ prepareMedia . mimetype = mimetype ;
1357+
1358+ return prepareMedia ;
13001359 }
1360+ }
13011361
1302- const message = await this . processAudio ( mediaData . audio , data . number ) ;
1362+ public async audioWhatsapp ( data : SendAudioDto , file ?: any , isIntegration = false ) {
1363+ const message = await this . processAudio ( data . audio , data . number , file ) ;
13031364
13041365 const audioSent = await this . sendMessageWithTyping (
13051366 data . number ,
0 commit comments