Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Farewell, Webpack! Re-injection, Pairing Code login, and 2.24x jumbofix #2816

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

PurpShell
Copy link
Sponsor Collaborator

@PurpShell PurpShell commented Mar 14, 2024

Support my work on GitHub Sponsors

TL;DR:

WhatsApp released 2.3000x, a version that does not use Webpack anymore. We had to change the Store system to no longer use moduleRaid. Instability issues are caused by relying on selectors & DOM Observers for login, as well as increased performance issues. This prompted me to adopt the "New startup flow" that I mentioned here. This update is important. This update will boost reliability in WWebJS at least 400%. I also added pairing code login for those who needed it since I had the docs on hand (I reverse engineer then take notes, so I know what I know when I make them into PRs). It changes a lot in the authentication and launching. I advise you all to test your systems before deploying to production (even though this build should be prod-safe).

You should immediately update to my version and cease using any other fork or version. Your system will work regardless if you are using a web cache, local cache, no cache.. LocalAuth, RemoteAuth, NoAuth... 2.24 and 2.3000.

TO INSTALL:

npm install github:pedroslopez/whatsapp-web.js#webpack-exodus

If you encounter a git not found error in the NPM/yarn install: Download git, https://git-scm.com

Thank you for your trust and time and thank you to my sponsors for their contribution.

PR Details

This PR adds support for Wwebjs past version 2.3000.x and 2.24..x. Send "F" in the chat for Webpack!

As always, very big thanks to my sponsors for their support! I am only able to do this thanks to them!

Also thanks to @allburov for his work on #2827, helped me a bit to know which modules are problematic.

This PR also adds re-injection in the case of navigation or refresh or intentional logout and pairing code login option.

It also changes a lot of the code in the startup flow.

To note:

  1. AUTHENTICATED and READY will now depend on the Socket, so if the WWebJS restarts or loses Internet, it will trigger these events. Do not trust that the event will only be triggered once.
  2. await client.initialize() returns it promise much earlier at the point of a new QR code (no login). The behavior is almost the same when logged in (it resolves the promise at AROUND ready).
  3. The Loading screen text will be hard-coded to "WhatsApp" for now. A new update will deprecate this screen text and replace it with loading types (ORGANIZING, INTIAL_LOAD, DOWNLOADING,...)
  4. A new AuthStore is exposed at the time of initial load (before READY) including moduleRaid (2.24) and some modules needed for authentication.

This update will bring a lot of performance, time savings and increased reliability due to this refactor. We are not relying on constantly changing and dynamic HTML to get QR codes, to detect logins and this will make it much better. I also went out of my way and reversed all of the Pairing Code infra to get the only needed functions (3) and made them into this way so that we stop getting failed attempts like #2363

Description

Related Issue

closes #2789, closes #1787, closes #3016

Motivation and Context

After WhatsApp's update to 2.3000.x, moduleRaid no longer detected webpack (since they changed build systems)
After WhatsApp's update to 2.24xx.x, the manifest json no longer included the version, requiring a revamp for the cache system!

How Has This Been Tested

I tested this on many machines and concluded it is non-obtrusive. This will not break old versions and works with new ones

Types of changes

  • Dependency change
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • I have updated the documentation accordingly (index.d.ts).

@ricardoapaes
Copy link
Contributor

Good morning, but it's not running here because it doesn't find this require "__debug", how do I solve it?

image

@complanboy2
Copy link

Also, the "eval" function from inject.js file isn't running due to content security policy !!

@Shinhwe
Copy link

Shinhwe commented Mar 15, 2024

Good morning, but it's not running here because it doesn't find this require "__debug", how do I solve it?

image

