@@ -31,11 +31,14 @@ import {
3131import { InstanceDto , SetPresenceDto } from '@api/dto/instance.dto' ;
3232import { HandleLabelDto , LabelDto } from '@api/dto/label.dto' ;
3333import {
34+ Button ,
3435 ContactMessage ,
3536 MediaMessage ,
3637 Options ,
3738 SendAudioDto ,
39+ SendButtonsDto ,
3840 SendContactDto ,
41+ SendListDto ,
3942 SendLocationDto ,
4043 SendMediaDto ,
4144 SendPollDto ,
@@ -44,6 +47,7 @@ import {
4447 SendStickerDto ,
4548 SendTextDto ,
4649 StatusMessage ,
50+ TypeButton ,
4751} from '@api/dto/sendMessage.dto' ;
4852import { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper' ;
4953import * as s3Service from '@api/integrations/storage/s3/libs/minio.server' ;
@@ -117,7 +121,7 @@ import makeWASocket, {
117121import { Label } from 'baileys/lib/Types/Label' ;
118122import { LabelAssociation } from 'baileys/lib/Types/LabelAssociation' ;
119123import { spawn } from 'child_process' ;
120- import { isBase64 , isURL } from 'class-validator' ;
124+ import { isArray , isBase64 , isURL } from 'class-validator' ;
121125import { randomBytes } from 'crypto' ;
122126import EventEmitter2 from 'eventemitter2' ;
123127import ffmpeg from 'fluent-ffmpeg' ;
@@ -582,6 +586,23 @@ export class BaileysStartupService extends ChannelStartupService {
582586 cachedGroupMetadata : this . getGroupMetadataCache ,
583587 userDevicesCache : this . userDevicesCache ,
584588 transactionOpts : { maxCommitRetries : 10 , delayBetweenTriesMs : 3000 } ,
589+ patchMessageBeforeSending ( message ) {
590+ if (
591+ message . deviceSentMessage ?. message ?. listMessage ?. listType === proto . Message . ListMessage . ListType . PRODUCT_LIST
592+ ) {
593+ message = JSON . parse ( JSON . stringify ( message ) ) ;
594+
595+ message . deviceSentMessage . message . listMessage . listType = proto . Message . ListMessage . ListType . SINGLE_SELECT ;
596+ }
597+
598+ if ( message . listMessage ?. listType == proto . Message . ListMessage . ListType . PRODUCT_LIST ) {
599+ message = JSON . parse ( JSON . stringify ( message ) ) ;
600+
601+ message . listMessage . listType = proto . Message . ListMessage . ListType . SINGLE_SELECT ;
602+ }
603+
604+ return message ;
605+ } ,
585606 } ;
586607
587608 this . endSession = false ;
@@ -1768,6 +1789,28 @@ export class BaileysStartupService extends ChannelStartupService {
17681789 if ( messageId ) option . messageId = messageId ;
17691790 else option . messageId = '3EB0' + randomBytes ( 18 ) . toString ( 'hex' ) . toUpperCase ( ) ;
17701791
1792+ if ( message [ 'viewOnceMessage' ] ) {
1793+ const m = generateWAMessageFromContent ( sender , message , {
1794+ timestamp : new Date ( ) ,
1795+ userJid : this . instance . wuid ,
1796+ messageId,
1797+ quoted,
1798+ } ) ;
1799+ const id = await this . client . relayMessage ( sender , message , { messageId } ) ;
1800+ m . key = {
1801+ id : id ,
1802+ remoteJid : sender ,
1803+ participant : isJidUser ( sender ) ? sender : undefined ,
1804+ fromMe : true ,
1805+ } ;
1806+ for ( const [ key , value ] of Object . entries ( m ) ) {
1807+ if ( ! value || ( isArray ( value ) && value . length ) === 0 ) {
1808+ delete m [ key ] ;
1809+ }
1810+ }
1811+ return m ;
1812+ }
1813+
17711814 if (
17721815 ! message [ 'audio' ] &&
17731816 ! message [ 'poll' ] &&
@@ -2684,8 +2727,95 @@ export class BaileysStartupService extends ChannelStartupService {
26842727 ) ;
26852728 }
26862729
2687- public async buttonMessage ( ) {
2688- throw new BadRequestException ( 'Method not available on WhatsApp Baileys' ) ;
2730+ private toJSONString ( button : Button ) : string {
2731+ const toString = ( obj : any ) => JSON . stringify ( obj ) ;
2732+
2733+ const json = {
2734+ call : ( ) => toString ( { display_text : button . displayText , phone_number : button . phoneNumber } ) ,
2735+ reply : ( ) => toString ( { display_text : button . displayText , id : button . id } ) ,
2736+ copy : ( ) => toString ( { display_text : button . displayText , copy_code : button . copyCode } ) ,
2737+ url : ( ) =>
2738+ toString ( {
2739+ display_text : button . displayText ,
2740+ url : button . url ,
2741+ merchant_url : button . url ,
2742+ } ) ,
2743+ } ;
2744+
2745+ return json [ button . type ] ?.( ) || '' ;
2746+ }
2747+
2748+ private readonly mapType = new Map < TypeButton , string > ( [
2749+ [ 'reply' , 'quick_reply' ] ,
2750+ [ 'copy' , 'cta_copy' ] ,
2751+ [ 'url' , 'cta_url' ] ,
2752+ [ 'call' , 'cta_call' ] ,
2753+ ] ) ;
2754+
2755+ public async buttonMessage ( data : SendButtonsDto ) {
2756+ const generate = await ( async ( ) => {
2757+ if ( data ?. thumbnailUrl ) {
2758+ return await this . prepareMediaMessage ( {
2759+ mediatype : 'image' ,
2760+ media : data . thumbnailUrl ,
2761+ } ) ;
2762+ }
2763+ } ) ( ) ;
2764+
2765+ const buttons = data . buttons . map ( ( value ) => {
2766+ return {
2767+ name : this . mapType . get ( value . type ) ,
2768+ buttonParamsJson : this . toJSONString ( value ) ,
2769+ } ;
2770+ } ) ;
2771+
2772+ const message : proto . IMessage = {
2773+ viewOnceMessage : {
2774+ message : {
2775+ interactiveMessage : {
2776+ body : {
2777+ text : ( ( ) => {
2778+ let t = '*' + data . title + '*' ;
2779+ if ( data ?. description ) {
2780+ t += '\n\n' ;
2781+ t += data . description ;
2782+ t += '\n' ;
2783+ }
2784+ return t ;
2785+ } ) ( ) ,
2786+ } ,
2787+ footer : {
2788+ text : data ?. footer ,
2789+ } ,
2790+ header : ( ( ) => {
2791+ if ( generate ?. message ?. imageMessage ) {
2792+ return {
2793+ hasMediaAttachment : ! ! generate . message . imageMessage ,
2794+ imageMessage : generate . message . imageMessage ,
2795+ } ;
2796+ }
2797+ } ) ( ) ,
2798+ nativeFlowMessage : {
2799+ buttons : buttons ,
2800+ messageParamsJson : JSON . stringify ( {
2801+ from : 'api' ,
2802+ templateId : v4 ( ) ,
2803+ } ) ,
2804+ } ,
2805+ } ,
2806+ } ,
2807+ } ,
2808+ } ;
2809+
2810+ console . log ( JSON . stringify ( message ) ) ;
2811+
2812+ return await this . sendMessageWithTyping ( data . number , message , {
2813+ delay : data ?. delay ,
2814+ presence : 'composing' ,
2815+ quoted : data ?. quoted ,
2816+ mentionsEveryOne : data ?. mentionsEveryOne ,
2817+ mentioned : data ?. mentioned ,
2818+ } ) ;
26892819 }
26902820
26912821 public async locationMessage ( data : SendLocationDto ) {
@@ -2709,8 +2839,27 @@ export class BaileysStartupService extends ChannelStartupService {
27092839 ) ;
27102840 }
27112841
2712- public async listMessage ( ) {
2713- throw new BadRequestException ( 'Method not available on WhatsApp Baileys' ) ;
2842+ public async listMessage ( data : SendListDto ) {
2843+ return await this . sendMessageWithTyping (
2844+ data . number ,
2845+ {
2846+ listMessage : {
2847+ title : data . title ,
2848+ description : data . description ,
2849+ buttonText : data ?. buttonText ,
2850+ footerText : data ?. footerText ,
2851+ sections : data . sections ,
2852+ listType : 2 ,
2853+ } ,
2854+ } ,
2855+ {
2856+ delay : data ?. delay ,
2857+ presence : 'composing' ,
2858+ quoted : data ?. quoted ,
2859+ mentionsEveryOne : data ?. mentionsEveryOne ,
2860+ mentioned : data ?. mentioned ,
2861+ } ,
2862+ ) ;
27142863 }
27152864
27162865 public async contactMessage ( data : SendContactDto ) {
0 commit comments