@@ -3310,48 +3310,57 @@ export class BaileysStartupService extends ChannelStartupService {
33103310 [ 'random' , 'EVP' ] ,
33113311 ] ) ;
33123312
3313- public async buttonMessage ( data : SendButtonsDto ) {
3314- if ( data . buttons . length === 0 ) {
3313+ aqui ?
3314+
3315+ public async buttonMessage ( data : SendButtonsDto ) {
3316+ if ( ! data . buttons || data . buttons . length === 0 ) {
33153317 throw new BadRequestException ( 'At least one button is required' ) ;
33163318 }
33173319
33183320 const hasReplyButtons = data . buttons . some ( ( btn ) => btn . type === 'reply' ) ;
33193321 const hasPixButton = data . buttons . some ( ( btn ) => btn . type === 'pix' ) ;
3320- const hasOtherButtons = data . buttons . some ( ( btn ) => btn . type !== 'reply' && btn . type !== 'pix' ) ;
3322+ const hasCTAButtons = data . buttons . some (
3323+ ( btn ) => btn . type === 'url' || btn . type === 'call' || btn . type === 'copy' ,
3324+ ) ;
3325+
3326+ /* =========================
3327+ * REGRAS DE VALIDAÇÃO
3328+ * ========================= */
33213329
3322- // Reply rules
3330+ // Reply
33233331 if ( hasReplyButtons ) {
33243332 if ( data . buttons . length > 3 ) {
33253333 throw new BadRequestException ( 'Maximum of 3 reply buttons allowed' ) ;
33263334 }
3327- if ( hasOtherButtons ) {
3328- throw new BadRequestException ( 'Reply buttons cannot be mixed with other button types' ) ;
3329- }
3330- }
3331-
3332- // CTA rules (url/call/copy) - WhatsApp limits to 2 CTAs
3333- if ( hasOtherButtons && ! hasReplyButtons && ! hasPixButton ) {
3334- if ( data . buttons . length > 2 ) {
3335- throw new BadRequestException ( 'Maximum of 2 CTA buttons allowed (url/call/copy)' ) ;
3335+ if ( hasCTAButtons || hasPixButton ) {
3336+ throw new BadRequestException ( 'Reply buttons cannot be mixed with CTA or PIX buttons' ) ;
33363337 }
33373338 }
33383339
3339- // PIX rules
3340+ // PIX
33403341 if ( hasPixButton ) {
33413342 if ( data . buttons . length > 1 ) {
33423343 throw new BadRequestException ( 'Only one PIX button is allowed' ) ;
33433344 }
3344- if ( hasOtherButtons ) {
3345+ if ( hasReplyButtons || hasCTAButtons ) {
33453346 throw new BadRequestException ( 'PIX button cannot be mixed with other button types' ) ;
33463347 }
33473348
33483349 const message : proto . IMessage = {
3349- deviceSentMessage : {
3350+ viewOnceMessage : {
33503351 message : {
33513352 interactiveMessage : {
33523353 nativeFlowMessage : {
3353- buttons : [ { name : this . mapType . get ( 'pix' ) , buttonParamsJson : this . toJSONString ( data . buttons [ 0 ] ) } ] ,
3354- messageParamsJson : JSON . stringify ( { from : 'api' , templateId : v4 ( ) } ) ,
3354+ buttons : [
3355+ {
3356+ name : this . mapType . get ( 'pix' ) ,
3357+ buttonParamsJson : this . toJSONString ( data . buttons [ 0 ] ) ,
3358+ } ,
3359+ ] ,
3360+ messageParamsJson : JSON . stringify ( {
3361+ from : 'api' ,
3362+ templateId : v4 ( ) ,
3363+ } ) ,
33553364 } ,
33563365 } ,
33573366 } ,
@@ -3367,43 +3376,63 @@ export class BaileysStartupService extends ChannelStartupService {
33673376 } ) ;
33683377 }
33693378
3370- const generate = await ( async ( ) => {
3371- if ( data ?. thumbnailUrl ) {
3372- return await this . prepareMediaMessage ( { mediatype : 'image' , media : data . thumbnailUrl } ) ;
3379+ // CTA (url / call / copy)
3380+ if ( hasCTAButtons ) {
3381+ if ( data . buttons . length > 2 ) {
3382+ throw new BadRequestException ( 'Maximum of 2 CTA buttons allowed' ) ;
3383+ }
3384+ if ( hasReplyButtons ) {
3385+ throw new BadRequestException ( 'CTA buttons cannot be mixed with reply buttons' ) ;
33733386 }
3374- } ) ( ) ;
3387+ }
33753388
3376- const buttons = data . buttons . map ( ( value ) => {
3377- return { name : this . mapType . get ( value . type ) , buttonParamsJson : this . toJSONString ( value ) } ;
3378- } ) ;
3389+ /* =========================
3390+ * HEADER (opcional)
3391+ * ========================= */
3392+
3393+ const generatedMedia = data ?. thumbnailUrl
3394+ ? await this . prepareMediaMessage ( { mediatype : 'image' , media : data . thumbnailUrl } )
3395+ : null ;
3396+
3397+ /* =========================
3398+ * BOTÕES
3399+ * ========================= */
3400+
3401+ const buttons = data . buttons . map ( ( btn ) => ( {
3402+ name : this . mapType . get ( btn . type ) ,
3403+ buttonParamsJson : this . toJSONString ( btn ) ,
3404+ } ) ) ;
3405+
3406+ /* =========================
3407+ * MENSAGEM FINAL
3408+ * ========================= */
33793409
33803410 const message : proto . IMessage = {
3381- deviceSentMessage : {
3411+ viewOnceMessage : {
33823412 message : {
33833413 interactiveMessage : {
33843414 body : {
33853415 text : ( ( ) => {
3386- let t = '*' + data . title + '*' ;
3416+ let text = `* ${ data . title } *` ;
33873417 if ( data ?. description ) {
3388- t += '\n\n' ;
3389- t += data . description ;
3390- t += '\n' ;
3418+ text += `\n\n${ data . description } ` ;
33913419 }
3392- return t ;
3420+ return text ;
33933421 } ) ( ) ,
33943422 } ,
3395- footer : { text : data ?. footer } ,
3396- header : ( ( ) => {
3397- if ( generate ?. message ?. imageMessage ) {
3398- return {
3399- hasMediaAttachment : ! ! generate . message . imageMessage ,
3400- imageMessage : generate . message . imageMessage ,
3401- } ;
3402- }
3403- } ) ( ) ,
3423+ footer : data ?. footer ? { text : data . footer } : undefined ,
3424+ header : generatedMedia ?. message ?. imageMessage
3425+ ? {
3426+ hasMediaAttachment : true ,
3427+ imageMessage : generatedMedia . message . imageMessage ,
3428+ }
3429+ : undefined ,
34043430 nativeFlowMessage : {
34053431 buttons,
3406- messageParamsJson : JSON . stringify ( { from : 'api' , templateId : v4 ( ) } ) ,
3432+ messageParamsJson : JSON . stringify ( {
3433+ from : 'api' ,
3434+ templateId : v4 ( ) ,
3435+ } ) ,
34073436 } ,
34083437 } ,
34093438 } ,
0 commit comments