try this
Object.values(window.require('__debug').modulesMap

@PurpShell PurpShell marked this pull request as draft March 16, 2024 15:25
@PurpShell
Copy link
Sponsor Collaborator Author

Good morning, but it's not running here because it doesn't find this require "__debug", how do I solve it?

image

Check the latest moduleRaid version

@PurpShell
Copy link
Sponsor Collaborator Author

Good morning, but it's not running here because it doesn't find this require "__debug", how do I solve it?
image

try this Object.values(window.require('__debug').modulesMap

pretty sure I did that, I will see if I didn't

@voidpack
Copy link

voidpack commented Mar 17, 2024

using nodejs v13 after apply new moduleraid on whatsapp web version Version 2.3000.1012111500 still got error

(node:10784) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')

@MoudiZd
Copy link

MoudiZd commented Mar 17, 2024

using nodejs v13 after apply new moduleraid on whatsapp web version Version 2.3000.1012111500 still got error

(node:10784) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')

I believe that the issue is not in the pr itself but in the way moduleRaid is used and the way is finding modules, used within injected.js, because in many cases it assumes that the findModule method returns non empty array, maybe with old webpack this way it was feasible but now with comet this code needs some optimization

I am not sure if the manipulation of these statements actually differs between node versions or between different modes, this need a lot of tests

@complanboy2
Copy link

ModuleError: Requiring module "%s" with unresolved dependencies: %s

Getting this error

@MoudiZd
Copy link

MoudiZd commented Mar 17, 2024

ModuleError: Requiring module "%s" with unresolved dependencies: %s

Getting this error

Please if you can print the full error so we can see in which file and in which line this error is occured

@complanboy2
Copy link

complanboy2 commented Mar 17, 2024

ModuleError: Requiring module "%s" with unresolved dependencies: %s
Getting this error

Please if you can print the full error so we can see in which file and in which line this error is occured

Thank you. I'm using module raid and the code from inject.js

@voidpack
Copy link

using nodejs v13 after apply new moduleraid on whatsapp web version Version 2.3000.1012111500 still got error
(node:10784) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')

I believe that the issue is not in the pr itself but in the way moduleRaid is used and the way is finding modules, used within injected.js, because in many cases it assumes that the findModule method returns non empty array, maybe with old webpack this way it was feasible but now with comet this code needs some optimization

I am not sure if the manipulation of these statements actually differs between node versions or between different modes, this need a lot of tests

maybe because i'm using backtick for this on module raid ? because without backtick it give error unexpected token '.' on nodejs v13

const isComet = parseInt(window.Debug?.VERSION?.split(".")?.[1]) >= 3000;

@mouhammad-zd
Copy link

mouhammad-zd commented Mar 17, 2024

using nodejs v13 after apply new moduleraid on whatsapp web version Version 2.3000.1012111500 still got error
(node:10784) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')

I believe that the issue is not in the pr itself but in the way moduleRaid is used and the way is finding modules, used within injected.js, because in many cases it assumes that the findModule method returns non empty array, maybe with old webpack this way it was feasible but now with comet this code needs some optimization
I am not sure if the manipulation of these statements actually differs between node versions or between different modes, this need a lot of tests

maybe because i'm using backtick for this on module raid ? because without backtick it give error unexpected token '.' on nodejs v13

const isComet = parseInt(window.Debug?.VERSION?.split(".")?.[1]) >= 3000;

Try to update your node version, as it seems that optional chaining is not supported in node older than node 14

@voidpack
Copy link

using nodejs v13 after apply new moduleraid on whatsapp web version Version 2.3000.1012111500 still got error
(node:10784) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')

I believe that the issue is not in the pr itself but in the way moduleRaid is used and the way is finding modules, used within injected.js, because in many cases it assumes that the findModule method returns non empty array, maybe with old webpack this way it was feasible but now with comet this code needs some optimization
I am not sure if the manipulation of these statements actually differs between node versions or between different modes, this need a lot of tests

maybe because i'm using backtick for this on module raid ? because without backtick it give error unexpected token '.' on nodejs v13
const isComet = parseInt(window.Debug?.VERSION?.split(".")?.[1]) >= 3000;

Try to update your node version, as it seems that optional chaining is not supported in node older than node 14

can't do it. because the client still using windows 7. latest support can only using node v13

@MoudiZd
Copy link

MoudiZd commented Mar 17, 2024

You must optimize code to use old javascript

using nodejs v13 after apply new moduleraid on whatsapp web version Version 2.3000.1012111500 still got error
(node:10784) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')

I believe that the issue is not in the pr itself but in the way moduleRaid is used and the way is finding modules, used within injected.js, because in many cases it assumes that the findModule method returns non empty array, maybe with old webpack this way it was feasible but now with comet this code needs some optimization
I am not sure if the manipulation of these statements actually differs between node versions or between different modes, this need a lot of tests

maybe because i'm using backtick for this on module raid ? because without backtick it give error unexpected token '.' on nodejs v13
const isComet = parseInt(window.Debug?.VERSION?.split(".")?.[1]) >= 3000;

Try to update your node version, as it seems that optional chaining is not supported in node older than node 14

can't do it. because the client still using windows 7. latest support can only using node v13

So you must optimize this statement to use old javascript

Try this:

var isComet = false;

if (window.Debug && window.Debug.VERSION) {
  var versionParts = window.Debug.VERSION.split(".");
  if (versionParts.length > 1) {
    var versionNumber = parseInt(versionParts[1]);
    isComet = versionNumber >= 3000;
  }
}

@maunklana
Copy link

maunklana commented Mar 18, 2024

I got this error

C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221
            throw new Error('Evaluation failed: ' + helper_js_1.helper.getExceptionMessage(exceptionDetails));
                  ^

Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')
    at __puppeteer_evaluation_script__:5:95
    at ExecutionContext._evaluateInternal (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ExecutionContext.evaluate (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:110:16)
    at async Client.initialize (C:\Users\Maunklana\Documents\ww\node_modules\whatsapp-web.js\src\Client.js:339:9)

Node.js v20.9.0

the error was caused by a change in the function

image

so I change the injected.js remove all .default

window.Store = Object.assign({}, window.mR.findModule(m => m && m.Chat)[1]);
window.Store.Call = window.mR.findModule((module) => module && module.Call)[0].Call;

Tested Sending & Receive Message is ok.

Update
Got this Error on Sending message on some text or something.

Error: Evaluation failed: Error: Data passed to getter must include an id property (it's how we memoize) but got undefined
	at new Error (<anonymous>:5:31)
	at h (https://static.whatsapp.net/rsrc.php/v3/yO/r/rP20sdRimEJ.js?_nc_x=Ij3Wp8lg5Kz:70:191)
	at t (https://static.whatsapp.net/rsrc.php/v3iex14/yT/l/makehaste_jhash/JjfhzrFnzpi.js?_nc_x=Ij3Wp8lg5Kz:391:4493)
	at Object.d [as getLinkPreview] (https://static.whatsapp.net/rsrc.php/v3iex14/yT/l/makehaste_jhash/JjfhzrFnzpi.js?_nc_x=Ij3Wp8lg5Kz:391:2447)
	at window.WWebJS.sendMessage (__puppeteer_evaluation_script__:135:62)
	at async __puppeteer_evaluation_script__:10:25
	at ExecutionContext._evaluateInternal (C:\Users\Maunklana\Documents\ww\node_modules\whatsapp-web.js\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19)
	at process.processTicksAndRejections (node:internal\process\task_queues:95:5)
	at async ExecutionContext.evaluate (C:\Users\Maunklana\Documents\ww\node_modules\whatsapp-web.js\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:110:16)
	at async Client.sendMessage (C:\Users\Maunklana\Documents\ww\node_modules\whatsapp-web.js\src\Client.js:930:28)

@voidpack
Copy link

I got this error

C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221
            throw new Error('Evaluation failed: ' + helper_js_1.helper.getExceptionMessage(exceptionDetails));
                  ^

Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')
    at __puppeteer_evaluation_script__:5:95
    at ExecutionContext._evaluateInternal (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ExecutionContext.evaluate (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:110:16)
    at async Client.initialize (C:\Users\Maunklana\Documents\ww\node_modules\whatsapp-web.js\src\Client.js:339:9)

Node.js v20.9.0

the error was caused by a change in the function

image

so I change the injected.js remove all .default

window.Store = Object.assign({}, window.mR.findModule(m => m && m.Chat)[1]); window.Store.Call = window.mR.findModule((module) => module && module.Call)[0].Call;

Tested Sending & Receive Message is ok.

i try remove that 2 line .default still error reading 'default'
and then i try remove all the .default on injected and got error reading 'on'

using node v13 and whatsapp web Version 2.3000.1012116664 (did your web version like mine ? i found that after 2.3000.xxxxx the number xxxxx keep increasing, maybe whatsapp keep updating or what ?)

@maunklana
Copy link

try following this change #2822

I got this error

C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221
            throw new Error('Evaluation failed: ' + helper_js_1.helper.getExceptionMessage(exceptionDetails));
                  ^

Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')
    at __puppeteer_evaluation_script__:5:95
    at ExecutionContext._evaluateInternal (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ExecutionContext.evaluate (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:110:16)
    at async Client.initialize (C:\Users\Maunklana\Documents\ww\node_modules\whatsapp-web.js\src\Client.js:339:9)

Node.js v20.9.0

the error was caused by a change in the function
image
so I change the injected.js remove all .default
window.Store = Object.assign({}, window.mR.findModule(m => m && m.Chat)[1]); window.Store.Call = window.mR.findModule((module) => module && module.Call)[0].Call;
Tested Sending & Receive Message is ok.

i try remove that 2 line .default still error reading 'default' and then i try remove all the .default on injected and got error reading 'on'

using node v13 and whatsapp web Version 2.3000.1012116664 (did your web version like mine ? i found that after 2.3000.xxxxx the number xxxxx keep increasing, maybe whatsapp keep updating or what ?)

@voidpack
Copy link

try following this change #2822

I got this error

C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221
            throw new Error('Evaluation failed: ' + helper_js_1.helper.getExceptionMessage(exceptionDetails));
                  ^

Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'default')
    at __puppeteer_evaluation_script__:5:95
    at ExecutionContext._evaluateInternal (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ExecutionContext.evaluate (C:\Users\Maunklana\Documents\ww\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:110:16)
    at async Client.initialize (C:\Users\Maunklana\Documents\ww\node_modules\whatsapp-web.js\src\Client.js:339:9)

Node.js v20.9.0

the error was caused by a change in the function
image
so I change the injected.js remove all .default
window.Store = Object.assign({}, window.mR.findModule(m => m && m.Chat)[1]); window.Store.Call = window.mR.findModule((module) => module && module.Call)[0].Call;
Tested Sending & Receive Message is ok.

i try remove that 2 line .default still error reading 'default' and then i try remove all the .default on injected and got error reading 'on'
using node v13 and whatsapp web Version 2.3000.1012116664 (did your web version like mine ? i found that after 2.3000.xxxxx the number xxxxx keep increasing, maybe whatsapp keep updating or what ?)

thx finally fix it. I miss the array [0] change to [1]. thx you very much

@maunklana maunklana mentioned this pull request Mar 19, 2024
6 tasks
@neb6la neb6la mentioned this pull request Mar 21, 2024
1 task
@Abhii-Agarwal09

This comment was marked as off-topic.

@MoudiZd MoudiZd mentioned this pull request Mar 31, 2024
1 task
@PurpShell PurpShell changed the title Farewell, Webpack! Farewell, Webpack! Also, patch for 2.24**!! Apr 2, 2024
@PurpShell PurpShell changed the title Farewell, Webpack! Also, patch for 2.24**!! Farewell, Webpack! Also, patch for 2.24xx.x!! Apr 3, 2024
@PurpShell PurpShell marked this pull request as ready for review April 3, 2024 00:53
Copy link
Collaborator

@tuyuribr tuyuribr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested the base functions and it's working, What are we waiting to commit this ?

example.js Outdated
@@ -5,19 +5,30 @@ const client = new Client({
// proxyAuthentication: { username: 'username', password: 'password' },
puppeteer: {
// args: ['--proxy-server=proxy-server-that-requires-authentication.example.com'],
headless: false
headless: true,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be false in the example ( so the first time user can see what is happening )

src/Client.js Outdated
});

await this.pupPage.exposeFunction('onOfflineProgressUpdateEvent', async (percent) => {
this.emit(Events.LOADING_SCREEN, percent, 'WhatsApp'); // Message is hardcoded as "WhatsApp" for now
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's missing if (lastPercent !== percent || lastPercentMessage !== message) {, it's proposital ?

return (fs.rmSync ? fs.rmSync : fs.rmdirSync).call(this, this.userDataDir, { recursive: true, force: true });
await fs.promises.rm(this.userDataDir, { recursive: true, force: true })
.catch(() => {
return this.logout();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catch should just give-up right? Won't this run forever if something breaks on the promise ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the directory change ?

const version = indexHtml.match(/manifest-([\d\\.]+)\.json/)[1];
if(!version) return;

async persist(indexHtml, version) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should sanitize the version here, only allow Numbers and dots

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add this to make new users catch errors:

client.pupPage.on("pageerror", function(err) {
            console.log("Page error: " + err.toString());
        });
        client.pupPage.on("error", function(err) {
            console.log("Page error: " + err.toString());
        });

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

@tuyuribr
Copy link
Collaborator

image
Page error: Error: Page crashed!

@alechkos alechkos added waiting for testers Waiting for other people test this PR in other envs breaking change Fix or feature that would cause existing functionality to change labels May 14, 2024
…3001)

* Change window.Store.ProfilePic.profilePicFind to window.Store.ProfilePic.requestProfilePicFromServer

* Prevent breaking v2.2x

* refactor: make it more readable

---------

Co-authored-by: alechkos <[email protected]>
tuyuribr and others added 3 commits May 15, 2024 14:09
* fix getInviteCode for group (#3007)

* move changes to proper getInviteCode method.

* style fix

* refactor: add try-catch in a case the user is not a group admin

* refactor: handle promise properly

---------

Co-authored-by: Sven Neumann <[email protected]>
Co-authored-by: alechkos <[email protected]>
@mission-sun
Copy link

Has anyone encountered a similar problem? When sending an image larger than 20M, an error will occur: Error: Evaluation failed: b

@DenysSamoiliuk
Copy link

DenysSamoiliuk commented May 16, 2024

hi, please tell me if you know what caused this error Initialize error: Waiting for selector [data-icon='search'] failed: Protocol error (Runtime.callFunctionOn): Target closed. and how to deal with it, we use this branch in the project, but periodically when we have to reload the docker container in k3s we get this log when initializing the session. I use version 2.3000.xxxx and also the latest 2.24xxx, but I got the same result

@alechkos alechkos mentioned this pull request May 16, 2024
1 task
@tofers
Copy link
Contributor

tofers commented May 17, 2024

Update the branch with main, please
I need to check vote_update

@TechnVision
Copy link

node_modules/whatsapp-web.js/index.d.ts:124:49 - error TS2371: A parameter initializer is only allowed in a function or constructor implementation.

124 requestPairingCode(phoneNumber: string, showNotification = true): Promise

I'm this error on logon easy fix requestPairingCode(phoneNumber: string, showNotification: true): Promise<string>

@wildandahru
Copy link

after install npm install github:pedroslopez/whatsapp-web.js#webpack-exodus qrcode didn't show up. I tried to change headless to false and the qr just stuck in load state.

@tofers
Copy link
Contributor

tofers commented May 19, 2024

/usr/src/app/node_modules/whatsapp-web.js/src/authStrategies/LocalAuth.js:49
                    throw new Error(e);
                          ^

Error: Error: ENOTEMPTY: directory not empty, rmdir '/sessions/3080405618/Default'
    at /usr/src/app/node_modules/whatsapp-web.js/src/authStrategies/LocalAuth.js:49:27
    at async LocalAuth.logout (/usr/src/app/node_modules/whatsapp-web.js/src/authStrategies/LocalAuth.js:47:13)
    at async /usr/src/app/node_modules/whatsapp-web.js/src/Client.js:345:1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Fix or feature that would cause existing functionality to change waiting for testers Waiting for other people test this PR in other envs
Projects
None yet