@@ -147,19 +147,44 @@ export class BusinessStartupService extends ChannelStartupService {
147147 const version = this . configService . get < WaBusiness > ( 'WA_BUSINESS' ) . VERSION ;
148148 urlServer = `${ urlServer } /${ version } /${ id } ` ;
149149 const headers = { 'Content-Type' : 'application/json' , Authorization : `Bearer ${ this . token } ` } ;
150+
151+ // Primeiro, obtenha a URL do arquivo
150152 let result = await axios . get ( urlServer , { headers } ) ;
151- result = await axios . get ( result . data . url , { headers, responseType : 'arraybuffer' } ) ;
153+
154+ // Depois, baixe o arquivo usando a URL retornada
155+ result = await axios . get ( result . data . url , {
156+ headers : { Authorization : `Bearer ${ this . token } ` } , // Use apenas o token de autorização para download
157+ responseType : 'arraybuffer' ,
158+ } ) ;
159+
152160 return result . data ;
153161 } catch ( e ) {
154- this . logger . error ( e ) ;
162+ this . logger . error ( `Error downloading media: ${ e } ` ) ;
163+ throw e ;
155164 }
156165 }
157166
158167 private messageMediaJson ( received : any ) {
159168 const message = received . messages [ 0 ] ;
160169 let content : any = message . type + 'Message' ;
161170 content = { [ content ] : message [ message . type ] } ;
162- message . context ? ( content = { ...content , contextInfo : { stanzaId : message . context . id } } ) : content ;
171+ if ( message . context ) {
172+ content = { ...content , contextInfo : { stanzaId : message . context . id } } ;
173+ }
174+ return content ;
175+ }
176+
177+ private messageAudioJson ( received : any ) {
178+ const message = received . messages [ 0 ] ;
179+ let content : any = {
180+ audioMessage : {
181+ ...message . audio ,
182+ ptt : message . audio . voice || false , // Define se é mensagem de voz
183+ } ,
184+ } ;
185+ if ( message . context ) {
186+ content = { ...content , contextInfo : { stanzaId : message . context . id } } ;
187+ }
163188 return content ;
164189 }
165190
@@ -387,11 +412,14 @@ export class BusinessStartupService extends ChannelStartupService {
387412 instanceId : this . instanceId ,
388413 } ;
389414 } else if ( this . isMediaMessage ( message ) ) {
415+ const messageContent =
416+ message . type === 'audio' ? this . messageAudioJson ( received ) : this . messageMediaJson ( received ) ;
417+
390418 messageRaw = {
391419 key,
392420 pushName,
393- message : this . messageMediaJson ( received ) ,
394- contextInfo : this . messageMediaJson ( received ) ?. contextInfo ,
421+ message : messageContent ,
422+ contextInfo : messageContent ?. contextInfo ,
395423 messageType : this . renderMessageType ( received . messages [ 0 ] . type ) ,
396424 messageTimestamp : parseInt ( received . messages [ 0 ] . timestamp ) as number ,
397425 source : 'unknown' ,
@@ -409,7 +437,10 @@ export class BusinessStartupService extends ChannelStartupService {
409437 const headers = { 'Content-Type' : 'application/json' , Authorization : `Bearer ${ this . token } ` } ;
410438 const result = await axios . get ( urlServer , { headers } ) ;
411439
412- const buffer = await axios . get ( result . data . url , { headers, responseType : 'arraybuffer' } ) ;
440+ const buffer = await axios . get ( result . data . url , {
441+ headers : { Authorization : `Bearer ${ this . token } ` } , // Use apenas o token de autorização para download
442+ responseType : 'arraybuffer' ,
443+ } ) ;
413444
414445 let mediaType ;
415446
@@ -434,6 +465,17 @@ export class BusinessStartupService extends ChannelStartupService {
434465 }
435466 }
436467
468+ // Para áudio, garantir extensão correta baseada no mimetype
469+ if ( mediaType === 'audio' ) {
470+ if ( mimetype . includes ( 'ogg' ) ) {
471+ fileName = `${ message . messages [ 0 ] . id } .ogg` ;
472+ } else if ( mimetype . includes ( 'mp3' ) ) {
473+ fileName = `${ message . messages [ 0 ] . id } .mp3` ;
474+ } else if ( mimetype . includes ( 'm4a' ) ) {
475+ fileName = `${ message . messages [ 0 ] . id } .m4a` ;
476+ }
477+ }
478+
437479 const size = result . headers [ 'content-length' ] || buffer . data . byteLength ;
438480
439481 const fullName = join ( `${ this . instance . id } ` , key . remoteJid , mediaType , fileName ) ;
@@ -460,13 +502,72 @@ export class BusinessStartupService extends ChannelStartupService {
460502
461503 messageRaw . message . mediaUrl = mediaUrl ;
462504 messageRaw . message . base64 = buffer . data . toString ( 'base64' ) ;
505+
506+ // Processar OpenAI speech-to-text para áudio após o mediaUrl estar disponível
507+ if ( this . configService . get < Openai > ( 'OPENAI' ) . ENABLED && mediaType === 'audio' ) {
508+ const openAiDefaultSettings = await this . prismaRepository . openaiSetting . findFirst ( {
509+ where : {
510+ instanceId : this . instanceId ,
511+ } ,
512+ include : {
513+ OpenaiCreds : true ,
514+ } ,
515+ } ) ;
516+
517+ if (
518+ openAiDefaultSettings &&
519+ openAiDefaultSettings . openaiCredsId &&
520+ openAiDefaultSettings . speechToText
521+ ) {
522+ try {
523+ messageRaw . message . speechToText = await this . openaiService . speechToText (
524+ openAiDefaultSettings . OpenaiCreds ,
525+ {
526+ message : {
527+ mediaUrl : messageRaw . message . mediaUrl ,
528+ ...messageRaw ,
529+ } ,
530+ } ,
531+ ) ;
532+ } catch ( speechError ) {
533+ this . logger . error ( `Error processing speech-to-text: ${ speechError } ` ) ;
534+ }
535+ }
536+ }
463537 } catch ( error ) {
464538 this . logger . error ( [ 'Error on upload file to minio' , error ?. message , error ?. stack ] ) ;
465539 }
466540 } else {
467541 const buffer = await this . downloadMediaMessage ( received ?. messages [ 0 ] ) ;
468-
469542 messageRaw . message . base64 = buffer . toString ( 'base64' ) ;
543+
544+ // Processar OpenAI speech-to-text para áudio mesmo sem S3
545+ if ( this . configService . get < Openai > ( 'OPENAI' ) . ENABLED && message . type === 'audio' ) {
546+ const openAiDefaultSettings = await this . prismaRepository . openaiSetting . findFirst ( {
547+ where : {
548+ instanceId : this . instanceId ,
549+ } ,
550+ include : {
551+ OpenaiCreds : true ,
552+ } ,
553+ } ) ;
554+
555+ if ( openAiDefaultSettings && openAiDefaultSettings . openaiCredsId && openAiDefaultSettings . speechToText ) {
556+ try {
557+ messageRaw . message . speechToText = await this . openaiService . speechToText (
558+ openAiDefaultSettings . OpenaiCreds ,
559+ {
560+ message : {
561+ base64 : messageRaw . message . base64 ,
562+ ...messageRaw ,
563+ } ,
564+ } ,
565+ ) ;
566+ } catch ( speechError ) {
567+ this . logger . error ( `Error processing speech-to-text: ${ speechError } ` ) ;
568+ }
569+ }
570+ }
470571 }
471572 } else if ( received ?. messages [ 0 ] . interactive ) {
472573 messageRaw = {
@@ -537,33 +638,6 @@ export class BusinessStartupService extends ChannelStartupService {
537638 // await this.client.readMessages([received.key]);
538639 }
539640
540- if ( this . configService . get < Openai > ( 'OPENAI' ) . ENABLED ) {
541- const openAiDefaultSettings = await this . prismaRepository . openaiSetting . findFirst ( {
542- where : {
543- instanceId : this . instanceId ,
544- } ,
545- include : {
546- OpenaiCreds : true ,
547- } ,
548- } ) ;
549-
550- const audioMessage = received ?. messages [ 0 ] ?. audio ;
551-
552- if (
553- openAiDefaultSettings &&
554- openAiDefaultSettings . openaiCredsId &&
555- openAiDefaultSettings . speechToText &&
556- audioMessage
557- ) {
558- messageRaw . message . speechToText = await this . openaiService . speechToText ( openAiDefaultSettings . OpenaiCreds , {
559- message : {
560- mediaUrl : messageRaw . message . mediaUrl ,
561- ...messageRaw ,
562- } ,
563- } ) ;
564- }
565- }
566-
567641 this . logger . log ( messageRaw ) ;
568642
569643 this . sendDataWebhook ( Events . MESSAGES_UPSERT , messageRaw ) ;
0 commit comments