From dca69deaaad120fa60d37a89950a119a5bb5fc3c Mon Sep 17 00:00:00 2001 From: Edgard Date: Sat, 24 Feb 2024 17:52:40 -0300 Subject: [PATCH] feat: Added support to WhasApp WEB 2.3000.x --- src/webpack/index.ts | 90 ++++++++++++++++++++-- src/whatsapp/functions/contactFunctions.ts | 2 +- src/whatsapp/functions/uploadThumbnail.ts | 3 + src/whatsapp/misc/EventEmitter.ts | 3 +- src/whatsapp/misc/Locale.ts | 34 -------- src/whatsapp/misc/index.ts | 1 - src/whatsapp/models/ModelChatBase.ts | 8 +- webpack.config.js | 2 +- 8 files changed, 98 insertions(+), 45 deletions(-) delete mode 100644 src/whatsapp/misc/Locale.ts diff --git a/src/webpack/index.ts b/src/webpack/index.ts index 30571d1ff3..9b14cc0bde 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -20,6 +20,11 @@ import { internalEv } from '../eventEmitter'; const debug = Debug('WA-JS:webpack'); +/** + * Is setted true when the loader is injected + */ +export let loaderType: 'meta' | 'unknown' | 'webpack' = 'unknown'; + /** * Is setted true when the loader is injected */ @@ -55,6 +60,14 @@ export function onFullReady(listener: () => void, delay = 0): void { export type SearchModuleCondition = (module: any, moduleId: string) => boolean; +export const __debug = () => { + const global = (self || window) as any; + + return global.require('__debug') as { + modulesMap: { [key: string]: any }; + }; +}; + export let webpackRequire: ((moduleId: string) => T) & { /** * module list @@ -75,6 +88,7 @@ export let webpackRequire: ((moduleId: string) => T) & { */ export const fallbackModules: { [key: string]: any } = {}; +const waitMainInit = internalEv.waitFor('conn.main_init'); const waitMainReady = internalEv.waitFor('conn.main_ready'); export function injectLoader(): void { @@ -82,15 +96,77 @@ export function injectLoader(): void { return; } + const global = (self || window) as any; + + /* BEGIN: For WhatsApp >= 2.3000.0 */ + const metaTimer = setInterval(async () => { + if (loaderType !== 'unknown') { + clearInterval(metaTimer); + return; + } + if (!global.require || !global.__d) { + return; + } + loaderType = 'meta'; + + // A wrap to work like webpack + webpackRequire = function (id: string) { + try { + global.ErrorGuard.skipGuardGlobal(true); + return global.importNamespace(id); + } catch (error) {} + return null; + } as any; + + Object.defineProperty(webpackRequire, 'm', { + get: () => { + const modulesMap = __debug().modulesMap; + const ids = Object.keys(modulesMap).filter((id) => + /^(?:use)?WA/.test(id) + ); + const result: any = {}; + + for (const id of ids) { + result[id] = modulesMap[id]?.factory; + } + + return result; + }, + }); + + isInjected = true; + debug('injected'); + await internalEv.emitAsync('webpack.injected').catch(() => null); + + await waitMainInit; + await new Promise((resolve) => setTimeout(resolve, 1000)); + isReady = true; + debug('ready to use'); + await internalEv.emitAsync('webpack.ready').catch(() => null); + + if ((window as any).wppForceMainLoad) { + await new Promise((resolve) => setTimeout(resolve, 5000)); + } else { + await waitMainReady; + } + isFullReady = true; + debug('full ready to use'); + await internalEv.emitAsync('webpack.full_ready').catch(() => null); + }, 1000); + + /* END: For WhatsApp >= 2.3000.0 */ + const chunkName = 'webpackChunkwhatsapp_web_client'; - const global = (self || window) as any; const chunk = global[chunkName] || []; if (typeof global[chunkName] === 'undefined') { global[chunkName] = chunk; + } else { + loaderType = 'webpack'; } const injectFunction = async (__webpack_require__: any) => { + loaderType = 'webpack'; webpackRequire = __webpack_require__; isInjected = true; @@ -165,7 +241,11 @@ export function injectLoader(): void { const sourceModuleMap = new Map(); export function moduleSource(moduleId: string) { - if (typeof webpackRequire.m[moduleId] === 'undefined') { + if (loaderType !== 'webpack') { + return ''; + } + + if (!webpackRequire.m[moduleId]) { return ''; } @@ -311,7 +391,7 @@ export function modules( } export function loadModule(moduleId: string) { - const module = /^\d+$/.test(moduleId) + const module = !/^fallback_/.test(moduleId) ? webpackRequire(moduleId) : fallbackModules[moduleId]; @@ -330,9 +410,9 @@ export function injectFallbackModule( ): void { moduleId = moduleId + ''; - if (/^\d+$/.test(moduleId)) { + if (/^fallback_/.test(moduleId)) { throw new Error('Invalid fallback ID'); } - fallbackModules[moduleId] = content; + fallbackModules[`fallback_${moduleId}`] = content; } diff --git a/src/whatsapp/functions/contactFunctions.ts b/src/whatsapp/functions/contactFunctions.ts index 20c0c2061e..88d0befdd9 100644 --- a/src/whatsapp/functions/contactFunctions.ts +++ b/src/whatsapp/functions/contactFunctions.ts @@ -262,7 +262,7 @@ exportModule( getFormattedName: 'getFormattedName', getFormattedUser: 'getFormattedUser', }, - (m) => m.getDisplayName + (m) => m.getDisplayName && m.getFormattedName ); injectFallbackModule('getDisplayName', { getDisplayName: (contact: ContactModel) => contact.displayName, diff --git a/src/whatsapp/functions/uploadThumbnail.ts b/src/whatsapp/functions/uploadThumbnail.ts index 743bcfaefb..aa6f6ae9b8 100644 --- a/src/whatsapp/functions/uploadThumbnail.ts +++ b/src/whatsapp/functions/uploadThumbnail.ts @@ -48,6 +48,9 @@ exportModule( uploadThumbnail: 'default', }, (m, id) => { + if (id === 'WAWebMediaUploadMmsThumbnail') { + return true; + } const source: string = webpack.moduleSource(id); return ( source.includes('thumbnail') && diff --git a/src/whatsapp/misc/EventEmitter.ts b/src/whatsapp/misc/EventEmitter.ts index dca310ac62..e87ab22d7e 100644 --- a/src/whatsapp/misc/EventEmitter.ts +++ b/src/whatsapp/misc/EventEmitter.ts @@ -125,6 +125,7 @@ exportModule( { EventEmitter: 'default', }, - (m) => + (m, id) => + id === 'WAWebEventEmitter' || m.default.toString().includes('Callback parameter passed is not a function') ); diff --git a/src/whatsapp/misc/Locale.ts b/src/whatsapp/misc/Locale.ts deleted file mode 100644 index 57e3f4602d..0000000000 --- a/src/whatsapp/misc/Locale.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*! - * Copyright 2021 WPPConnect Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { exportModule } from '../exportModule'; - -declare class LocaleClass {} - -/** @whatsapp 14296 - * @whatsapp 43725 >= 2.2204.13 - * @whatsapp 914296 >= 2.2222.8 - * @whatsapp 568064 >= 2.2230.8 - */ -export declare const Locale: LocaleClass; - -exportModule( - exports, - { - Locale: 'default', - }, - (m) => m.default.downloadAndSetTranslation -); diff --git a/src/whatsapp/misc/index.ts b/src/whatsapp/misc/index.ts index 03425e9451..6824790016 100644 --- a/src/whatsapp/misc/index.ts +++ b/src/whatsapp/misc/index.ts @@ -22,7 +22,6 @@ export * from './Conn'; export * from './Constants'; export * from './EventEmitter'; export * from './ImageUtils'; -export * from './Locale'; export * from './MediaBlobCache'; export * from './MediaEntry'; export * from './MediaObject'; diff --git a/src/whatsapp/models/ModelChatBase.ts b/src/whatsapp/models/ModelChatBase.ts index ce7627e93c..03d556de19 100644 --- a/src/whatsapp/models/ModelChatBase.ts +++ b/src/whatsapp/models/ModelChatBase.ts @@ -49,6 +49,10 @@ export declare class ModelChatBase extends Model { notifyMsgCollectionMerge(...args: any[]): void; } -exportModule(exports, { ModelChatBase: 'default' }, (m) => - m.default.toString().includes('onEmptyMRM not implemented') +exportModule( + exports, + { ModelChatBase: 'default' }, + (m, id) => + id === 'WAWebSuperChatMsgs' || + m.default.toString().includes('onEmptyMRM not implemented') ); diff --git a/webpack.config.js b/webpack.config.js index cb216e14bc..7936563f41 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -25,7 +25,7 @@ module.exports = { path: path.resolve(__dirname, 'dist'), library: { name: 'WPP', - type: 'umd', + type: 'global', }, }, plugins: [