diff --git a/src/Client.js b/src/Client.js index 17817f5..c7a433d 100644 --- a/src/Client.js +++ b/src/Client.js @@ -937,7 +937,7 @@ class Client extends EventEmitter { unmuteDate = unmuteDate ? unmuteDate.getTime() / 1000 : -1; await this.pupPage.evaluate(async (chatId, timestamp) => { let chat = await window.Store.Chat.get(chatId); - await chat.mute.mute({expiration: timestamp, sendDevice:!0}); + await chat.mute.mute(timestamp, !0); }, chatId, unmuteDate || -1); } diff --git a/src/structures/Buttons.js b/src/structures/Buttons.js index 00e8e8b..908f2bb 100644 --- a/src/structures/Buttons.js +++ b/src/structures/Buttons.js @@ -7,8 +7,8 @@ const MessageMedia = require('./MessageMedia'); * @typedef {Object} ButtonSpec * @property {string} body - The text to show on the button. * @property {string=} id - Custom ID to set on the button. A random one will be generated if one is not passed. - * @property {string=} url - Custom URL to set on the button. Optional and will change the type of the button - * @property {string=} number - Custom URL to set on the button. Optional and will change the type of the button + * @ property {string=} url - Custom URL to set on the button. Optional and will change the type of the button + * @ property {string=} number - Custom URL to set on the button. Optional and will change the type of the button */ /** @@ -17,7 +17,6 @@ const MessageMedia = require('./MessageMedia'); * @property {{displayText: string, url: string}=} urlButton * @property {{displayText: string, phoneNumber: string}=} callButton * @property {{displayText: string, id: string}=} quickReplyButton - * @property {{regularButtons: {text: string, id: string}}=} regularButtons */ /** @@ -29,9 +28,8 @@ class Buttons { * @param {ButtonSpec[]} buttons - See {@link ButtonSpec} * @param {string?} title * @param {string?} footer - * @param {boolean?} templateOverride */ - constructor(body, buttons, title, footer, templateOverride = false) { + constructor(body, buttons, title, footer) { /** * Message body * @type {string|MessageMedia} @@ -63,12 +61,7 @@ class Buttons { */ this.buttons = this._format(buttons); if(!this.buttons.length){ throw '[BT01] No buttons';} - - /** - * Override buttons with templates - * @type {boolean} - */ - this.useTemplateButtons = templateOverride; + } /** @@ -78,30 +71,30 @@ class Buttons { */ _format(buttons){ // Limit the buttons (max 3 of regular and 3 of special buttons) 5 buttons total at the same time - const templateButtons = buttons.filter(button => button.url || button.number); - const regularButtons = buttons.filter(button => !button.url && !button.number); - buttons = regularButtons.concat(templateButtons); + const templateButtons = buttons.filter(button => button.url || button.number).slice(0,3); + const regularButtons = buttons.filter(button => !button.url && !button.number).slice(0,3); + buttons = templateButtons.concat(regularButtons).slice(0,5); return buttons.map((button, index) => { if (button.url && button.number && button.id) throw 'Only pick one of the following (url/number/id)'; if (button.number) { - console.log('[WARNING] THIS FEATURE (CALL BUTTONS) IS UNSTABLE AND IS NOT TESTED OR EXPECTED TO WORK ON ALL PLATFORMS. Help test this feature with us on https://github.com/wwebjs/buttons-test'); - return { + throw 'Not supported, URL and Call buttons are not supported on IOS'; + /* return { index, callButton: { displayText: button.body, phoneNumber: button.number || '' } - }; + }; */ } else if (button.url) { - console.log('[WARNING] THIS FEATURE (URL BUTTONS) IS UNSTABLE AND IS NOT TESTED OR EXPECTED TO WORK ON ALL PLATFORMS. Help test this feature with us on https://github.com/wwebjs/buttons-test'); - return { + throw 'Not supported, URL and Call buttons are not supported on IOS'; + /* return { index, urlButton: { displayText: button.body, url: button.url || '' } - }; + }; */ } else { return { index, diff --git a/src/util/Injected.js b/src/util/Injected.js index eb4f6c5..325d5ca 100644 --- a/src/util/Injected.js +++ b/src/util/Injected.js @@ -25,7 +25,7 @@ exports.ExposeStore = (moduleRaidStr) => { window.Store.MsgKey = window.mR.findModule((module) => module.default && module.default.fromString)[0].default; window.Store.MessageInfo = window.mR.findModule('sendQueryMsgInfo')[0]; window.Store.OpaqueData = window.mR.findModule(module => module.default && module.default.createFromData)[0].default; - window.Store.QueryExist = window.mR.findModule('queryExists')[0] ? window.mR.findModule('queryExists')[0].queryExists : window.mR.findModule('queryExist')[0].queryWidExists; + window.Store.QueryExist = window.mR.findModule('queryWidExists')[0].queryExists; window.Store.QueryProduct = window.mR.findModule('queryProduct')[0]; window.Store.QueryOrder = window.mR.findModule('queryOrder')[0]; window.Store.SendClear = window.mR.findModule('sendClear')[0]; @@ -105,13 +105,12 @@ exports.ExposeStore = (moduleRaidStr) => { }; // Function to modify functions. - // This function simply just runs the callback you provide with the original code in the first argument and all the arguments passed to that function. window.injectToFunction = (selector, callback) => { const oldFunct = window.mR.findModule(selector.name)[selector.index][selector.property]; window.mR.findModule(selector.name)[selector.index][selector.property] = (...args) => callback(oldFunct, args); }; - // Find Template models + // Find button models window.Store.TemplateButtonModel = window.findProxyModel('TemplateButtonModel'); window.Store.TemplateButtonCollection = window.mR.findModule('TemplateButtonCollection')[0].TemplateButtonCollection; @@ -212,40 +211,38 @@ exports.ExposeStore = (moduleRaidStr) => { return proto; }); - setTimeout(() => { - window.injectToFunction({ - index: 0, - name: 'createMsgProtobuf', - property: 'createMsgProtobuf' - }, (func, args) => { - const proto = func(...args); - if (proto.templateMessage) { - proto.viewOnceMessage = { - message: { - templateMessage: proto.templateMessage, - }, - }; - delete proto.templateMessage; - } - if (proto.buttonsMessage) { - proto.viewOnceMessage = { - message: { - buttonsMessage: proto.buttonsMessage, - }, - }; - delete proto.buttonsMessage; - } - if (proto.listMessage) { - proto.viewOnceMessage = { - message: { - listMessage: proto.listMessage, - }, - }; - delete proto.listMessage; - } - return proto; - }); - }, 100); + window.injectToFunction({ + index: 0, + name: 'createMsgProtobuf', + property: 'createMsgProtobuf' + }, (func, args) => { + const proto = func(...args); + if (proto.templateMessage) { + proto.viewOnceMessage = { + message: { + templateMessage: proto.templateMessage, + }, + }; + delete proto.templateMessage; + } + if (proto.buttonsMessage) { + proto.viewOnceMessage = { + message: { + buttonsMessage: proto.buttonsMessage, + }, + }; + delete proto.buttonsMessage; + } + if (proto.listMessage) { + proto.viewOnceMessage = { + message: { + listMessage: proto.listMessage, + }, + }; + delete proto.listMessage; + } + return proto; + }); window.injectToFunction({ index: 0, @@ -253,20 +250,6 @@ exports.ExposeStore = (moduleRaidStr) => { property: 'typeAttributeFromProtobuf' }, (func, args) => { const [proto] = args; - - if (proto.ephemeralMessage) { - const { message } = proto.ephemeralMessage; - return message ? func(message) : 'text'; - } - if (proto.deviceSentMessage) { - const { message } = proto.deviceSentMessage; - return message ? func(message) : 'text'; - } - if (proto.viewOnceMessage) { - const { message } = proto.viewOnceMessage; - return message ? func(message) : 'text'; - } - if (proto.templateMessage?.hydratedTemplate) { const keys = Object.keys(proto.templateMessage?.hydratedTemplate); const messagePart = [ @@ -287,9 +270,28 @@ exports.ExposeStore = (moduleRaidStr) => { ) { return 'text'; } + + return func(...args); + }); - if (proto.listMessage) { - return 'text'; + window.injectToFunction({ + index: 0, + name: 'typeAttributeFromProtobuf', + property: 'typeAttributeFromProtobuf' + }, (func, args) => { + const [proto] = args; + + if (proto.ephemeralMessage) { + const { message } = proto.ephemeralMessage; + return message ? func(message) : 'text'; + } + if (proto.deviceSentMessage) { + const { message } = proto.deviceSentMessage; + return message ? func(message) : 'text'; + } + if (proto.viewOnceMessage) { + const { message } = proto.viewOnceMessage; + return message ? func(message) : 'text'; } return func(...args); @@ -306,6 +308,28 @@ exports.ExposeStore = (moduleRaidStr) => { } return func(...args); }); + + window.injectToFunction({ + index: 0, + name: 'mediaTypeFromProtobuf', + property: 'mediaTypeFromProtobuf' + }, (func, args) => { + const [proto] = args; + if (proto.deviceSentMessage) { + const { message } = proto.deviceSentMessage; + return message ? func(message) : null; + } + if (proto.ephemeralMessage) { + const { message } = proto.ephemeralMessage; + return message ? func(message) : null; + } + if (proto.viewOnceMessage) { + const { message } = proto.viewOnceMessage; + return message ? func(message) : null; + } + + return func(...args); + }); window.injectToFunction({ index: 0, @@ -357,44 +381,45 @@ exports.LoadUtils = () => { return returnObject; } + if (typeof buttonsOptions.useTemplateButtons === 'undefined' || buttonsOptions.useTemplateButtons === null) { + buttonsOptions.useTemplateButtons = buttonsOptions.buttons.some((button) => { + return 'callButton' in button || 'urlButton' in button; + }); + } + returnObject.title = buttonsOptions.title; returnObject.footer = buttonsOptions.footer; if (buttonsOptions.useTemplateButtons) { returnObject.isFromTemplate = true; returnObject.hydratedButtons = buttonsOptions.buttons; - returnObject.buttons = new window.Store.TemplateButtonCollection(); + returnObject.buttons = new window.Store.TemplateButtonCollection; - returnObject.buttons.add( - returnObject.hydratedButtons.map((button, index) => { - const i = `${null != button.index ? button.index : index}`; - - if (button.urlButton) { - return new window.Store.TemplateButtonModel({ - id: i, - displayText: button.urlButton?.displayText, - url: button.urlButton?.url, - subtype: 'url', - }); - } - - if (button.callButton) { - return new window.Store.TemplateButtonModel({ - id: i, - displayText: button.callButton.displayText, - phoneNumber: button.callButton.phoneNumber, - subtype: 'call', - }); - } - + returnObject.buttons.add(returnObject.hydratedButtons.map((button, index) => { + const buttonIndex = button.index ? button.index : index; + if (button.urlButton) { return new window.Store.TemplateButtonModel({ - id: i, + id: buttonIndex, + displayText: button.urlButton?.displayText || '', + url: button.urlButton?.url, + subtype: 'url' + }); + } else if (button.callButton) { + return new window.Store.TemplateButtonModel({ + id: buttonIndex, + displayText: button.callButton?.displayText, + phoneNumber: button.callButton?.phoneNumber, + subtype: 'call' + }); + } else { + return new window.Store.TemplateButtonModel({ + id: buttonIndex, displayText: button.quickReplyButton?.displayText, selectionId: button.quickReplyButton?.id, - subtype: 'quick_reply', + subtype: 'quick_reply' }); - }) - ); + } + })); } else { returnObject.isDynamicReplyButtonsMsg = true;