Compare commits

...

46 Commits

Author SHA1 Message Date
Pedro Lopez
c0ef9223ed chore: mark version 1.16.7 2022-06-09 23:57:17 -04:00
github-actions[bot]
294e5027b0 Update supported WhatsApp Web version to v2.2220.8 (#1416)
Co-authored-by: pedroslopez <pedroslopez@users.noreply.github.com>
2022-06-09 23:47:17 -04:00
Shir Serlui
ebc56bc280 fix: correctly get models and fetchMessages in WhatsApp Web v2.2220.8
* Fix models is undefined

* Feat models is undefined

* Feat models is undefined

* Fix loadEarlierMsgs

* use `getModelsArray()` to get models

* fix: correctly loadEarlierMsgs with ConversationMsgs module

Co-authored-by: Pedro Lopez <pedroslopez@me.com>
2022-06-09 23:41:25 -04:00
Pedro Lopez
b16e1cdf83 chore: mark version 1.16.6 2022-04-21 17:58:08 -04:00
github-actions[bot]
a24294ec61 Update supported WhatsApp Web version to v2.2212.8 (#1381)
Co-authored-by: pedroslopez <pedroslopez@users.noreply.github.com>
2022-04-21 17:32:42 -04:00
Pedro Lopez
374983b9a6 fix: find old features module 2022-04-21 17:18:47 -04:00
Rajeh Taher
5e2e9dd139 Fix: Cannot read properties of undefined (reading 'features') // original: (#1407) (#1410)
* Fix: Cannot read properties of undefined (reading 'features') (#1407)

* Fix: Cannot read properties of undefined (reading 'features')

Find MD backend without features

* Fix for tests

* Update Client.js

* Update LegacySessionAuth.js

Co-authored-by: Shir Serlui <70711723+shirser121@users.noreply.github.com>
2022-04-21 17:15:00 -04:00
Pedro Lopez
3a2acf71c2 chore: mark version v1.16.5 2022-03-28 23:47:16 -04:00
Pedro Lopez
f32f3c71ba fix: get groupnotification chat
close #1329
2022-03-28 23:44:04 -04:00
github-actions[bot]
017dd4b783 Update supported WhatsApp Web version to v2.2210.9 (#1340)
Co-authored-by: pedroslopez <pedroslopez@users.noreply.github.com>
2022-03-28 23:28:09 -04:00
Ahmed Fouzan
fa9f6610d7 fix(typings): Add ConnectOptions typings (#1354)
* Add ConnectOptions typings

* simplify type

Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2022-03-28 23:22:51 -04:00
༺ LᴇG̸ᴇɴD ༻
e9104b390d Fix: Cannot read properties of undefined (reading 'getProfilePicFull') (#1362)
* Fix for issue#1356 - Cannot read properties of undefined reading getProfilePicFull

* use cross-compatible profilePicFind function

Co-authored-by: Joaquin Touris <joaquin@192.168.1.6>
Co-authored-by: Pedro Lopez <pedroslopez@me.com>
2022-03-28 23:17:55 -04:00
ogxing
a23c285f3c fix: group chat create (#1319) 2022-03-28 22:56:07 -04:00
github-actions[bot]
281aec40ad Update supported WhatsApp Web version to v2.2208.7 (#1287)
Co-authored-by: pedroslopez <pedroslopez@users.noreply.github.com>
Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2022-03-09 18:32:04 -04:00
Pedro Lopez
2e4890d113 chore: mark version v1.16.4 2022-03-09 18:26:05 -04:00
Pedro Lopez
0bd8eb9d96 chore: mark version v1.16.4-alpha.0 2022-03-09 00:57:36 -04:00
Pedro S. Lopez
2718c1328c fix compatibility issues with WhatsApp Web 2.2208.7 (#1311)
* fix compatiblity issues with v2.2208.7

* remove expclusive test
2022-03-09 00:54:57 -04:00
Pedro Lopez
24f8b4622b chore: mark version v1.16.3 2022-03-06 23:30:20 -04:00
Pedro Lopez
9ab9c48f7b fix(typings): LegacySessionAuth restartOnAuthFail 2022-03-06 01:35:58 -04:00
༺ LᴇG̸ᴇɴD ༻
b96607338a getProfilePicture Fix => Evaluation failed: Error: Comms::sendIq called before startComms (#1264)
* Fix: Evaluation failed: Error: Comms::sendIq called before startComms

* [Requested Changes] - Only call Wap if we're not on MD & vice-versa

Co-authored-by: Joaquin Touris <joaquin@192.168.1.5>
2022-03-05 16:24:40 +02:00
Pedro S. Lopez
ea2cc81d47 add feature request form template 2022-03-05 02:30:49 -04:00
Clifford Fajardo
56644f4f03 add github ISSUE_TEMPLATE files (#1195)
* add github ISSUE_TEMPLATE files

* Update .github/ISSUE_TEMPLATE/config.yml

* Update .github/ISSUE_TEMPLATE/bug_report.yml

Co-authored-by: Rajeh Taher <rajeh@reforward.dev>

* apply updates per feedback that was given

* Update bug_report.yml

* Update bug_report.yml

* Update bug_report.yml

* Update bug_report.yml

* Update bug_report.yml

* Update bug_report.yml

Co-authored-by: clifford <cfajardo@linkedin.com>
Co-authored-by: Rajeh Taher <rajeh@reforward.dev>
Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2022-03-05 02:26:49 -04:00
Pedro Lopez
fcb78a1cd4 chore: mark version v1.16.2 2022-03-01 23:23:26 -04:00
Fábio Dias
f88bd274be fix(LocalAuth): logout method (#1267)
The logout method was trying to use a function call passing the "dataDir" as the "this" reference
2022-03-01 23:15:08 -04:00
Alon Schwartzblat
c45fae5c15 Fix get order. (#1274)
* Fix get order.

* Fix types.
2022-03-01 23:08:27 -04:00
Pedro Lopez
1b75d0d243 fix(LocalAuth): only throw user-supplied userDataDir error if path is different
fix #1261
2022-03-01 22:25:22 -04:00
Filipe
cc78e9863d add typings for LocalAuth attributes (#1262) 2022-02-28 23:00:21 -04:00
inceabdullah
fc205ff530 fix: Cannot destructure property 'session' of 'undefined' as it is undefined. (#1259) 2022-02-28 22:59:54 -04:00
Pedro Lopez
6ab98a5365 chore: mark version v1.16.1 2022-02-28 00:51:59 -04:00
Pedro Lopez
3c24df085a add back deprecated info.me 2022-02-28 00:51:28 -04:00
Pedro Lopez
979e97ea42 chore: mark version v1.16.0 2022-02-27 23:30:03 -04:00
Pedro Lopez
1f4328c7a3 fix tests 2022-02-27 23:29:09 -04:00
Pedro Lopez
6691d25282 fix: message.getInfo() works for both MD and non-MD 2022-02-27 23:28:57 -04:00
Pedro S. Lopez
12d9735b73 Update README.md 2022-02-27 22:58:39 -04:00
SuperChang
ab5167c4ad fix: ChangeParticipantsPermissions typo in index.d.ts (#1206)
Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2022-02-27 22:34:12 -04:00
YaronD
52c8336236 Added message duration in seconds (#1230)
Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2022-02-27 22:30:47 -04:00
Pedro Lopez
9fe91692cf update tests to work with authStrategies 2022-02-27 22:18:54 -04:00
Pedro S. Lopez
f6de161c7d Auth Strategies (#1257)
* auth strategies

* default to no auth

* rename base auth strategy

* rename base strategy cont.

* refactor auth strategy methods and LocalAuth

* activate old session options even if is falsy value

* move restartOnAuthFail to LegacyAuthStrategy option

* add link to guide item

* update example/shell

* types
2022-02-27 22:02:49 -04:00
Rajeh Taher
0d55d40885 feat: Multi-device support (#889)
* 🚑 Added ready selector for multi-device

* SendMessage fix

* File management system and some fixes

* cleanup

* cleanup again

* eslint

* critical fix for reloading the same session

* Checking for valid folder name (regex)

* ESLint hotfix (regex escapes)

* Typings cleanup

* cleanup listener

* Multi-device Branch merge (#888)

* Duplicate

* qr fix and allow non-beta users to connect

* urgent: selector fix

* urgent: qr timeout fix

* fix

* Updated type so no TS error when sending list/buttons

* Update index.d.ts

* fix QueryExist for Multidevice (#928)

* creates isRegisteredUserBeta

* fix QueryExist

* fix Error: GROUP_JID: invalid jid type: Not an instance of WID issue (#926)

* fix Error: GROUP_JID: invalid jid type: Not an instance of WID issue

* clean code

* Cleanup

* Fix for update chrome error

* ESLint fix

* :red_light: fix for RMDIR

* Update README.md

* Update README.md

* fix: getProfilePicUrl fix by victormga (#941)

* fix: MD presence available/unavailable (#942)

* delete session when appropriate & fix for SW

* ignore QR timeout errors

* Presence and ChatState updates working for MD+Non-MD

* shell uses new session storage

* lint fix

* support session.json-based auth for non-md

* md fix

* md fix

* fix shell clientId

* remove exclusive mocha test

* make linkPreview default to false

* remove ignored errors on getQuotedMessage

* fix: dont modify existing this.options.puppeteer object

* tests work with new dir auth

* remove exclusive test

* fixes and tests for group creation and participant functions

* remove unused function

* wip fix group settings functions

* isRegisteredUser && getNumberId hotFix (#955)

* isRegisteredUser && getNumberId hotFix

A fix for client.isRegisteredUser and client.getNumberId. Use for reference or if you are stuck with MD and NEEDS this function. Problably Whatsapp will break this in a couple weeks

* fix for non-md

Co-authored-by: Rajeh Taher <rajeh@reforward.dev>

* Fix WA 2.2146.9 MD +  victormga branch (#991)

* qrcode now uses observers instead of timeout

* automatic auth/qrcode detection

* Fix WA 2.2146.9 MD

Got from github:victormga/whatsapp-web.js#multidevice maybe it's behind pedro branch

Co-authored-by: victormga <victor_mga@hotmail.com>

* fix

* fix*

* getnumberid to multidevice (#1027)

* getNumberId to main

 isRegisteredUser && getNumberId hotFix #955 To main

* Update Client.js

Co-authored-by: tuyuribr <45042245+tuyuribr@users.noreply.github.com>

* Update Client.js

* Message.raw() (#1005)

* Message.raw()

* i just noticed

* Update index.d.ts

* Update index.d.ts

* Update Message.js

* Get rid of sharp now!!!!!!!! (#1045)

* commit 1

* finally, gotten rid of sharp

* pckg.json

* service worker fix & disableMessage option

* typings

* Update example.js

* clear session system

* Update Client.js

* Update Client.js

* Fix accepting group private invite (#1094)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* [MD] Add getCommonGroups with specific user. (#1097)

* Add getCommonGroups with specific user.

* Fix

* Fix

* Fix

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Fix getCommonGroups. (#1122)

* Fix of Unexpected identifier async destroy() (#1123)

* Fix of Unexpected identifier async destroy()

* Fix made in #1107

* Temporary fix for "Sticker" module

* some really quick changes

* Update Injected.js

* Update Injected.js

* Update index.d.ts

* fix: getNumberId Solved (#1142)

* getNumberId Solved

* isRegisteredUser Solved

* formmated

* Apply suggestions from code review

* Update src/util/Injected.js

Co-authored-by: Rajeh Taher <rajeh@reforward.dev>

* Fix: "Chrome user data dir was not found ..."

fixes the error caused by puppeteer.

* Update Client.js (#1154)

* fix: getNumberId and isRegisteredUser (#1159)

* fix: getNumberId and isRegisteredUser

* Apply suggestions from code review

Co-authored-by: Rajeh Taher <rajeh@reforward.dev>

* Update client.js

* Update Injected.js

* Update Client.js

* Update index.d.ts

* Update Client.js

* Update Client.js

* fix lint indentation

* fix auth_failure event for non-md, tests

* fix setting group subject

* fix finding Label module

* set remember-me after clearing localStorage

* fix: send messages to groups correctly on MD, use new ID format

* fix setting / getting contact status

* fix msg.getInfo, add message tests

* fix group settings functions

* fix set group description, handle errors in setSubject

* fix group invite functions

* fix leaving group

* bring back phone info for non-md users

* remove unused option, update typings

* add back jsdoc for qr event

* fix setting sticker metadata, clean up sticker functions

* rawData is a get only property

* fix and simplify getNumberId/isRegisteredUser

* fix getInviteInfo

* setDisplayName returns bool, not yet implemented for md

* fix: stream module (#1241)

* linkPreview has no effect on MD, return default to true

* fix: del linkPreview option on md

* cleanup, types and docs updates

* update readmes / test notes

* remove DS_Store

* DS_Store in gitignore

* test stability (timeouts/sleeps)

Co-authored-by: Rajeh Taher <rajeh@reforward.tk>
Co-authored-by: Gustavo B <52040719+Gugabit@users.noreply.github.com>
Co-authored-by: Maikel Ortega Hernández <maikeloh@gmail.com>
Co-authored-by: victormga <victor_mga@hotmail.com>
Co-authored-by: Pedro Lopez <pedroslopez@me.com>
Co-authored-by: tuyuribr <45042245+tuyuribr@users.noreply.github.com>
Co-authored-by: gon <68490103+nekiak@users.noreply.github.com>
Co-authored-by: Alon Schwartzblat <63599777+Schwartzblat@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Šebestíček <44745014+SebestikCZ@users.noreply.github.com>
Co-authored-by: Emmanuel Anaya Luna <38712443+KeruMx@users.noreply.github.com>
Co-authored-by: L337C0D3R <51872799+L337C0D3R@users.noreply.github.com>
Co-authored-by: Reni Delonzek <renidelonzek@gmail.com>
2022-02-27 18:51:08 -04:00
Pedro Lopez
8ef37b68ae chore: mark version v1.15.8 2022-02-25 17:45:33 -04:00
github-actions[bot]
bd5cfdc936 Update supported WhatsApp Web version to v2.2206.5 (#1247)
Co-authored-by: pedroslopez <pedroslopez@users.noreply.github.com>
2022-02-25 17:43:30 -04:00
༺ LᴇG̸ᴇɴD ༻
f0e49efcf9 [Main Branch]: Fix Cannot read properties of undefined (reading 'Socket') (#1249)
Co-authored-by: Joaquin Touris <joaquin@192.168.1.5>
2022-02-25 17:11:28 -04:00
Pedro Lopez
5d83b45ed4 chore: mark version v1.15.7 2022-02-19 15:48:03 -04:00
github-actions[bot]
e29354fca3 Update supported WhatsApp Web version to v2.2204.13 (#1210)
Co-authored-by: pedroslopez <pedroslopez@users.noreply.github.com>
2022-02-19 15:45:21 -04:00
Shir Serlui
66283da903 Fix message.delete(true) (#1211)
* Fix message.delete(true)

* Fix for tests
2022-02-19 15:31:23 -04:00
Tomas Melone
d7f7889b0f fix: Remove duplicate identifier (#1205) 2022-02-19 15:18:34 -04:00
90 changed files with 3256 additions and 1417 deletions

View File

@@ -1,2 +1,3 @@
WWEBJS_TEST_SESSION_PATH=test_session.json WWEBJS_TEST_REMOTE_ID=XXXXXXXXXX@c.us
WWEBJS_TEST_REMOTE_ID=XXXXXXXXXX@c.us WWEBJS_TEST_CLIENT_ID=authenticated
WWEBJS_TEST_MD=1

View File

@@ -1,41 +0,0 @@
---
name: Bug report
about: Is something not working as intended? Report it here.
title: ''
assignees: ''
---
### Bug description
A clear and concise description of what the bug is.
### Reproduction steps
Steps to reproduce the behavior:
1.
2.
3.
...
### Expected behavior
A clear and concise description of what you expected to happen.
### Relevant code
If applicable, add code snippets to help explain your problem.
### Environment (please complete the following information):
**WhatsApp**
- Account type [Standard / Business]:
- Device OS [iOS / Android]:
- WhatsApp Web version [run `await client.getWWebVersion()`]:
**Library**
- Browser [Chrome / Chromium]:
- NodeJS version (`node -v`):
- npm or yarn version (`npm -v`):
- whatsapp-web.js version:
**Other**
- Operating system (the one running node) [Linux / MacOS / Windows]:
- Operating system version (ex. Windows 10):
### Additional context
Add any other context about the problem here.

105
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,105 @@
name: '🐛 Bug report'
description: Create a report to help us improve
labels: bug
body:
- type: markdown
attributes:
value: |
Thank you for reporting an issue :pray:.
This issue tracker is for reporting bugs found in [`whatsapp-web.js`](https://github.com/pedroslopez/whatsapp-web.js).
If you have a question about how to achieve something and are struggling, please post a question in our [Discord server](https://discord.gg/wyKybbF) instead.
Before submitting a new bug/issue, please check the links below to see if there is a solution or question posted there already:
- `whatsapp-web.js` [Issues tab](https://github.com/pedroslopez/whatsapp-web.js/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc)
- `whatsapp-web.js` [closed Issues tab](https://github.com/pedroslopez/whatsapp-web.js/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aclosed)
The more information you fill in, the better the community can help you.
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
id: description
attributes:
label: Describe the bug
description: Provide a clear and concise description of the challenge you are running into.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
description: Provide a clear and concise description of what you expected to happen.
placeholder: |
As a user, I expected ___ behavior but I am seeing ___
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to Reproduce the Bug or Issue
description: Describe the steps we have to take to reproduce the behavior.
placeholder: |
1. Do X
2. Do Y
3. Do Z
4. See error
validations:
required: true
- type: textarea
id: relevant_code
attributes:
label: Relevant Code
description: If applicable, add code snippets to help explain your problem.
validations:
required: false
- type: dropdown
id: browser_type
attributes:
label: Browser Type
description: What web browser are you using?
options:
- Chromium
- Google Chrome
- Other (please write in Additional Context)
validations:
required: true
- type: dropdown
id: whatsapp_type
attributes:
label: WhatsApp Account Type
options:
- Standard
- WhatsApp Business
validations:
required: true
- type: dropdown
id: multidevice
attributes:
label: Does your WhatsApp account have multidevice enabled?
options:
- Yes, I am using Multi Device
- No, I am not using Multi Device
validations:
required: true
- type: textarea
attributes:
label: Environment
description: |
- OS: [e.g. Mac, Windows, Linux, Docker + Ubuntu 18, etc]
- Phone OS: [e.g. Android, iOS]
- whatsapp-web.js version [e.g. 1.2.3]
- WhatsApp Web version [run `await client.getWWebVersion()`]:
- Node.js Version [e.g. 1.2.3]
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional context
description: Add any other context about the problem here.

View File

@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -0,0 +1,42 @@
name: 🚀 Feature request
description: Suggest an idea for this project
labels: enhancement
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue related to this feature request already exists.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Is your feature request related to a problem? Please describe.
description: A concise description of the problem you are facing or the motivetion behind this feature request.
placeholder: I faced a problem due to ...
validations:
required: false
- type: textarea
attributes:
label: Describe the solution you'd like.
description: A concise description of the solution for the issue.
validations:
required: true
- type: textarea
attributes:
label: Describe an alternate solution.
description: Is there any other approach to solve the problem?
validations:
required: false
- type: textarea
attributes:
label: Additional context
description: |
Links? Screenshots? References? Anything that will give us more context about what you would like to see!
validations:
required: false

6
.gitignore vendored
View File

@@ -64,8 +64,10 @@ typings/
# next.js build output # next.js build output
.next .next
# macOS Thumbnails # macOS
._* ._*
.DS_Store
# Test sessions # Test sessions
*session.json *session.json
.wwebjs_auth/

View File

@@ -12,6 +12,8 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
*session.json *session.json
.wwebjs_auth/
.env .env
tools/ tools/
tests/ tests/

View File

@@ -1,4 +1,4 @@
[![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js) [![Depfu](https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg)](https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765) ![WhatsApp_Web 2.2202.12](https://img.shields.io/badge/WhatsApp_Web-2.2202.12-brightgreen.svg) [![Discord Chat](https://img.shields.io/discord/698610475432411196.svg?logo=discord)](https://discord.gg/H7DqQs4) [![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js) [![Depfu](https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg)](https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765) ![WhatsApp_Web 2.2220.8](https://img.shields.io/badge/WhatsApp_Web-2.2220.8-brightgreen.svg) [![Discord Chat](https://img.shields.io/discord/698610475432411196.svg?logo=discord)](https://discord.gg/H7DqQs4)
# whatsapp-web.js # whatsapp-web.js
A WhatsApp API client that connects through the WhatsApp Web browser app A WhatsApp API client that connects through the WhatsApp Web browser app
@@ -47,43 +47,14 @@ client.initialize();
Take a look at [example.js](https://github.com/pedroslopez/whatsapp-web.js/blob/master/example.js) for another example with more use cases. Take a look at [example.js](https://github.com/pedroslopez/whatsapp-web.js/blob/master/example.js) for another example with more use cases.
## Remote Access For more information on saving and restoring sessions, check out the available [Authentication Strategies](https://wwebjs.dev/guide/authentication.html).
You could also connect to any previously existing browser instance:
```js
const client = new Client({
puppeteer: {
browserWSEndpoint: `ws://localhost:3000`
}
});
```
### Docker
1) Installing a browser using browserless:
```
docker run \
--rm \
-p 3000:3000 \
-e "MAX_CONCURRENT_SESSIONS=1" \
browserless/chrome:latest
```
Reference: https://docs.browserless.io/docs/docker-quickstart.html
### Remote Debugging
2) Running a browser with websocket remote debugging enabled:
> chrome.exe --remote-debugging-port=9222
After that check the following webpage and check http://127.0.0.1:9220/json and get the **webSocketDebuggerUrl**
## Supported features ## Supported features
| Feature | Status | | Feature | Status |
| ------------- | ------------- | | ------------- | ------------- |
| Multi Device | ✅ |
| Send messages | ✅ | | Send messages | ✅ |
| Receive messages | ✅ | | Receive messages | ✅ |
| Send media (images/audio/documents) | ✅ | | Send media (images/audio/documents) | ✅ |
@@ -116,11 +87,13 @@ Something missing? Make an issue and let us know!
Pull requests are welcome! If you see something you'd like to add, please do. For drastic changes, please open an issue first. Pull requests are welcome! If you see something you'd like to add, please do. For drastic changes, please open an issue first.
## Donating ## Supporting the project
You can support the maintainer of this project through the link below You can support the maintainer of this project through the links below
[![Support via PayPal](https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg)](https://www.paypal.me/psla/) - [Support via GitHub Sponsors](https://github.com/sponsors/pedroslopez)
- [Support via PayPal](https://www.paypal.me/psla/)
- [Sign up for DigitalOcean](https://m.do.co/c/73f906a36ed4) and get $100 in credit when you sign up (Referral)
## Disclaimer ## Disclaimer

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Base</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Base</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -50,7 +50,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -0,0 +1,65 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Class: BaseAuthStrategy</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-main" role="main">
<header class="page-header">
<div class="symbol-detail-labels"><span class="label label-kind">class</span></div>
<h1><small></small><span class="symbol-name">BaseAuthStrategy</span></h1>
<p class="source-link">Source: <a href="authStrategies_BaseAuthStrategy.js.html#source-line-6">authStrategies/<wbr>BaseAuthStrategy.<wbr>js:6</a></p>
<div class="symbol-classdesc">
<p>Base class which all authentication strategies extend</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
</section>
<section>
<h2 id="BaseAuthStrategy">new&nbsp;<span class="symbol-name">BaseAuthStrategy</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
</dl>
</section>
<section>
</section>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: BusinessContact</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: BusinessContact</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -111,19 +111,22 @@
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="BusinessContact.html#getCommonGroups">getCommonGroups()</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#getCountryCode">getCountryCode()</a></dt> <dt><a href="BusinessContact.html#getCountryCode">getCountryCode()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="BusinessContact.html#getFormattedNumber">getFormattedNumber()</a></dt> <dt><a href="BusinessContact.html#getFormattedNumber">getFormattedNumber()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="BusinessContact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
</dl> </dl>
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="BusinessContact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#unblock">unblock()</a></dt> <dt><a href="BusinessContact.html#unblock">unblock()</a></dt>
<dd> <dd>
</dd> </dd>
@@ -269,6 +272,15 @@
<dd></dd> <dd></dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getCommonGroups"><span class="symbol-name">getCommonGroups</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of WAWebJS.ChatId</span></span></h3>
<p>Gets the Contact's common groups with you. Returns empty array if you don't have any common group.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#getCommonGroups">Contact#getCommonGroups</a></dd>
<dt>Returns</dt>
<dd></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getCountryCode"><span class="symbol-name">getCountryCode</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing string</span></span></h3> <h3 id="getCountryCode"><span class="symbol-name">getCountryCode</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing string</span></span></h3>
<p>Returns the contact's countrycode, (1541859685@c.us) =&gt; (1)</p> <p>Returns the contact's countrycode, (1541859685@c.us) =&gt; (1)</p>
<dl class="dl-compact"> <dl class="dl-compact">
@@ -314,7 +326,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Buttons</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Buttons</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -234,7 +234,7 @@ Returns: [{ buttonId:&#x27;customId&#x27;,buttonText:{&#x27;displayText&#x27;:&#
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Call</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Call</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -144,7 +144,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Chat</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Chat</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -483,7 +483,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Client</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Client</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -26,7 +26,7 @@
<header class="page-header"> <header class="page-header">
<div class="symbol-detail-labels"><span class="label label-kind">class</span></div> <div class="symbol-detail-labels"><span class="label label-kind">class</span></div>
<h1><small></small><span class="symbol-name">Client</span></h1> <h1><small></small><span class="symbol-name">Client</span></h1>
<p class="source-link">Source: <a href="Client.js.html#source-line-53">Client.<wbr>js:53</a></p> <p class="source-link">Source: <a href="Client.js.html#source-line-49">Client.<wbr>js:49</a></p>
<div class="symbol-classdesc"> <div class="symbol-classdesc">
<p>Starting point for interacting with the WhatsApp Web API</p> <p>Starting point for interacting with the WhatsApp Web API</p>
</div> </div>
@@ -55,7 +55,7 @@
<div class="summary-content"> <div class="summary-content">
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="Client.html#acceptGroupV4Invite">acceptGroupV4Invite(inviteV4)</a></dt> <dt><a href="Client.html#acceptGroupV4Invite">acceptGroupV4Invite(inviteInfo)</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Client.html#acceptInvite">acceptInvite(inviteCode)</a></dt> <dt><a href="Client.html#acceptInvite">acceptInvite(inviteCode)</a></dt>
@@ -85,19 +85,22 @@
<dt><a href="Client.html#getChatsByLabelId">getChatsByLabelId(labelId)</a></dt> <dt><a href="Client.html#getChatsByLabelId">getChatsByLabelId(labelId)</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Client.html#getCommonGroups">getCommonGroups(contactId)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#getContactById">getContactById(contactId)</a></dt> <dt><a href="Client.html#getContactById">getContactById(contactId)</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Client.html#getContacts">getContacts()</a></dt> <dt><a href="Client.html#getContacts">getContacts()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Client.html#getCountryCode">getCountryCode(number)</a></dt>
<dd>
</dd>
</dl> </dl>
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="Client.html#getCountryCode">getCountryCode(number)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#getFormattedNumber">getFormattedNumber(number)</a></dt> <dt><a href="Client.html#getFormattedNumber">getFormattedNumber(number)</a></dt>
<dd> <dd>
</dd> </dd>
@@ -134,13 +137,13 @@
<dt><a href="Client.html#markChatUnread">markChatUnread(chatId)</a></dt> <dt><a href="Client.html#markChatUnread">markChatUnread(chatId)</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Client.html#muteChat">muteChat(chatId, unmuteDate)</a></dt>
<dd>
</dd>
</dl> </dl>
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="Client.html#muteChat">muteChat(chatId, unmuteDate)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#pinChat">pinChat()</a></dt> <dt><a href="Client.html#pinChat">pinChat()</a></dt>
<dd> <dd>
</dd> </dd>
@@ -156,6 +159,9 @@
<dt><a href="Client.html#sendPresenceAvailable">sendPresenceAvailable()</a></dt> <dt><a href="Client.html#sendPresenceAvailable">sendPresenceAvailable()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Client.html#sendPresenceUnavailable">sendPresenceUnavailable()</a></dt>
<dd>
</dd>
<dt><a href="Client.html#sendSeen">sendSeen(chatId)</a></dt> <dt><a href="Client.html#sendSeen">sendSeen(chatId)</a></dt>
<dd> <dd>
</dd> </dd>
@@ -284,6 +290,20 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr>
<td>
<p>authStrategy</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used.</p>
</td>
</tr>
<tr> <tr>
<td> <td>
<p>authTimeoutMs</p> <p>authTimeoutMs</p>
@@ -312,34 +332,6 @@
<p>Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/</p> <p>Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/</p>
</td> </td>
</tr> </tr>
<tr>
<td>
<p>qrRefreshIntervalMs</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Refresh interval for qr code (how much time to wait before checking if the qr code has changed)</p>
</td>
</tr>
<tr>
<td>
<p>qrTimeoutMs</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Timeout for qr code selector in puppeteer</p>
</td>
</tr>
<tr> <tr>
<td> <td>
<p>qrMaxRetries</p> <p>qrMaxRetries</p>
@@ -365,7 +357,7 @@
<p>&nbsp;</p> <p>&nbsp;</p>
</td> </td>
<td> <td>
<p>Restart client with a new session (i.e. use null 'session' var) if authentication fails</p> <p>@deprecated This option should be set directly on the LegacySessionAuth.</p>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -379,59 +371,7 @@
<p>&nbsp;</p> <p>&nbsp;</p>
</td> </td>
<td> <td>
<p>Whatsapp session to restore. If not set, will start a new session</p> <p>@deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.</p>
</td>
</tr>
<tr>
<td>
<p>session.WABrowserId</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>session.WASecretBundle</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>session.WAToken1</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>session.WAToken2</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -530,7 +470,6 @@
<dd><a href="Client.html#event:group_update">Client#event:group_update</a></dd> <dd><a href="Client.html#event:group_update">Client#event:group_update</a></dd>
<dd><a href="Client.html#event:disconnected">Client#event:disconnected</a></dd> <dd><a href="Client.html#event:disconnected">Client#event:disconnected</a></dd>
<dd><a href="Client.html#event:change_state">Client#event:change_state</a></dd> <dd><a href="Client.html#event:change_state">Client#event:change_state</a></dd>
<dd><a href="Client.html#event:change_battery">Client#event:change_battery</a></dd>
</dl> </dl>
</section> </section>
<section> <section>
@@ -545,7 +484,7 @@
<h2>Methods</h2> <h2>Methods</h2>
<section> <section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="acceptGroupV4Invite"><span class="symbol-name">acceptGroupV4Invite</span><span class="signature"><span class="signature-params">(inviteV4)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Object</span></span></h3> <h3 id="acceptGroupV4Invite"><span class="symbol-name">acceptGroupV4Invite</span><span class="signature"><span class="signature-params">(inviteInfo)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Object</span></span></h3>
<p>Accepts a private invitation to join a group</p> <p>Accepts a private invitation to join a group</p>
<section> <section>
<h4>Parameter</h4> <h4>Parameter</h4>
@@ -561,7 +500,7 @@
<tbody> <tbody>
<tr> <tr>
<td> <td>
<p>inviteV4</p> <p>inviteInfo</p>
</td> </td>
<td> <td>
<p>object</p> <p>object</p>
@@ -830,6 +769,44 @@
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getCommonGroups"><span class="symbol-name">getCommonGroups</span><span class="signature"><span class="signature-params">(contactId)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of WAWebJS.ChatId</span></span></h3>
<p>Gets the Contact's common groups with you. Returns empty array if you don't have any common group.</p>
<section>
<h4>Parameter</h4>
<table class="jsdoc-details-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>contactId</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>the whatsapp user's ID (_serialized format)</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Array of WAWebJS.ChatId</code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getContactById"><span class="symbol-name">getContactById</span><span class="signature"><span class="signature-params">(contactId)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Contact.html">Contact</a></span></span></h3> <h3 id="getContactById"><span class="symbol-name">getContactById</span><span class="signature"><span class="signature-params">(contactId)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Contact.html">Contact</a></span></span></h3>
<p>Get contact instance by ID</p> <p>Get contact instance by ID</p>
<section> <section>
@@ -1452,6 +1429,11 @@
<dl class="dl-compact"> <dl class="dl-compact">
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendPresenceUnavailable"><span class="symbol-name">sendPresenceUnavailable</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Marks the client as unavailable</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendSeen"><span class="symbol-name">sendSeen</span><span class="signature"><span class="signature-params">(chatId)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing boolean</span></span></h3> <h3 id="sendSeen"><span class="symbol-name">sendSeen</span><span class="signature"><span class="signature-params">(chatId)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing boolean</span></span></h3>
<p>Mark as seen for the Chat</p> <p>Mark as seen for the Chat</p>
<section> <section>
@@ -1491,7 +1473,7 @@
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="setDisplayName"><span class="symbol-name">setDisplayName</span><span class="signature"><span class="signature-params">(displayName)</span></span></h3> <h3 id="setDisplayName"><span class="symbol-name">setDisplayName</span><span class="signature"><span class="signature-params">(displayName)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Sets the current user's display name. <p>Sets the current user's display name.
This is the name shown to WhatsApp users that have not added you as a contact beside your number in groups and in your profile.</p> This is the name shown to WhatsApp users that have not added you as a contact beside your number in groups and in your profile.</p>
<section> <section>
@@ -1524,6 +1506,10 @@
</table> </table>
</section> </section>
<dl class="dl-compact"> <dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Boolean</code> </p>
</dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="setStatus"><span class="symbol-name">setStatus</span><span class="signature"><span class="signature-params">(status)</span></span></h3> <h3 id="setStatus"><span class="symbol-name">setStatus</span><span class="signature"><span class="signature-params">(status)</span></span></h3>
@@ -1650,104 +1636,10 @@
</dl> </dl>
<h3 id="event:authenticated"><span class="symbol-name">authenticated</span></h3> <h3 id="event:authenticated"><span class="symbol-name">authenticated</span></h3>
<p>Emitted when authentication is successful</p> <p>Emitted when authentication is successful</p>
<section>
<h4>Parameters</h4>
<table class="jsdoc-details-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>session</p>
</td>
<td>
<p>object</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Object containing session information. Can be used to restore the session.</p>
<p>Values in <code>session</code> have the following properties:</p>
<table class="jsdoc-details-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>WABrowserId</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>WASecretBundle</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>WAToken1</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>WAToken2</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact"> <dl class="dl-compact">
</dl> </dl>
<h3 id="event:change_battery"><span class="symbol-name">change_battery</span></h3> <h3 id="event:change_battery"><span class="symbol-name">change_battery</span></h3>
<p>Emitted when the battery percentage for the attached device changes</p> <p>Emitted when the battery percentage for the attached device changes. Will not be sent if using multi-device.</p>
<section> <section>
<h4>Parameters</h4> <h4>Parameters</h4>
<table class="jsdoc-details-table"> <table class="jsdoc-details-table">
@@ -1818,6 +1710,8 @@
</table> </table>
</section> </section>
<dl class="dl-compact"> <dl class="dl-compact">
<dt>Deprecated</dt>
<dd></dd>
</dl> </dl>
<h3 id="event:change_state"><span class="symbol-name">change_state</span></h3> <h3 id="event:change_state"><span class="symbol-name">change_state</span></h3>
<p>Emitted when the connection state changes</p> <p>Emitted when the connection state changes</p>
@@ -2370,7 +2264,7 @@
<dl class="dl-compact"> <dl class="dl-compact">
</dl> </dl>
<h3 id="event:qr"><span class="symbol-name">qr</span></h3> <h3 id="event:qr"><span class="symbol-name">qr</span></h3>
<p>Emitted when the QR code is received</p> <p>Emitted when a QR code is received</p>
<section> <section>
<h4>Parameter</h4> <h4>Parameter</h4>
<table class="jsdoc-details-table"> <table class="jsdoc-details-table">
@@ -2416,7 +2310,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: Client.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: Client.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -34,7 +34,6 @@
const EventEmitter &#x3D; require(&#x27;events&#x27;); const EventEmitter &#x3D; require(&#x27;events&#x27;);
const puppeteer &#x3D; require(&#x27;puppeteer&#x27;); const puppeteer &#x3D; require(&#x27;puppeteer&#x27;);
const moduleRaid &#x3D; require(&#x27;@pedroslopez/moduleraid/moduleraid&#x27;); const moduleRaid &#x3D; require(&#x27;@pedroslopez/moduleraid/moduleraid&#x27;);
const jsQR &#x3D; require(&#x27;jsqr&#x27;);
const Util &#x3D; require(&#x27;./util/Util&#x27;); const Util &#x3D; require(&#x27;./util/Util&#x27;);
const InterfaceController &#x3D; require(&#x27;./util/InterfaceController&#x27;); const InterfaceController &#x3D; require(&#x27;./util/InterfaceController&#x27;);
@@ -42,22 +41,20 @@ const { WhatsWebURL, DefaultOptions, Events, WAState } &#x3D; require(&#x27;./ut
const { ExposeStore, LoadUtils } &#x3D; require(&#x27;./util/Injected&#x27;); const { ExposeStore, LoadUtils } &#x3D; require(&#x27;./util/Injected&#x27;);
const ChatFactory &#x3D; require(&#x27;./factories/ChatFactory&#x27;); const ChatFactory &#x3D; require(&#x27;./factories/ChatFactory&#x27;);
const ContactFactory &#x3D; require(&#x27;./factories/ContactFactory&#x27;); const ContactFactory &#x3D; require(&#x27;./factories/ContactFactory&#x27;);
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification , Label, Call, Buttons, List} &#x3D; require(&#x27;./structures&#x27;); const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List } &#x3D; require(&#x27;./structures&#x27;);
const LegacySessionAuth &#x3D; require(&#x27;./authStrategies/LegacySessionAuth&#x27;);
const NoAuth &#x3D; require(&#x27;./authStrategies/NoAuth&#x27;);
/** /**
* Starting point for interacting with the WhatsApp Web API * Starting point for interacting with the WhatsApp Web API
* @extends {EventEmitter} * @extends {EventEmitter}
* @param {object} options - Client options * @param {object} options - Client options
* @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used.
* @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer * @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer
* @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/ * @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/
* @param {number} options.qrRefreshIntervalMs - Refresh interval for qr code (how much time to wait before checking if the qr code has changed)
* @param {number} options.qrTimeoutMs - Timeout for qr code selector in puppeteer
* @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up * @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up
* @param {string} options.restartOnAuthFail - Restart client with a new session (i.e. use null &#x27;session&#x27; var) if authentication fails * @param {string} options.restartOnAuthFail - @deprecated This option should be set directly on the LegacySessionAuth.
* @param {object} options.session - Whatsapp session to restore. If not set, will start a new session * @param {object} options.session - @deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.
* @param {string} options.session.WABrowserId
* @param {string} options.session.WASecretBundle
* @param {string} options.session.WAToken1
* @param {string} options.session.WAToken2
* @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser * @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser
* @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session * @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session
* @param {string} options.userAgent - User agent to use in puppeteer * @param {string} options.userAgent - User agent to use in puppeteer
@@ -79,13 +76,33 @@ const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification
* @fires Client#group_update * @fires Client#group_update
* @fires Client#disconnected * @fires Client#disconnected
* @fires Client#change_state * @fires Client#change_state
* @fires Client#change_battery
*/ */
class Client extends EventEmitter { class Client extends EventEmitter {
constructor(options &#x3D; {}) { constructor(options &#x3D; {}) {
super(); super();
this.options &#x3D; Util.mergeDefault(DefaultOptions, options); this.options &#x3D; Util.mergeDefault(DefaultOptions, options);
if(!this.options.authStrategy) {
if(Object.prototype.hasOwnProperty.call(this.options, &#x27;session&#x27;)) {
process.emitWarning(
&#x27;options.session is deprecated and will be removed in a future release due to incompatibility with multi-device. &#x27; +
&#x27;Use the LocalAuth authStrategy, don\&#x27;t pass in a session as an option, or suppress this warning by using the LegacySessionAuth strategy explicitly (see https://wwebjs.dev/guide/authentication.html#legacysessionauth-strategy).&#x27;,
&#x27;DeprecationWarning&#x27;
);
this.authStrategy &#x3D; new LegacySessionAuth({
session: this.options.session,
restartOnAuthFail: this.options.restartOnAuthFail
});
} else {
this.authStrategy &#x3D; new NoAuth();
}
} else {
this.authStrategy &#x3D; this.options.authStrategy;
}
this.authStrategy.setup(this);
this.pupBrowser &#x3D; null; this.pupBrowser &#x3D; null;
this.pupPage &#x3D; null; this.pupPage &#x3D; null;
@@ -98,41 +115,25 @@ class Client extends EventEmitter {
*/ */
async initialize() { async initialize() {
let [browser, page] &#x3D; [null, null]; let [browser, page] &#x3D; [null, null];
if(this.options.puppeteer &amp;amp;&amp;amp; this.options.puppeteer.browserWSEndpoint) { await this.authStrategy.beforeBrowserInitialized();
browser &#x3D; await puppeteer.connect(this.options.puppeteer);
const puppeteerOpts &#x3D; this.options.puppeteer;
if (puppeteerOpts &amp;amp;&amp;amp; puppeteerOpts.browserWSEndpoint) {
browser &#x3D; await puppeteer.connect(puppeteerOpts);
page &#x3D; await browser.newPage(); page &#x3D; await browser.newPage();
} else { } else {
browser &#x3D; await puppeteer.launch(this.options.puppeteer); browser &#x3D; await puppeteer.launch(puppeteerOpts);
page &#x3D; (await browser.pages())[0]; page &#x3D; (await browser.pages())[0];
} }
await page.setUserAgent(this.options.userAgent); await page.setUserAgent(this.options.userAgent);
if (this.options.bypassCSP) await page.setBypassCSP(true);
this.pupBrowser &#x3D; browser; this.pupBrowser &#x3D; browser;
this.pupPage &#x3D; page; this.pupPage &#x3D; page;
// remember me await this.authStrategy.afterBrowserInitialized();
await page.evaluateOnNewDocument(() &#x3D;&gt; {
localStorage.setItem(&#x27;remember-me&#x27;, &#x27;true&#x27;);
});
if (this.options.session) {
await page.evaluateOnNewDocument(
session &#x3D;&gt; {
if(document.referrer &#x3D;&#x3D;&#x3D; &#x27;https://whatsapp.com/&#x27;) {
localStorage.clear();
localStorage.setItem(&#x27;WABrowserId&#x27;, session.WABrowserId);
localStorage.setItem(&#x27;WASecretBundle&#x27;, session.WASecretBundle);
localStorage.setItem(&#x27;WAToken1&#x27;, session.WAToken1);
localStorage.setItem(&#x27;WAToken2&#x27;, session.WAToken2);
}
}, this.options.session);
}
if(this.options.bypassCSP) {
await page.setBypassCSP(true);
}
await page.goto(WhatsWebURL, { await page.goto(WhatsWebURL, {
waitUntil: &#x27;load&#x27;, waitUntil: &#x27;load&#x27;,
@@ -140,56 +141,54 @@ class Client extends EventEmitter {
referer: &#x27;https://whatsapp.com/&#x27; referer: &#x27;https://whatsapp.com/&#x27;
}); });
const KEEP_PHONE_CONNECTED_IMG_SELECTOR &#x3D; &#x27;[data-icon&#x3D;&quot;intro-md-beta-logo-dark&quot;], [data-icon&#x3D;&quot;intro-md-beta-logo-light&quot;], [data-asset-intro-image-light&#x3D;&quot;true&quot;], [data-asset-intro-image-dark&#x3D;&quot;true&quot;]&#x27;; const INTRO_IMG_SELECTOR &#x3D; &#x27;[data-testid&#x3D;&quot;intro-md-beta-logo-dark&quot;], [data-testid&#x3D;&quot;intro-md-beta-logo-light&quot;], [data-asset-intro-image-light&#x3D;&quot;true&quot;], [data-asset-intro-image-dark&#x3D;&quot;true&quot;]&#x27;;
const INTRO_QRCODE_SELECTOR &#x3D; &#x27;div[data-ref] canvas&#x27;;
if (this.options.session) { // Checks which selector appears first
// Check if session restore was successful const needAuthentication &#x3D; await Promise.race([
try { new Promise(resolve &#x3D;&gt; {
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: this.options.authTimeoutMs }); page.waitForSelector(INTRO_IMG_SELECTOR, { timeout: this.options.authTimeoutMs })
} catch (err) { .then(() &#x3D;&gt; resolve(false))
if (err.name &#x3D;&#x3D;&#x3D; &#x27;TimeoutError&#x27;) { .catch((err) &#x3D;&gt; resolve(err));
/** }),
* Emitted when there has been an error while trying to restore an existing session new Promise(resolve &#x3D;&gt; {
* @event Client#auth_failure page.waitForSelector(INTRO_QRCODE_SELECTOR, { timeout: this.options.authTimeoutMs })
* @param {string} message .then(() &#x3D;&gt; resolve(true))
*/ .catch((err) &#x3D;&gt; resolve(err));
this.emit(Events.AUTHENTICATION_FAILURE, &#x27;Unable to log in. Are the session details valid?&#x27;); })
browser.close(); ]);
if (this.options.restartOnAuthFail) {
// session restore failed so try again but without session to force new authentication // Checks if an error ocurred on the first found selector. The second will be discarded and ignored by .race;
this.options.session &#x3D; null; if (needAuthentication instanceof Error) throw needAuthentication;
this.initialize();
} // Scan-qrcode selector was found. Needs authentication
return; if (needAuthentication) {
const { failed, failureEventPayload, restart } &#x3D; await this.authStrategy.onAuthenticationNeeded();
if(failed) {
/**
* Emitted when there has been an error while trying to restore an existing session
* @event Client#auth_failure
* @param {string} message
*/
this.emit(Events.AUTHENTICATION_FAILURE, failureEventPayload);
await this.destroy();
if (restart) {
// session restore failed so try again but without session to force new authentication
return this.initialize();
} }
return;
throw err;
} }
} else { const QR_CONTAINER &#x3D; &#x27;div[data-ref]&#x27;;
const QR_RETRY_BUTTON &#x3D; &#x27;div[data-ref] &gt; span &gt; button&#x27;;
let qrRetries &#x3D; 0; let qrRetries &#x3D; 0;
await page.exposeFunction(&#x27;qrChanged&#x27;, async (qr) &#x3D;&gt; {
const getQrCode &#x3D; async () &#x3D;&gt; {
// Check if retry button is present
var QR_RETRY_SELECTOR &#x3D; &#x27;div[data-ref] &gt; span &gt; button&#x27;;
var qrRetry &#x3D; await page.$(QR_RETRY_SELECTOR);
if (qrRetry) {
await qrRetry.click();
}
// Wait for QR Code
const QR_CANVAS_SELECTOR &#x3D; &#x27;canvas&#x27;;
await page.waitForSelector(QR_CANVAS_SELECTOR, { timeout: this.options.qrTimeoutMs });
const qrImgData &#x3D; await page.$eval(QR_CANVAS_SELECTOR, canvas &#x3D;&gt; [].slice.call(canvas.getContext(&#x27;2d&#x27;).getImageData(0, 0, 264, 264).data));
const qr &#x3D; jsQR(qrImgData, 264, 264).data;
/** /**
* Emitted when the QR code is received * Emitted when a QR code is received
* @event Client#qr * @event Client#qr
* @param {string} qr QR Code * @param {string} qr QR Code
*/ */
this.emit(Events.QR_RECEIVED, qr); this.emit(Events.QR_RECEIVED, qr);
if (this.options.qrMaxRetries &gt; 0) { if (this.options.qrMaxRetries &gt; 0) {
qrRetries++; qrRetries++;
if (qrRetries &gt; this.options.qrMaxRetries) { if (qrRetries &gt; this.options.qrMaxRetries) {
@@ -197,15 +196,39 @@ class Client extends EventEmitter {
await this.destroy(); await this.destroy();
} }
} }
}; });
getQrCode();
this._qrRefreshInterval &#x3D; setInterval(getQrCode, this.options.qrRefreshIntervalMs); await page.evaluate(function (selectors) {
const qr_container &#x3D; document.querySelector(selectors.QR_CONTAINER);
window.qrChanged(qr_container.dataset.ref);
const obs &#x3D; new MutationObserver((muts) &#x3D;&gt; {
muts.forEach(mut &#x3D;&gt; {
// Listens to qr token change
if (mut.type &#x3D;&#x3D;&#x3D; &#x27;attributes&#x27; &amp;amp;&amp;amp; mut.attributeName &#x3D;&#x3D;&#x3D; &#x27;data-ref&#x27;) {
window.qrChanged(mut.target.dataset.ref);
} else
// Listens to retry button, when found, click it
if (mut.type &#x3D;&#x3D;&#x3D; &#x27;childList&#x27;) {
const retry_button &#x3D; document.querySelector(selectors.QR_RETRY_BUTTON);
if (retry_button) retry_button.click();
}
});
});
obs.observe(qr_container.parentElement, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: [&#x27;data-ref&#x27;],
});
}, {
QR_CONTAINER,
QR_RETRY_BUTTON
});
// Wait for code scan // Wait for code scan
try { try {
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: 0 }); await page.waitForSelector(INTRO_IMG_SELECTOR, { timeout: 0 });
clearInterval(this._qrRefreshInterval);
this._qrRefreshInterval &#x3D; undefined;
} catch(error) { } catch(error) {
if ( if (
error.name &#x3D;&#x3D;&#x3D; &#x27;ProtocolError&#x27; &amp;amp;&amp;amp; error.name &#x3D;&#x3D;&#x3D; &#x27;ProtocolError&#x27; &amp;amp;&amp;amp;
@@ -218,44 +241,29 @@ class Client extends EventEmitter {
throw error; throw error;
} }
} }
await page.evaluate(ExposeStore, moduleRaid.toString()); await page.evaluate(ExposeStore, moduleRaid.toString());
const authEventPayload &#x3D; await this.authStrategy.getAuthEventPayload();
// Get session tokens
const localStorage &#x3D; JSON.parse(await page.evaluate(() &#x3D;&gt; {
return JSON.stringify(window.localStorage);
}));
const session &#x3D; {
WABrowserId: localStorage.WABrowserId,
WASecretBundle: localStorage.WASecretBundle,
WAToken1: localStorage.WAToken1,
WAToken2: localStorage.WAToken2
};
/** /**
* Emitted when authentication is successful * Emitted when authentication is successful
* @event Client#authenticated * @event Client#authenticated
* @param {object} session Object containing session information. Can be used to restore the session.
* @param {string} session.WABrowserId
* @param {string} session.WASecretBundle
* @param {string} session.WAToken1
* @param {string} session.WAToken2
*/ */
this.emit(Events.AUTHENTICATED, session); this.emit(Events.AUTHENTICATED, authEventPayload);
// Check window.Store Injection // Check window.Store Injection
await page.waitForFunction(&#x27;window.Store !&#x3D; undefined&#x27;); await page.waitForFunction(&#x27;window.Store !&#x3D; undefined&#x27;);
const isMD &#x3D; await page.evaluate(() &#x3D;&gt; { await page.evaluate(async () &#x3D;&gt; {
return window.Store.Features.features.MD_BACKEND; // safely unregister service workers
const registrations &#x3D; await navigator.serviceWorker.getRegistrations();
for (let registration of registrations) {
registration.unregister();
}
}); });
if(isMD) {
throw new Error(&#x27;Multi-device is not yet supported by whatsapp-web.js. Please check out https://github.com/pedroslopez/whatsapp-web.js/pull/889 to follow the progress.&#x27;);
}
//Load util functions (serializers, helper functions) //Load util functions (serializers, helper functions)
await page.evaluate(LoadUtils); await page.evaluate(LoadUtils);
@@ -265,7 +273,7 @@ class Client extends EventEmitter {
* @type {ClientInfo} * @type {ClientInfo}
*/ */
this.info &#x3D; new ClientInfo(this, await page.evaluate(() &#x3D;&gt; { this.info &#x3D; new ClientInfo(this, await page.evaluate(() &#x3D;&gt; {
return window.Store.Conn.serialize(); return { ...window.Store.Conn.serialize(), wid: window.Store.User.getMeUser() };
})); }));
// Add InterfaceController // Add InterfaceController
@@ -429,11 +437,12 @@ class Client extends EventEmitter {
if (battery &#x3D;&#x3D;&#x3D; undefined) return; if (battery &#x3D;&#x3D;&#x3D; undefined) return;
/** /**
* Emitted when the battery percentage for the attached device changes * Emitted when the battery percentage for the attached device changes. Will not be sent if using multi-device.
* @event Client#change_battery * @event Client#change_battery
* @param {object} batteryInfo * @param {object} batteryInfo
* @param {number} batteryInfo.battery - The current battery percentage * @param {number} batteryInfo.battery - The current battery percentage
* @param {boolean} batteryInfo.plugged - Indicates if the phone is plugged in (true) or not (false) * @param {boolean} batteryInfo.plugged - Indicates if the phone is plugged in (true) or not (false)
* @deprecated
*/ */
this.emit(Events.BATTERY_CHANGED, { battery, plugged }); this.emit(Events.BATTERY_CHANGED, { battery, plugged });
}); });
@@ -452,14 +461,14 @@ class Client extends EventEmitter {
* @param {boolean} call.webClientShouldHandle - If Waweb should handle * @param {boolean} call.webClientShouldHandle - If Waweb should handle
* @param {object} call.participants - Participants * @param {object} call.participants - Participants
*/ */
const cll &#x3D; new Call(this,call); const cll &#x3D; new Call(this, call);
this.emit(Events.INCOMING_CALL, cll); this.emit(Events.INCOMING_CALL, cll);
}); });
await page.evaluate(() &#x3D;&gt; { await page.evaluate(() &#x3D;&gt; {
window.Store.Msg.on(&#x27;change&#x27;, (msg) &#x3D;&gt; { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on(&#x27;change&#x27;, (msg) &#x3D;&gt; { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.Msg.on(&#x27;change:type&#x27;, (msg) &#x3D;&gt; { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on(&#x27;change:type&#x27;, (msg) &#x3D;&gt; { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.Msg.on(&#x27;change:ack&#x27;, (msg,ack) &#x3D;&gt; { window.onMessageAckEvent(window.WWebJS.getMessageModel(msg), ack); }); window.Store.Msg.on(&#x27;change:ack&#x27;, (msg, ack) &#x3D;&gt; { window.onMessageAckEvent(window.WWebJS.getMessageModel(msg), ack); });
window.Store.Msg.on(&#x27;change:isUnsentMedia&#x27;, (msg, unsent) &#x3D;&gt; { if (msg.id.fromMe &amp;amp;&amp;amp; !unsent) window.onMessageMediaUploadedEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on(&#x27;change:isUnsentMedia&#x27;, (msg, unsent) &#x3D;&gt; { if (msg.id.fromMe &amp;amp;&amp;amp; !unsent) window.onMessageMediaUploadedEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.Msg.on(&#x27;remove&#x27;, (msg) &#x3D;&gt; { if (msg.isNewMsg) window.onRemoveMessageEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on(&#x27;remove&#x27;, (msg) &#x3D;&gt; { if (msg.isNewMsg) window.onRemoveMessageEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.AppState.on(&#x27;change:state&#x27;, (_AppState, state) &#x3D;&gt; { window.onAppStateChangedEvent(state); }); window.Store.AppState.on(&#x27;change:state&#x27;, (_AppState, state) &#x3D;&gt; { window.onAppStateChangedEvent(state); });
@@ -497,9 +506,6 @@ class Client extends EventEmitter {
* Closes the client * Closes the client
*/ */
async destroy() { async destroy() {
if (this._qrRefreshInterval) {
clearInterval(this._qrRefreshInterval);
}
await this.pupBrowser.close(); await this.pupBrowser.close();
} }
@@ -507,9 +513,11 @@ class Client extends EventEmitter {
* Logs out the client, closing the current session * Logs out the client, closing the current session
*/ */
async logout() { async logout() {
return await this.pupPage.evaluate(() &#x3D;&gt; { await this.pupPage.evaluate(() &#x3D;&gt; {
return window.Store.AppState.logout(); return window.Store.AppState.logout();
}); });
await this.authStrategy.logout();
} }
/** /**
@@ -539,7 +547,7 @@ class Client extends EventEmitter {
/** /**
* Message options. * Message options.
* @typedef {Object} MessageSendOptions * @typedef {Object} MessageSendOptions
* @property {boolean} [linkPreview&#x3D;true] - Show links preview * @property {boolean} [linkPreview&#x3D;true] - Show links preview. Has no effect on multi-device accounts.
* @property {boolean} [sendAudioAsVoice&#x3D;false] - Send audio as voice message * @property {boolean} [sendAudioAsVoice&#x3D;false] - Send audio as voice message
* @property {boolean} [sendVideoAsGif&#x3D;false] - Send video as gif * @property {boolean} [sendVideoAsGif&#x3D;false] - Send video as gif
* @property {boolean} [sendMediaAsSticker&#x3D;false] - Send media as a sticker * @property {boolean} [sendMediaAsSticker&#x3D;false] - Send media as a sticker
@@ -589,34 +597,36 @@ class Client extends EventEmitter {
} else if (content instanceof Location) { } else if (content instanceof Location) {
internalOptions.location &#x3D; content; internalOptions.location &#x3D; content;
content &#x3D; &#x27;&#x27;; content &#x3D; &#x27;&#x27;;
} else if(content instanceof Contact) { } else if (content instanceof Contact) {
internalOptions.contactCard &#x3D; content.id._serialized; internalOptions.contactCard &#x3D; content.id._serialized;
content &#x3D; &#x27;&#x27;; content &#x3D; &#x27;&#x27;;
} else if(Array.isArray(content) &amp;amp;&amp;amp; content.length &gt; 0 &amp;amp;&amp;amp; content[0] instanceof Contact) { } else if (Array.isArray(content) &amp;amp;&amp;amp; content.length &gt; 0 &amp;amp;&amp;amp; content[0] instanceof Contact) {
internalOptions.contactCardList &#x3D; content.map(contact &#x3D;&gt; contact.id._serialized); internalOptions.contactCardList &#x3D; content.map(contact &#x3D;&gt; contact.id._serialized);
content &#x3D; &#x27;&#x27;; content &#x3D; &#x27;&#x27;;
} else if(content instanceof Buttons){ } else if (content instanceof Buttons) {
if(content.type !&#x3D;&#x3D; &#x27;chat&#x27;){internalOptions.attachment &#x3D; content.body;} if (content.type !&#x3D;&#x3D; &#x27;chat&#x27;) { internalOptions.attachment &#x3D; content.body; }
internalOptions.buttons &#x3D; content; internalOptions.buttons &#x3D; content;
content &#x3D; &#x27;&#x27;; content &#x3D; &#x27;&#x27;;
} else if(content instanceof List){ } else if (content instanceof List) {
internalOptions.list &#x3D; content; internalOptions.list &#x3D; content;
content &#x3D; &#x27;&#x27;; content &#x3D; &#x27;&#x27;;
} }
if (internalOptions.sendMediaAsSticker &amp;amp;&amp;amp; internalOptions.attachment) { if (internalOptions.sendMediaAsSticker &amp;amp;&amp;amp; internalOptions.attachment) {
internalOptions.attachment &#x3D; internalOptions.attachment &#x3D; await Util.formatToWebpSticker(
await Util.formatToWebpSticker(internalOptions.attachment, { internalOptions.attachment, {
name: options.stickerName, name: options.stickerName,
author: options.stickerAuthor, author: options.stickerAuthor,
categories: options.stickerCategories categories: options.stickerCategories
}); }, this.pupPage
);
} }
const newMessage &#x3D; await this.pupPage.evaluate(async (chatId, message, options, sendSeen) &#x3D;&gt; { const newMessage &#x3D; await this.pupPage.evaluate(async (chatId, message, options, sendSeen) &#x3D;&gt; {
const chatWid &#x3D; window.Store.WidFactory.createWid(chatId); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
const chat &#x3D; await window.Store.Chat.find(chatWid); const chat &#x3D; await window.Store.Chat.find(chatWid);
if (sendSeen) { if (sendSeen) {
window.WWebJS.sendSeen(chatId); window.WWebJS.sendSeen(chatId);
} }
@@ -703,7 +713,7 @@ class Client extends EventEmitter {
*/ */
async getInviteInfo(inviteCode) { async getInviteInfo(inviteCode) {
return await this.pupPage.evaluate(inviteCode &#x3D;&gt; { return await this.pupPage.evaluate(inviteCode &#x3D;&gt; {
return window.Store.Wap.groupInviteInfo(inviteCode); return window.Store.InviteInfo.sendQueryGroupInvite(inviteCode);
}, inviteCode); }, inviteCode);
} }
@@ -722,25 +732,25 @@ class Client extends EventEmitter {
/** /**
* Accepts a private invitation to join a group * Accepts a private invitation to join a group
* @param {object} inviteV4 Invite V4 Info * @param {object} inviteInfo Invite V4 Info
* @returns {Promise&amp;lt;Object&gt;} * @returns {Promise&amp;lt;Object&gt;}
*/ */
async acceptGroupV4Invite(inviteInfo) { async acceptGroupV4Invite(inviteInfo) {
if(!inviteInfo.inviteCode) throw &#x27;Invalid invite code, try passing the message.inviteV4 object&#x27;; if (!inviteInfo.inviteCode) throw &#x27;Invalid invite code, try passing the message.inviteV4 object&#x27;;
if (inviteInfo.inviteCodeExp &#x3D;&#x3D; 0) throw &#x27;Expired invite code&#x27;; if (inviteInfo.inviteCodeExp &#x3D;&#x3D; 0) throw &#x27;Expired invite code&#x27;;
return await this.pupPage.evaluate(async inviteInfo &#x3D;&gt; { return this.pupPage.evaluate(async inviteInfo &#x3D;&gt; {
let { groupId, fromId, inviteCode, inviteCodeExp, toId } &#x3D; inviteInfo; let { groupId, fromId, inviteCode, inviteCodeExp } &#x3D; inviteInfo;
return await window.Store.Wap.acceptGroupV4Invite(groupId, fromId, inviteCode, String(inviteCodeExp), toId); return await window.Store.JoinInviteV4.sendJoinGroupViaInviteV4(inviteCode, String(inviteCodeExp), groupId, fromId);
}, inviteInfo); }, inviteInfo);
} }
/** /**
* Sets the current user&#x27;s status message * Sets the current user&#x27;s status message
* @param {string} status New status message * @param {string} status New status message
*/ */
async setStatus(status) { async setStatus(status) {
await this.pupPage.evaluate(async status &#x3D;&gt; { await this.pupPage.evaluate(async status &#x3D;&gt; {
return await window.Store.Wap.sendSetStatus(status); return await window.Store.StatusUtils.setMyStatus(status);
}, status); }, status);
} }
@@ -748,11 +758,22 @@ class Client extends EventEmitter {
* Sets the current user&#x27;s display name. * Sets the current user&#x27;s display name.
* This is the name shown to WhatsApp users that have not added you as a contact beside your number in groups and in your profile. * This is the name shown to WhatsApp users that have not added you as a contact beside your number in groups and in your profile.
* @param {string} displayName New display name * @param {string} displayName New display name
* @returns {Promise&amp;lt;Boolean&gt;}
*/ */
async setDisplayName(displayName) { async setDisplayName(displayName) {
await this.pupPage.evaluate(async displayName &#x3D;&gt; { const couldSet &#x3D; await this.pupPage.evaluate(async displayName &#x3D;&gt; {
return await window.Store.Wap.setPushname(displayName); if(!window.Store.Conn.canSetMyPushname()) return false;
if(window.Store.MDBackend) {
// TODO
return false;
} else {
const res &#x3D; await window.Store.Wap.setPushname(displayName);
return !res.status || res.status &#x3D;&#x3D;&#x3D; 200;
}
}, displayName); }, displayName);
return couldSet;
} }
/** /**
@@ -771,7 +792,16 @@ class Client extends EventEmitter {
*/ */
async sendPresenceAvailable() { async sendPresenceAvailable() {
return await this.pupPage.evaluate(() &#x3D;&gt; { return await this.pupPage.evaluate(() &#x3D;&gt; {
return window.Store.Wap.sendPresenceAvailable(); return window.Store.PresenceUtils.sendPresenceAvailable();
});
}
/**
* Marks the client as unavailable
*/
async sendPresenceUnavailable() {
return await this.pupPage.evaluate(() &#x3D;&gt; {
return window.Store.PresenceUtils.sendPresenceUnavailable();
}); });
} }
@@ -810,8 +840,9 @@ class Client extends EventEmitter {
return true; return true;
} }
const MAX_PIN_COUNT &#x3D; 3; const MAX_PIN_COUNT &#x3D; 3;
if (window.Store.Chat.models.length &gt; MAX_PIN_COUNT) { const chatModels &#x3D; window.Store.Chat.getModelsArray();
let maxPinned &#x3D; window.Store.Chat.models[MAX_PIN_COUNT - 1].pin; if (chatModels.length &gt; MAX_PIN_COUNT) {
let maxPinned &#x3D; chatModels[MAX_PIN_COUNT - 1].pin;
if (maxPinned) { if (maxPinned) {
return false; return false;
} }
@@ -877,13 +908,43 @@ class Client extends EventEmitter {
* @returns {Promise&amp;lt;string&gt;} * @returns {Promise&amp;lt;string&gt;}
*/ */
async getProfilePicUrl(contactId) { async getProfilePicUrl(contactId) {
const profilePic &#x3D; await this.pupPage.evaluate((contactId) &#x3D;&gt; { const profilePic &#x3D; await this.pupPage.evaluate(async contactId &#x3D;&gt; {
return window.Store.Wap.profilePicFind(contactId); try {
const chatWid &#x3D; window.Store.WidFactory.createWid(contactId);
return await window.Store.ProfilePic.profilePicFind(chatWid);
} catch (err) {
if(err.name &#x3D;&#x3D;&#x3D; &#x27;ServerStatusCodeError&#x27;) return undefined;
throw err;
}
}, contactId); }, contactId);
return profilePic ? profilePic.eurl : undefined; return profilePic ? profilePic.eurl : undefined;
} }
/**
* Gets the Contact&#x27;s common groups with you. Returns empty array if you don&#x27;t have any common group.
* @param {string} contactId the whatsapp user&#x27;s ID (_serialized format)
* @returns {Promise&amp;lt;WAWebJS.ChatId[]&gt;}
*/
async getCommonGroups(contactId) {
const commonGroups &#x3D; await this.pupPage.evaluate(async (contactId) &#x3D;&gt; {
const contact &#x3D; window.Store.Contact.get(contactId);
if (contact.commonGroups) {
return contact.commonGroups.serialize();
}
const status &#x3D; await window.Store.findCommonGroups(contact);
if (status) {
return contact.commonGroups.serialize();
}
return [];
}, contactId);
const chats &#x3D; [];
for (const group of commonGroups) {
chats.push(group.id);
}
return chats;
}
/** /**
* Force reset of connection state for the client * Force reset of connection state for the client
*/ */
@@ -899,10 +960,7 @@ class Client extends EventEmitter {
* @returns {Promise&amp;lt;Boolean&gt;} * @returns {Promise&amp;lt;Boolean&gt;}
*/ */
async isRegisteredUser(id) { async isRegisteredUser(id) {
return await this.pupPage.evaluate(async (id) &#x3D;&gt; { return Boolean(await this.getNumberId(id));
let result &#x3D; await window.Store.Wap.queryExist(id);
return result.jid !&#x3D;&#x3D; undefined;
}, id);
} }
/** /**
@@ -912,14 +970,15 @@ class Client extends EventEmitter {
* @returns {Promise&amp;lt;Object|null&gt;} * @returns {Promise&amp;lt;Object|null&gt;}
*/ */
async getNumberId(number) { async getNumberId(number) {
if (!number.endsWith(&#x27;@c.us&#x27;)) number +&#x3D; &#x27;@c.us&#x27;; if (!number.endsWith(&#x27;@c.us&#x27;)) {
try { number +&#x3D; &#x27;@c.us&#x27;;
return await this.pupPage.evaluate(async numberId &#x3D;&gt; {
return window.WWebJS.getNumberId(numberId);
}, number);
} catch(_) {
return null;
} }
return await this.pupPage.evaluate(async number &#x3D;&gt; {
const result &#x3D; await window.Store.QueryExist(number);
if (!result || result.wid &#x3D;&#x3D;&#x3D; undefined) return null;
return result.wid;
}, number);
} }
/** /**
@@ -928,14 +987,14 @@ class Client extends EventEmitter {
* @returns {Promise&amp;lt;string&gt;} * @returns {Promise&amp;lt;string&gt;}
*/ */
async getFormattedNumber(number) { async getFormattedNumber(number) {
if(!number.endsWith(&#x27;@s.whatsapp.net&#x27;)) number &#x3D; number.replace(&#x27;c.us&#x27;, &#x27;s.whatsapp.net&#x27;); if (!number.endsWith(&#x27;@s.whatsapp.net&#x27;)) number &#x3D; number.replace(&#x27;c.us&#x27;, &#x27;s.whatsapp.net&#x27;);
if(!number.includes(&#x27;@s.whatsapp.net&#x27;)) number &#x3D; &#x60;${number}@s.whatsapp.net&#x60;; if (!number.includes(&#x27;@s.whatsapp.net&#x27;)) number &#x3D; &#x60;${number}@s.whatsapp.net&#x60;;
return await this.pupPage.evaluate(async numberId &#x3D;&gt; { return await this.pupPage.evaluate(async numberId &#x3D;&gt; {
return window.Store.NumberInfo.formattedPhoneNumber(numberId); return window.Store.NumberInfo.formattedPhoneNumber(numberId);
}, number); }, number);
} }
/** /**
* Get the country code of a WhatsApp ID. * Get the country code of a WhatsApp ID.
* @param {string} number Number or ID * @param {string} number Number or ID
@@ -948,7 +1007,7 @@ class Client extends EventEmitter {
return window.Store.NumberInfo.findCC(numberId); return window.Store.NumberInfo.findCC(numberId);
}, number); }, number);
} }
/** /**
* Create a new group * Create a new group
* @param {string} name group title * @param {string} name group title
@@ -967,12 +1026,9 @@ class Client extends EventEmitter {
} }
const createRes &#x3D; await this.pupPage.evaluate(async (name, participantIds) &#x3D;&gt; { const createRes &#x3D; await this.pupPage.evaluate(async (name, participantIds) &#x3D;&gt; {
const res &#x3D; await window.Store.Wap.createGroup(name, participantIds); const participantWIDs &#x3D; participantIds.map(p &#x3D;&gt; window.Store.WidFactory.createWid(p));
console.log(res); const id &#x3D; window.Store.MsgKey.newId();
if (!res.status &#x3D;&#x3D;&#x3D; 200) { const res &#x3D; await window.Store.GroupUtils.sendCreateGroup(name, participantWIDs, undefined, id);
throw &#x27;An error occurred while creating the group!&#x27;;
}
return res; return res;
}, name, participants); }, name, participants);
@@ -993,9 +1049,9 @@ class Client extends EventEmitter {
async getLabels() { async getLabels() {
const labels &#x3D; await this.pupPage.evaluate(async () &#x3D;&gt; { const labels &#x3D; await this.pupPage.evaluate(async () &#x3D;&gt; {
return window.WWebJS.getLabels(); return window.WWebJS.getLabels();
}); });
return labels.map(data &#x3D;&gt; new Label(this , data)); return labels.map(data &#x3D;&gt; new Label(this, data));
} }
/** /**
@@ -1006,7 +1062,7 @@ class Client extends EventEmitter {
async getLabelById(labelId) { async getLabelById(labelId) {
const label &#x3D; await this.pupPage.evaluate(async (labelId) &#x3D;&gt; { const label &#x3D; await this.pupPage.evaluate(async (labelId) &#x3D;&gt; {
return window.WWebJS.getLabel(labelId); return window.WWebJS.getLabel(labelId);
}, labelId); }, labelId);
return new Label(this, label); return new Label(this, label);
} }
@@ -1016,12 +1072,12 @@ class Client extends EventEmitter {
* @param {string} chatId * @param {string} chatId
* @returns {Promise&amp;lt;Array&amp;lt;Label&gt;&gt;} * @returns {Promise&amp;lt;Array&amp;lt;Label&gt;&gt;}
*/ */
async getChatLabels(chatId){ async getChatLabels(chatId) {
const labels &#x3D; await this.pupPage.evaluate(async (chatId) &#x3D;&gt; { const labels &#x3D; await this.pupPage.evaluate(async (chatId) &#x3D;&gt; {
return window.WWebJS.getChatLabels(chatId); return window.WWebJS.getChatLabels(chatId);
}, chatId); }, chatId);
return labels.map(data &#x3D;&gt; new Label(this, data)); return labels.map(data &#x3D;&gt; new Label(this, data));
} }
/** /**
@@ -1029,16 +1085,16 @@ class Client extends EventEmitter {
* @param {string} labelId * @param {string} labelId
* @returns {Promise&amp;lt;Array&amp;lt;Chat&gt;&gt;} * @returns {Promise&amp;lt;Array&amp;lt;Chat&gt;&gt;}
*/ */
async getChatsByLabelId(labelId){ async getChatsByLabelId(labelId) {
const chatIds &#x3D; await this.pupPage.evaluate(async (labelId) &#x3D;&gt; { const chatIds &#x3D; await this.pupPage.evaluate(async (labelId) &#x3D;&gt; {
const label &#x3D; window.Store.Label.get(labelId); const label &#x3D; window.Store.Label.get(labelId);
const labelItems &#x3D; label.labelItemCollection.models; const labelItems &#x3D; label.labelItemCollection.getModelsArray();
return labelItems.reduce((result, item) &#x3D;&gt; { return labelItems.reduce((result, item) &#x3D;&gt; {
if(item.parentType &#x3D;&#x3D;&#x3D; &#x27;Chat&#x27;){ if (item.parentType &#x3D;&#x3D;&#x3D; &#x27;Chat&#x27;) {
result.push(item.parentId); result.push(item.parentId);
} }
return result; return result;
},[]); }, []);
}, labelId); }, labelId);
return Promise.all(chatIds.map(id &#x3D;&gt; this.getChatById(id))); return Promise.all(chatIds.map(id &#x3D;&gt; this.getChatById(id)));
@@ -1050,8 +1106,8 @@ class Client extends EventEmitter {
*/ */
async getBlockedContacts() { async getBlockedContacts() {
const blockedContacts &#x3D; await this.pupPage.evaluate(() &#x3D;&gt; { const blockedContacts &#x3D; await this.pupPage.evaluate(() &#x3D;&gt; {
let chatIds &#x3D; window.Store.Blocklist.models.map(a &#x3D;&gt; a.id._serialized); let chatIds &#x3D; window.Store.Blocklist.getModelsArray().map(a &#x3D;&gt; a.id._serialized);
return Promise.all(chatIds.map(id &#x3D;&gt; window.WWebJS.getContact(id))); return Promise.all(chatIds.map(id &#x3D;&gt; window.WWebJS.getContact(id)));
}); });
return blockedContacts.map(contact &#x3D;&gt; ContactFactory.create(this.client, contact)); return blockedContacts.map(contact &#x3D;&gt; ContactFactory.create(this.client, contact));
@@ -1069,7 +1125,7 @@ module.exports &#x3D; Client;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: ClientInfo</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: ClientInfo</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -101,7 +101,7 @@
</dl> </dl>
<h3 id="phone"><span class="symbol-name">phone</span><small class="property-type"> <h3 id="phone"><span class="symbol-name">phone</span><small class="property-type">
&nbsp;object</small></h3> &nbsp;object</small></h3>
<p>Information about the phone this client is connected to</p> <p>Information about the phone this client is connected to. Not available in multi-device.</p>
<section> <section>
<h4>Properties</h4> <h4>Properties</h4>
<table class="jsdoc-details-table"> <table class="jsdoc-details-table">
@@ -188,10 +188,12 @@
</table> </table>
</section> </section>
<dl class="dl-compact"> <dl class="dl-compact">
<dt>Deprecated</dt>
<dd></dd>
</dl> </dl>
<h3 id="platform"><span class="symbol-name">platform</span><small class="property-type"> <h3 id="platform"><span class="symbol-name">platform</span><small class="property-type">
&nbsp;string</small></h3> &nbsp;string</small></h3>
<p>Platform the phone is running on</p> <p>Platform WhatsApp is running on</p>
<dl class="dl-compact"> <dl class="dl-compact">
</dl> </dl>
<h3 id="pushname"><span class="symbol-name">pushname</span><small class="property-type"> <h3 id="pushname"><span class="symbol-name">pushname</span><small class="property-type">
@@ -211,6 +213,8 @@
<h3 id="getBatteryStatus"><span class="symbol-name">getBatteryStatus</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> (object, number, or boolean)</span></span></h3> <h3 id="getBatteryStatus"><span class="symbol-name">getBatteryStatus</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> (object, number, or boolean)</span></span></h3>
<p>Get current battery percentage and charging status for the attached device</p> <p>Get current battery percentage and charging status for the attached device</p>
<dl class="dl-compact"> <dl class="dl-compact">
<dt>Deprecated</dt>
<dd></dd>
<dt>Returns</dt> <dt>Returns</dt>
<dd> <dd>
<p><code>object</code>  <p><code>object</code> 
@@ -238,7 +242,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Contact</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Contact</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -108,19 +108,22 @@
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="Contact.html#getCommonGroups">getCommonGroups()</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#getCountryCode">getCountryCode()</a></dt> <dt><a href="Contact.html#getCountryCode">getCountryCode()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Contact.html#getFormattedNumber">getFormattedNumber()</a></dt> <dt><a href="Contact.html#getFormattedNumber">getFormattedNumber()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Contact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
</dl> </dl>
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="Contact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#unblock">unblock()</a></dt> <dt><a href="Contact.html#unblock">unblock()</a></dt>
<dd> <dd>
</dd> </dd>
@@ -236,6 +239,15 @@
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getCommonGroups"><span class="symbol-name">getCommonGroups</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of WAWebJS.ChatId</span></span></h3>
<p>Gets the Contact's common groups with you. Returns empty array if you don't have any common group.</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Array of WAWebJS.ChatId</code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getCountryCode"><span class="symbol-name">getCountryCode</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing string</span></span></h3> <h3 id="getCountryCode"><span class="symbol-name">getCountryCode</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing string</span></span></h3>
<p>Returns the contact's countrycode, (1541859685@c.us) =&gt; (1)</p> <p>Returns the contact's countrycode, (1541859685@c.us) =&gt; (1)</p>
<dl class="dl-compact"> <dl class="dl-compact">
@@ -281,7 +293,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: GroupChat</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: GroupChat</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -645,12 +645,14 @@
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="revokeInvite"><span class="symbol-name">revokeInvite</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise</span></span></h3> <h3 id="revokeInvite"><span class="symbol-name">revokeInvite</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing string</span></span></h3>
<p>Invalidates the current group invite code and generates a new one</p> <p>Invalidates the current group invite code and generates a new one</p>
<dl class="dl-compact"> <dl class="dl-compact">
<dt>Returns</dt> <dt>Returns</dt>
<dd> <dd>
<p><code>Promise</code> </p> <p><code>Promise containing string</code> 
<p>New invite code</p>
</p>
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
@@ -731,7 +733,7 @@
<dd><a href="Chat.html#sendStateTyping">Chat#sendStateTyping</a></dd> <dd><a href="Chat.html#sendStateTyping">Chat#sendStateTyping</a></dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="setDescription"><span class="symbol-name">setDescription</span><span class="signature"><span class="signature-params">(description)</span>&nbsp;&rarr; <span class="signature-returns"> Promise</span></span></h3> <h3 id="setDescription"><span class="symbol-name">setDescription</span><span class="signature"><span class="signature-params">(description)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing boolean</span></span></h3>
<p>Updates the group description</p> <p>Updates the group description</p>
<section> <section>
<h4>Parameter</h4> <h4>Parameter</h4>
@@ -764,7 +766,9 @@
<dl class="dl-compact"> <dl class="dl-compact">
<dt>Returns</dt> <dt>Returns</dt>
<dd> <dd>
<p><code>Promise</code> </p> <p><code>Promise containing boolean</code> 
<p>Returns true if the description was properly updated. This can return false if the user does not have the necessary permissions.</p>
</p>
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
@@ -850,7 +854,7 @@
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="setSubject"><span class="symbol-name">setSubject</span><span class="signature"><span class="signature-params">(subject)</span>&nbsp;&rarr; <span class="signature-returns"> Promise</span></span></h3> <h3 id="setSubject"><span class="symbol-name">setSubject</span><span class="signature"><span class="signature-params">(subject)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing boolean</span></span></h3>
<p>Updates the group subject</p> <p>Updates the group subject</p>
<section> <section>
<h4>Parameter</h4> <h4>Parameter</h4>
@@ -883,7 +887,9 @@
<dl class="dl-compact"> <dl class="dl-compact">
<dt>Returns</dt> <dt>Returns</dt>
<dd> <dd>
<p><code>Promise</code> </p> <p><code>Promise containing boolean</code> 
<p>Returns true if the subject was properly updated. This can return false if the user does not have the necessary permissions.</p>
</p>
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
@@ -921,7 +927,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: GroupNotification</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: GroupNotification</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -233,7 +233,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: InterfaceController</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: InterfaceController</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -382,7 +382,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Label</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Label</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -163,7 +163,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

188
docs/LegacySessionAuth.html Normal file
View File

@@ -0,0 +1,188 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Class: LegacySessionAuth</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-main" role="main">
<header class="page-header">
<div class="symbol-detail-labels"><span class="label label-kind">class</span></div>
<h1><small></small><span class="symbol-name">LegacySessionAuth</span></h1>
<p class="source-link">Source: <a href="authStrategies_LegacySessionAuth.js.html#source-line-16">authStrategies/<wbr>LegacySessionAuth.<wbr>js:16</a></p>
<div class="symbol-classdesc">
<p>Legacy session auth strategy
Not compatible with multi-device accounts.</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
</section>
<section>
<h2 id="LegacySessionAuth">new&nbsp;<span class="symbol-name">LegacySessionAuth</span><span class="signature"><span class="signature-params">(options)</span></span></h2>
<section>
<h3>Parameters</h3>
<table class="jsdoc-details-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>options</p>
<p>Values in <code>options</code> have the following properties:</p>
<table class="jsdoc-details-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>restartOnAuthFail</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Restart client with a new session (i.e. use null 'session' var) if authentication fails</p>
</td>
</tr>
<tr>
<td>
<p>session</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Whatsapp session to restore. If not set, will start a new session</p>
</td>
</tr>
<tr>
<td>
<p>session.WABrowserId</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>session.WASecretBundle</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>session.WAToken1</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>session.WAToken2</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
</section>
<section>
</section>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: List</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: List</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -256,7 +256,7 @@ Returns: [{&#x27;title&#x27;:&#x27;sectionTitle&#x27;,&#x27;rows&#x27;:[{&#x27;r
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

135
docs/LocalAuth.html Normal file
View File

@@ -0,0 +1,135 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Class: LocalAuth</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-main" role="main">
<header class="page-header">
<div class="symbol-detail-labels"><span class="label label-kind">class</span></div>
<h1><small></small><span class="symbol-name">LocalAuth</span></h1>
<p class="source-link">Source: <a href="authStrategies_LocalAuth.js.html#source-line-13">authStrategies/<wbr>LocalAuth.<wbr>js:13</a></p>
<div class="symbol-classdesc">
<p>Local directory-based authentication</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
</section>
<section>
<h2 id="LocalAuth">new&nbsp;<span class="symbol-name">LocalAuth</span><span class="signature"><span class="signature-params">(options)</span></span></h2>
<section>
<h3>Parameters</h3>
<table class="jsdoc-details-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>options</p>
<p>Values in <code>options</code> have the following properties:</p>
<table class="jsdoc-details-table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Optional</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>clientId</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Client id to distinguish instances if you are using multiple, otherwise keep null if you are using only one instance</p>
</td>
</tr>
<tr>
<td>
<p>dataPath</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Change the default path for saving session files, default is: &quot;./.wwebjs_auth/&quot;</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
</section>
<section>
</section>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Location</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Location</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -149,7 +149,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Message</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Message</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -54,6 +54,9 @@
<dt><a href="Message.html#deviceType">deviceType</a></dt> <dt><a href="Message.html#deviceType">deviceType</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Message.html#duration">duration</a></dt>
<dd>
</dd>
<dt><a href="Message.html#forwardingScore">forwardingScore</a></dt> <dt><a href="Message.html#forwardingScore">forwardingScore</a></dt>
<dd> <dd>
</dd> </dd>
@@ -97,13 +100,13 @@
<dt><a href="Message.html#links">links</a></dt> <dt><a href="Message.html#links">links</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Message.html#location">location</a></dt>
<dd>
</dd>
</dl> </dl>
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="Message.html#location">location</a></dt>
<dd>
</dd>
<dt><a href="Message.html#mediaKey">mediaKey</a></dt> <dt><a href="Message.html#mediaKey">mediaKey</a></dt>
<dd> <dd>
</dd> </dd>
@@ -113,6 +116,9 @@
<dt><a href="Message.html#orderId">orderId</a></dt> <dt><a href="Message.html#orderId">orderId</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Message.html#rawData">rawData</a></dt>
<dd>
</dd>
<dt><a href="Message.html#timestamp">timestamp</a></dt> <dt><a href="Message.html#timestamp">timestamp</a></dt>
<dd> <dd>
</dd> </dd>
@@ -178,6 +184,9 @@
<dt><a href="Message.html#getQuotedMessage">getQuotedMessage()</a></dt> <dt><a href="Message.html#getQuotedMessage">getQuotedMessage()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="Message.html#reload">reload()</a></dt>
<dd>
</dd>
<dt><a href="Message.html#reply">reply(content[, chatId][, options])</a></dt> <dt><a href="Message.html#reply">reply(content[, chatId][, options])</a></dt>
<dd> <dd>
</dd> </dd>
@@ -227,6 +236,11 @@
<p>String that represents from which device type the message was sent</p> <p>String that represents from which device type the message was sent</p>
<dl class="dl-compact"> <dl class="dl-compact">
</dl> </dl>
<h3 id="duration"><span class="symbol-name">duration</span><small class="property-type">
&nbsp;string</small></h3>
<p>Indicates the duration of the message in seconds</p>
<dl class="dl-compact">
</dl>
<h3 id="forwardingScore"><span class="symbol-name">forwardingScore</span><small class="property-type"> <h3 id="forwardingScore"><span class="symbol-name">forwardingScore</span><small class="property-type">
&nbsp;number</small></h3> &nbsp;number</small></h3>
<p>Indicates how many times the message was forwarded.</p> <p>Indicates how many times the message was forwarded.</p>
@@ -313,6 +327,11 @@
<p>Order ID for message type ORDER</p> <p>Order ID for message type ORDER</p>
<dl class="dl-compact"> <dl class="dl-compact">
</dl> </dl>
<h3 id="rawData"><span class="symbol-name">rawData</span><small class="property-type">
&nbsp;Object</small></h3>
<p>Returns message in a raw format</p>
<dl class="dl-compact">
</dl>
<h3 id="timestamp"><span class="symbol-name">timestamp</span><small class="property-type"> <h3 id="timestamp"><span class="symbol-name">timestamp</span><small class="property-type">
&nbsp;number</small></h3> &nbsp;number</small></h3>
<p>Unix timestamp for when the message was created</p> <p>Unix timestamp for when the message was created</p>
@@ -496,6 +515,16 @@
</dd> </dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="reload"><span class="symbol-name">reload</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3>
<p>Reloads this Message object's data in-place with the latest values from WhatsApp Web.
Note that the Message must still be in the web app cache for this to work, otherwise will return null.</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Message.html">Message</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="reply"><span class="symbol-name">reply</span><span class="signature"><span class="signature-params">(content[, chatId][, options])</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3> <h3 id="reply"><span class="symbol-name">reply</span><span class="signature"><span class="signature-params">(content[, chatId][, options])</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3>
<p>Sends a message as a reply to this message. If chatId is specified, it will be sent <p>Sends a message as a reply to this message. If chatId is specified, it will be sent
through the specified Chat. If not, it will send the message through the specified Chat. If not, it will send the message
@@ -580,7 +609,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: MessageMedia</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: MessageMedia</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -343,7 +343,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

66
docs/NoAuth.html Normal file
View File

@@ -0,0 +1,66 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Class: NoAuth</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-main" role="main">
<header class="page-header">
<div class="symbol-detail-labels"><span class="label label-kind">class</span></div>
<h1><small></small><span class="symbol-name">NoAuth</span></h1>
<p class="source-link">Source: <a href="authStrategies_NoAuth.js.html#source-line-9">authStrategies/<wbr>NoAuth.<wbr>js:9</a></p>
<div class="symbol-classdesc">
<p>No session restoring functionality
Will need to authenticate via QR code every time</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
</section>
<section>
<h2 id="NoAuth">new&nbsp;<span class="symbol-name">NoAuth</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
</dl>
</section>
<section>
</section>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Order</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Order</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -102,7 +102,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: PrivateChat</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: PrivateChat</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -519,7 +519,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: PrivateContact</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: PrivateContact</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -108,19 +108,22 @@
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="PrivateContact.html#getCommonGroups">getCommonGroups()</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#getCountryCode">getCountryCode()</a></dt> <dt><a href="PrivateContact.html#getCountryCode">getCountryCode()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="PrivateContact.html#getFormattedNumber">getFormattedNumber()</a></dt> <dt><a href="PrivateContact.html#getFormattedNumber">getFormattedNumber()</a></dt>
<dd> <dd>
</dd> </dd>
<dt><a href="PrivateContact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
</dl> </dl>
</div> </div>
<div class="summary-column"> <div class="summary-column">
<dl class="dl-summary-callout"> <dl class="dl-summary-callout">
<dt><a href="PrivateContact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#unblock">unblock()</a></dt> <dt><a href="PrivateContact.html#unblock">unblock()</a></dt>
<dd> <dd>
</dd> </dd>
@@ -262,6 +265,15 @@
<dd></dd> <dd></dd>
</dl> </dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div> <div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getCommonGroups"><span class="symbol-name">getCommonGroups</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of WAWebJS.ChatId</span></span></h3>
<p>Gets the Contact's common groups with you. Returns empty array if you don't have any common group.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#getCommonGroups">Contact#getCommonGroups</a></dd>
<dt>Returns</dt>
<dd></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getCountryCode"><span class="symbol-name">getCountryCode</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing string</span></span></h3> <h3 id="getCountryCode"><span class="symbol-name">getCountryCode</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing string</span></span></h3>
<p>Returns the contact's countrycode, (1541859685@c.us) =&gt; (1)</p> <p>Returns the contact's countrycode, (1541859685@c.us) =&gt; (1)</p>
<dl class="dl-compact"> <dl class="dl-compact">
@@ -307,7 +319,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Product</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Product</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -127,7 +127,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Class: Util</title> <title>whatsapp-web.js 1.16.7 &raquo; Class: Util</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -26,7 +26,7 @@
<header class="page-header"> <header class="page-header">
<div class="symbol-detail-labels"><span class="label label-kind">class</span></div> <div class="symbol-detail-labels"><span class="label label-kind">class</span></div>
<h1><small></small><span class="symbol-name">Util</span></h1> <h1><small></small><span class="symbol-name">Util</span></h1>
<p class="source-link">Source: <a href="util_Util.js.html#source-line-16">util/<wbr>Util.<wbr>js:16</a></p> <p class="source-link">Source: <a href="util_Util.js.html#source-line-15">util/<wbr>Util.<wbr>js:15</a></p>
<div class="symbol-classdesc"> <div class="symbol-classdesc">
<p>Utility methods</p> <p>Utility methods</p>
</div> </div>
@@ -243,7 +243,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -0,0 +1,77 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Source: authStrategies/BaseAuthStrategy.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-banner" role="banner">
</div>
<div id="jsdoc-main" role="main">
<header class="page-header">
<h1>Source: authStrategies/BaseAuthStrategy.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
/**
* Base class which all authentication strategies extend
*/
class BaseAuthStrategy {
constructor() {}
setup(client) {
this.client &#x3D; client;
}
async beforeBrowserInitialized() {}
async afterBrowserInitialized() {}
async onAuthenticationNeeded() {
return {
failed: false,
restart: false,
failureEventPayload: undefined
};
}
async getAuthEventPayload() {}
async logout() {}
}
module.exports &#x3D; BaseAuthStrategy;</code></pre>
</article>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -0,0 +1,126 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Source: authStrategies/LegacySessionAuth.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-banner" role="banner">
</div>
<div id="jsdoc-main" role="main">
<header class="page-header">
<h1>Source: authStrategies/LegacySessionAuth.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const BaseAuthStrategy &#x3D; require(&#x27;./BaseAuthStrategy&#x27;);
/**
* Legacy session auth strategy
* Not compatible with multi-device accounts.
* @param {object} options - options
* @param {string} options.restartOnAuthFail - Restart client with a new session (i.e. use null &#x27;session&#x27; var) if authentication fails
* @param {object} options.session - Whatsapp session to restore. If not set, will start a new session
* @param {string} options.session.WABrowserId
* @param {string} options.session.WASecretBundle
* @param {string} options.session.WAToken1
* @param {string} options.session.WAToken2
*/
class LegacySessionAuth extends BaseAuthStrategy {
constructor({ session, restartOnAuthFail }&#x3D;{}) {
super();
this.session &#x3D; session;
this.restartOnAuthFail &#x3D; restartOnAuthFail;
}
async afterBrowserInitialized() {
if(this.session) {
await this.client.pupPage.evaluateOnNewDocument(session &#x3D;&gt; {
if (document.referrer &#x3D;&#x3D;&#x3D; &#x27;https://whatsapp.com/&#x27;) {
localStorage.clear();
localStorage.setItem(&#x27;WABrowserId&#x27;, session.WABrowserId);
localStorage.setItem(&#x27;WASecretBundle&#x27;, session.WASecretBundle);
localStorage.setItem(&#x27;WAToken1&#x27;, session.WAToken1);
localStorage.setItem(&#x27;WAToken2&#x27;, session.WAToken2);
}
localStorage.setItem(&#x27;remember-me&#x27;, &#x27;true&#x27;);
}, this.session);
}
}
async onAuthenticationNeeded() {
if(this.session) {
this.session &#x3D; null;
return {
failed: true,
restart: this.restartOnAuthFail,
failureEventPayload: &#x27;Unable to log in. Are the session details valid?&#x27;
};
}
return { failed: false };
}
async getAuthEventPayload() {
const isMD &#x3D; await this.client.pupPage.evaluate(() &#x3D;&gt; {
return window.Store.MDBackend;
});
if(isMD) throw new Error(&#x27;Authenticating via JSON session is not supported for MultiDevice-enabled WhatsApp accounts.&#x27;);
const localStorage &#x3D; JSON.parse(await this.client.pupPage.evaluate(() &#x3D;&gt; {
return JSON.stringify(window.localStorage);
}));
return {
WABrowserId: localStorage.WABrowserId,
WASecretBundle: localStorage.WASecretBundle,
WAToken1: localStorage.WAToken1,
WAToken2: localStorage.WAToken2
};
}
}
module.exports &#x3D; LegacySessionAuth;
</code></pre>
</article>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -0,0 +1,106 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Source: authStrategies/LocalAuth.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-banner" role="banner">
</div>
<div id="jsdoc-main" role="main">
<header class="page-header">
<h1>Source: authStrategies/LocalAuth.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const path &#x3D; require(&#x27;path&#x27;);
const fs &#x3D; require(&#x27;fs&#x27;);
const BaseAuthStrategy &#x3D; require(&#x27;./BaseAuthStrategy&#x27;);
/**
* Local directory-based authentication
* @param {object} options - options
* @param {string} options.clientId - Client id to distinguish instances if you are using multiple, otherwise keep null if you are using only one instance
* @param {string} options.dataPath - Change the default path for saving session files, default is: &quot;./.wwebjs_auth/&quot;
*/
class LocalAuth extends BaseAuthStrategy {
constructor({ clientId, dataPath }&#x3D;{}) {
super();
const idRegex &#x3D; /^[-_\w]+$/i;
if(clientId &amp;amp;&amp;amp; !idRegex.test(clientId)) {
throw new Error(&#x27;Invalid clientId. Only alphanumeric characters, underscores and hyphens are allowed.&#x27;);
}
this.dataPath &#x3D; path.resolve(dataPath || &#x27;./.wwebjs_auth/&#x27;);
this.clientId &#x3D; clientId;
}
async beforeBrowserInitialized() {
const puppeteerOpts &#x3D; this.client.options.puppeteer;
const sessionDirName &#x3D; this.clientId ? &#x60;session-${this.clientId}&#x60; : &#x27;session&#x27;;
const dirPath &#x3D; path.join(this.dataPath, sessionDirName);
if(puppeteerOpts.userDataDir &amp;amp;&amp;amp; puppeteerOpts.userDataDir !&#x3D;&#x3D; dirPath) {
throw new Error(&#x27;LocalAuth is not compatible with a user-supplied userDataDir.&#x27;);
}
fs.mkdirSync(dirPath, { recursive: true });
this.client.options.puppeteer &#x3D; {
...puppeteerOpts,
userDataDir: dirPath
};
this.userDataDir &#x3D; dirPath;
}
async logout() {
if (this.userDataDir) {
return (fs.rmSync ? fs.rmSync : fs.rmdirSync).call(this, this.userDataDir, { recursive: true });
}
}
}
module.exports &#x3D; LocalAuth;</code></pre>
</article>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -0,0 +1,65 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8">
<title>whatsapp-web.js 1.16.7 &raquo; Source: authStrategies/NoAuth.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
<link href="css/baseline.css" rel="stylesheet">
</head>
<body onload="prettyPrint()">
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div>
</div>
</nav>
<div id="jsdoc-body-container">
<div id="jsdoc-content">
<div id="jsdoc-content-container">
<div id="jsdoc-banner" role="banner">
</div>
<div id="jsdoc-main" role="main">
<header class="page-header">
<h1>Source: authStrategies/NoAuth.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const BaseAuthStrategy &#x3D; require(&#x27;./BaseAuthStrategy&#x27;);
/**
* No session restoring functionality
* Will need to authenticate via QR code every time
*/
class NoAuth extends BaseAuthStrategy { }
module.exports &#x3D; NoAuth;</code></pre>
</article>
</div>
</div>
<nav id="jsdoc-toc-nav" role="navigation"></nav>
</div>
</div>
<footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container">
<p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p>
</div>
</footer>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tree.jquery.js"></script>
<script src="scripts/prettify.js"></script>
<script src="scripts/jsdoc-toc.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/scrollanchor.js"></script>
</body>
</html>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Globals</title> <title>whatsapp-web.js 1.16.7 &raquo; Globals</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -1714,7 +1714,7 @@
<p>Yes</p> <p>Yes</p>
</td> </td>
<td> <td>
<p>Show links preview</p> <p>Show links preview. Has no effect on multi-device accounts.</p>
<p>Defaults to <code>true</code>.</p> <p>Defaults to <code>true</code>.</p>
</td> </td>
</tr> </tr>
@@ -1980,7 +1980,7 @@
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Home</title> <title>whatsapp-web.js 1.16.7 &raquo; Home</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -27,11 +27,11 @@
<div id="jsdoc-main" role="main"> <div id="jsdoc-main" role="main">
<header class="page-header"> <header class="page-header">
<h1> <h1>
whatsapp-web.js 1.15.6 whatsapp-web.js 1.16.7
</h1> </h1>
</header> </header>
<article> <article>
<p><a href="https://www.npmjs.com/package/whatsapp-web.js"><img src="https://img.shields.io/npm/v/whatsapp-web.js.svg" alt="npm"></a> <a href="https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765"><img src="https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg" alt="Depfu"></a> <img src="https://img.shields.io/badge/WhatsApp_Web-2.2202.12-brightgreen.svg" alt="WhatsApp_Web 2.2202.12"> <a href="https://discord.gg/H7DqQs4"><img src="https://img.shields.io/discord/698610475432411196.svg?logo=discord" alt="Discord Chat"></a></p> <p><a href="https://www.npmjs.com/package/whatsapp-web.js"><img src="https://img.shields.io/npm/v/whatsapp-web.js.svg" alt="npm"></a> <a href="https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765"><img src="https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg" alt="Depfu"></a> <img src="https://img.shields.io/badge/WhatsApp_Web-2.2220.8-brightgreen.svg" alt="WhatsApp_Web 2.2220.8"> <a href="https://discord.gg/H7DqQs4"><img src="https://img.shields.io/discord/698610475432411196.svg?logo=discord" alt="Discord Chat"></a></p>
<h1>whatsapp-web.js</h1> <h1>whatsapp-web.js</h1>
<p>A WhatsApp API client that connects through the WhatsApp Web browser app</p> <p>A WhatsApp API client that connects through the WhatsApp Web browser app</p>
<p>It uses Puppeteer to run a real instance of Whatsapp Web to avoid getting blocked.</p> <p>It uses Puppeteer to run a real instance of Whatsapp Web to avoid getting blocked.</p>
@@ -69,33 +69,7 @@ client.on('message', msg => {
client.initialize(); client.initialize();
</code></pre> </code></pre>
<p>Take a look at <a href="https://github.com/pedroslopez/whatsapp-web.js/blob/master/example.js">example.js</a> for another example with more use cases.</p> <p>Take a look at <a href="https://github.com/pedroslopez/whatsapp-web.js/blob/master/example.js">example.js</a> for another example with more use cases.</p>
<h2>Remote Access</h2> <p>For more information on saving and restoring sessions, check out the available <a href="https://wwebjs.dev/guide/authentication.html">Authentication Strategies</a>.</p>
<p>You could also connect to any previously existing browser instance:</p>
<pre class="prettyprint source lang-js"><code>const client = new Client({
puppeteer: {
browserWSEndpoint: `ws://localhost:3000`
}
});
</code></pre>
<h3>Docker</h3>
<ol>
<li>Installing a browser using browserless:</li>
</ol>
<pre class="prettyprint source"><code>docker run \
--rm \
-p 3000:3000 \
-e &quot;MAX_CONCURRENT_SESSIONS=1&quot; \
browserless/chrome:latest
</code></pre>
<p>Reference: https://docs.browserless.io/docs/docker-quickstart.html</p>
<h3>Remote Debugging</h3>
<ol start="2">
<li>Running a browser with websocket remote debugging enabled:</li>
</ol>
<blockquote>
<p>chrome.exe --remote-debugging-port=9222</p>
</blockquote>
<p>After that check the following webpage and check http://127.0.0.1:9220/json and get the <strong>webSocketDebuggerUrl</strong></p>
<h2>Supported features</h2> <h2>Supported features</h2>
<table> <table>
<thead> <thead>
@@ -105,6 +79,10 @@ client.initialize();
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr>
<td>Multi Device</td>
<td></td>
</tr>
<tr> <tr>
<td>Send messages</td> <td>Send messages</td>
<td></td> <td></td>
@@ -210,9 +188,13 @@ client.initialize();
<p>Something missing? Make an issue and let us know!</p> <p>Something missing? Make an issue and let us know!</p>
<h2>Contributing</h2> <h2>Contributing</h2>
<p>Pull requests are welcome! If you see something you'd like to add, please do. For drastic changes, please open an issue first.</p> <p>Pull requests are welcome! If you see something you'd like to add, please do. For drastic changes, please open an issue first.</p>
<h2>Donating</h2> <h2>Supporting the project</h2>
<p>You can support the maintainer of this project through the link below</p> <p>You can support the maintainer of this project through the links below</p>
<p><a href="https://www.paypal.me/psla/"><img src="https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg" alt="Support via PayPal"></a></p> <ul>
<li><a href="https://github.com/sponsors/pedroslopez">Support via GitHub Sponsors</a></li>
<li><a href="https://www.paypal.me/psla/">Support via PayPal</a></li>
<li><a href="https://m.do.co/c/73f906a36ed4">Sign up for DigitalOcean</a> and get $100 in credit when you sign up (Referral)</li>
</ul>
<h2>Disclaimer</h2> <h2>Disclaimer</h2>
<p>This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or its affiliates. The official WhatsApp website can be found at https://whatsapp.com. &quot;WhatsApp&quot; as well as related names, marks, emblems and images are registered trademarks of their respective owners.</p> <p>This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or its affiliates. The official WhatsApp website can be found at https://whatsapp.com. &quot;WhatsApp&quot; as well as related names, marks, emblems and images are registered trademarks of their respective owners.</p>
<h2>License</h2> <h2>License</h2>
@@ -251,6 +233,30 @@ client.initialize();
</div> </div>
</div> </div>
</section> </section>
<section>
<div class="symbol-index-content">
<h2 id="BaseAuthStrategy">BaseAuthStrategy</h2>
<div class="symbol-index-section">
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name">
<a href="BaseAuthStrategy.html" class="!symbol-index-name">BaseAuthStrategy()</a>
</dt>
<dd>
</dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
</div>
</div>
</section>
<section> <section>
<div class="symbol-index-content"> <div class="symbol-index-content">
<h2 id="BusinessContact">BusinessContact</h2> <h2 id="BusinessContact">BusinessContact</h2>
@@ -282,6 +288,11 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name">
<a href="BusinessContact.html#getCommonGroups" class="!symbol-index-name">BusinessContact#<wbr>getCommonGroups()</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="BusinessContact.html#getCountryCode" class="!symbol-index-name">BusinessContact#<wbr>getCountryCode()</a> <a href="BusinessContact.html#getCountryCode" class="!symbol-index-name">BusinessContact#<wbr>getCountryCode()</a>
</dt> </dt>
@@ -292,15 +303,15 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="BusinessContact.html#getProfilePicUrl" class="!symbol-index-name">BusinessContact#<wbr>getProfilePicUrl()</a> <a href="BusinessContact.html#getProfilePicUrl" class="!symbol-index-name">BusinessContact#<wbr>getProfilePicUrl()</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="BusinessContact.html#id" class="!symbol-index-name">BusinessContact#<wbr>id</a> <a href="BusinessContact.html#id" class="!symbol-index-name">BusinessContact#<wbr>id</a>
</dt> </dt>
@@ -336,15 +347,15 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="BusinessContact.html#isUser" class="!symbol-index-name">BusinessContact#<wbr>isUser</a> <a href="BusinessContact.html#isUser" class="!symbol-index-name">BusinessContact#<wbr>isUser</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="BusinessContact.html#isWAContact" class="!symbol-index-name">BusinessContact#<wbr>isWAContact</a> <a href="BusinessContact.html#isWAContact" class="!symbol-index-name">BusinessContact#<wbr>isWAContact</a>
</dt> </dt>
@@ -703,7 +714,7 @@ client.initialize();
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Client.html#acceptGroupV4Invite" class="!symbol-index-name">Client#<wbr>acceptGroupV4Invite(inviteV4)</a> <a href="Client.html#acceptGroupV4Invite" class="!symbol-index-name">Client#<wbr>acceptGroupV4Invite(inviteInfo)</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
@@ -792,15 +803,15 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Client.html#event:message_revoke_everyone" class="!symbol-index-name">Client#<wbr>event:message_revoke_everyone</a> <a href="Client.html#event:message_revoke_everyone" class="!symbol-index-name">Client#<wbr>event:message_revoke_everyone</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Client.html#event:message_revoke_me" class="!symbol-index-name">Client#<wbr>event:message_revoke_me</a> <a href="Client.html#event:message_revoke_me" class="!symbol-index-name">Client#<wbr>event:message_revoke_me</a>
</dt> </dt>
@@ -841,6 +852,11 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name">
<a href="Client.html#getCommonGroups" class="!symbol-index-name">Client#<wbr>getCommonGroups(contactId)</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Client.html#getContactById" class="!symbol-index-name">Client#<wbr>getContactById(contactId)</a> <a href="Client.html#getContactById" class="!symbol-index-name">Client#<wbr>getContactById(contactId)</a>
</dt> </dt>
@@ -891,15 +907,15 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Client.html#getWWebVersion" class="!symbol-index-name">Client#<wbr>getWWebVersion()</a> <a href="Client.html#getWWebVersion" class="!symbol-index-name">Client#<wbr>getWWebVersion()</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Client.html#info" class="!symbol-index-name">Client#<wbr>info</a> <a href="Client.html#info" class="!symbol-index-name">Client#<wbr>info</a>
</dt> </dt>
@@ -955,6 +971,11 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name">
<a href="Client.html#sendPresenceUnavailable" class="!symbol-index-name">Client#<wbr>sendPresenceUnavailable()</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Client.html#sendSeen" class="!symbol-index-name">Client#<wbr>sendSeen(chatId)</a> <a href="Client.html#sendSeen" class="!symbol-index-name">Client#<wbr>sendSeen(chatId)</a>
</dt> </dt>
@@ -1070,6 +1091,11 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name">
<a href="Contact.html#getCommonGroups" class="!symbol-index-name">Contact#<wbr>getCommonGroups()</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Contact.html#getCountryCode" class="!symbol-index-name">Contact#<wbr>getCountryCode()</a> <a href="Contact.html#getCountryCode" class="!symbol-index-name">Contact#<wbr>getCountryCode()</a>
</dt> </dt>
@@ -1124,15 +1150,15 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Contact.html#isUser" class="!symbol-index-name">Contact#<wbr>isUser</a> <a href="Contact.html#isUser" class="!symbol-index-name">Contact#<wbr>isUser</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Contact.html#isWAContact" class="!symbol-index-name">Contact#<wbr>isWAContact</a> <a href="Contact.html#isWAContact" class="!symbol-index-name">Contact#<wbr>isWAContact</a>
</dt> </dt>
@@ -1767,6 +1793,30 @@ client.initialize();
</div> </div>
</div> </div>
</section> </section>
<section>
<div class="symbol-index-content">
<h2 id="LegacySessionAuth">LegacySessionAuth</h2>
<div class="symbol-index-section">
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name">
<a href="LegacySessionAuth.html" class="!symbol-index-name">LegacySessionAuth(options)</a>
</dt>
<dd>
</dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
</div>
</div>
</section>
<section> <section>
<div class="symbol-index-content"> <div class="symbol-index-content">
<h2 id="List">List</h2> <h2 id="List">List</h2>
@@ -1821,6 +1871,30 @@ client.initialize();
</div> </div>
</div> </div>
</section> </section>
<section>
<div class="symbol-index-content">
<h2 id="LocalAuth">LocalAuth</h2>
<div class="symbol-index-section">
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name">
<a href="LocalAuth.html" class="!symbol-index-name">LocalAuth(options)</a>
</dt>
<dd>
</dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
</div>
</div>
</section>
<section> <section>
<div class="symbol-index-content"> <div class="symbol-index-content">
<h2 id="Location">Location</h2> <h2 id="Location">Location</h2>
@@ -1911,6 +1985,11 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name">
<a href="Message.html#duration" class="!symbol-index-name">Message#<wbr>duration</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Message.html#forward" class="!symbol-index-name">Message#<wbr>forward(chat)</a> <a href="Message.html#forward" class="!symbol-index-name">Message#<wbr>forward(chat)</a>
</dt> </dt>
@@ -2010,15 +2089,15 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Message.html#isStatus" class="!symbol-index-name">Message#<wbr>isStatus</a> <a href="Message.html#isStatus" class="!symbol-index-name">Message#<wbr>isStatus</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Message.html#links" class="!symbol-index-name">Message#<wbr>links</a> <a href="Message.html#links" class="!symbol-index-name">Message#<wbr>links</a>
</dt> </dt>
@@ -2044,6 +2123,16 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name">
<a href="Message.html#rawData" class="!symbol-index-name">Message#<wbr>rawData</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name">
<a href="Message.html#reload" class="!symbol-index-name">Message#<wbr>reload()</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="Message.html#reply" class="!symbol-index-name">Message#<wbr>reply(content[, chatId][, options])</a> <a href="Message.html#reply" class="!symbol-index-name">Message#<wbr>reply(content[, chatId][, options])</a>
</dt> </dt>
@@ -2381,6 +2470,30 @@ client.initialize();
</div> </div>
</div> </div>
</section> </section>
<section>
<div class="symbol-index-content">
<h2 id="NoAuth">NoAuth</h2>
<div class="symbol-index-section">
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name">
<a href="NoAuth.html" class="!symbol-index-name">NoAuth()</a>
</dt>
<dd>
</dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
</dl>
</div>
</div>
</div>
</section>
<section> <section>
<div class="symbol-index-content"> <div class="symbol-index-content">
<h2 id="Order">Order</h2> <h2 id="Order">Order</h2>
@@ -2669,6 +2782,11 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
<dt class="symbol-index-name">
<a href="PrivateContact.html#getCommonGroups" class="!symbol-index-name">PrivateContact#<wbr>getCommonGroups()</a>
</dt>
<dd>
</dd>
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="PrivateContact.html#getCountryCode" class="!symbol-index-name">PrivateContact#<wbr>getCountryCode()</a> <a href="PrivateContact.html#getCountryCode" class="!symbol-index-name">PrivateContact#<wbr>getCountryCode()</a>
</dt> </dt>
@@ -2723,15 +2841,15 @@ client.initialize();
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="PrivateContact.html#isUser" class="!symbol-index-name">PrivateContact#<wbr>isUser</a> <a href="PrivateContact.html#isUser" class="!symbol-index-name">PrivateContact#<wbr>isUser</a>
</dt> </dt>
<dd> <dd>
</dd> </dd>
</dl>
</div>
<div class="symbol-index-column">
<dl class="symbol-index-list">
<dt class="symbol-index-name"> <dt class="symbol-index-name">
<a href="PrivateContact.html#isWAContact" class="!symbol-index-name">PrivateContact#<wbr>isWAContact</a> <a href="PrivateContact.html#isWAContact" class="!symbol-index-name">PrivateContact#<wbr>isWAContact</a>
</dt> </dt>
@@ -3031,7 +3149,7 @@ client.initialize();
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -6,7 +6,7 @@
treeNode.tree({ treeNode.tree({
autoEscape: false, autoEscape: false,
closedIcon: '&#x21e2;', closedIcon: '&#x21e2;',
data: [{"label":"<a href=\"global.html\">Globals</a>","id":"global","children":[]},{"label":"<a href=\"Base.html\">Base</a>","id":"Base","children":[]},{"label":"<a href=\"BusinessContact.html\">BusinessContact</a>","id":"BusinessContact","children":[]},{"label":"<a href=\"Buttons.html\">Buttons</a>","id":"Buttons","children":[]},{"label":"<a href=\"Call.html\">Call</a>","id":"Call","children":[]},{"label":"<a href=\"Chat.html\">Chat</a>","id":"Chat","children":[]},{"label":"<a href=\"Client.html\">Client</a>","id":"Client","children":[]},{"label":"<a href=\"ClientInfo.html\">ClientInfo</a>","id":"ClientInfo","children":[]},{"label":"<a href=\"Contact.html\">Contact</a>","id":"Contact","children":[]},{"label":"<a href=\"GroupChat.html\">GroupChat</a>","id":"GroupChat","children":[]},{"label":"<a href=\"GroupNotification.html\">GroupNotification</a>","id":"GroupNotification","children":[]},{"label":"<a href=\"InterfaceController.html\">InterfaceController</a>","id":"InterfaceController","children":[]},{"label":"<a href=\"Label.html\">Label</a>","id":"Label","children":[]},{"label":"<a href=\"List.html\">List</a>","id":"List","children":[]},{"label":"<a href=\"Location.html\">Location</a>","id":"Location","children":[]},{"label":"<a href=\"Message.html\">Message</a>","id":"Message","children":[]},{"label":"<a href=\"MessageMedia.html\">MessageMedia</a>","id":"MessageMedia","children":[]},{"label":"<a href=\"Order.html\">Order</a>","id":"Order","children":[]},{"label":"<a href=\"PrivateChat.html\">PrivateChat</a>","id":"PrivateChat","children":[]},{"label":"<a href=\"PrivateContact.html\">PrivateContact</a>","id":"PrivateContact","children":[]},{"label":"<a href=\"Product.html\">Product</a>","id":"Product","children":[]},{"label":"<a href=\"Util.html\">Util</a>","id":"Util","children":[]}], data: [{"label":"<a href=\"global.html\">Globals</a>","id":"global","children":[]},{"label":"<a href=\"Base.html\">Base</a>","id":"Base","children":[]},{"label":"<a href=\"BaseAuthStrategy.html\">BaseAuthStrategy</a>","id":"BaseAuthStrategy","children":[]},{"label":"<a href=\"BusinessContact.html\">BusinessContact</a>","id":"BusinessContact","children":[]},{"label":"<a href=\"Buttons.html\">Buttons</a>","id":"Buttons","children":[]},{"label":"<a href=\"Call.html\">Call</a>","id":"Call","children":[]},{"label":"<a href=\"Chat.html\">Chat</a>","id":"Chat","children":[]},{"label":"<a href=\"Client.html\">Client</a>","id":"Client","children":[]},{"label":"<a href=\"ClientInfo.html\">ClientInfo</a>","id":"ClientInfo","children":[]},{"label":"<a href=\"Contact.html\">Contact</a>","id":"Contact","children":[]},{"label":"<a href=\"GroupChat.html\">GroupChat</a>","id":"GroupChat","children":[]},{"label":"<a href=\"GroupNotification.html\">GroupNotification</a>","id":"GroupNotification","children":[]},{"label":"<a href=\"InterfaceController.html\">InterfaceController</a>","id":"InterfaceController","children":[]},{"label":"<a href=\"Label.html\">Label</a>","id":"Label","children":[]},{"label":"<a href=\"LegacySessionAuth.html\">LegacySessionAuth</a>","id":"LegacySessionAuth","children":[]},{"label":"<a href=\"List.html\">List</a>","id":"List","children":[]},{"label":"<a href=\"LocalAuth.html\">LocalAuth</a>","id":"LocalAuth","children":[]},{"label":"<a href=\"Location.html\">Location</a>","id":"Location","children":[]},{"label":"<a href=\"Message.html\">Message</a>","id":"Message","children":[]},{"label":"<a href=\"MessageMedia.html\">MessageMedia</a>","id":"MessageMedia","children":[]},{"label":"<a href=\"NoAuth.html\">NoAuth</a>","id":"NoAuth","children":[]},{"label":"<a href=\"Order.html\">Order</a>","id":"Order","children":[]},{"label":"<a href=\"PrivateChat.html\">PrivateChat</a>","id":"PrivateChat","children":[]},{"label":"<a href=\"PrivateContact.html\">PrivateContact</a>","id":"PrivateContact","children":[]},{"label":"<a href=\"Product.html\">Product</a>","id":"Product","children":[]},{"label":"<a href=\"Util.html\">Util</a>","id":"Util","children":[]}],
openedIcon: ' &#x21e3;', openedIcon: ' &#x21e3;',
saveState: false, saveState: false,
useContextMenu: false useContextMenu: false

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Base.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Base.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -60,7 +60,7 @@ module.exports &#x3D; Base;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/BusinessContact.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/BusinessContact.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -59,7 +59,7 @@ module.exports &#x3D; BusinessContact;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Buttons.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Buttons.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -120,7 +120,7 @@ module.exports &#x3D; Buttons;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Call.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Call.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -106,7 +106,7 @@ module.exports &#x3D; Call;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Chat.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Chat.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -210,11 +210,11 @@ class Chat extends Base {
const msgFilter &#x3D; m &#x3D;&gt; !m.isNotification; // dont include notification messages const msgFilter &#x3D; m &#x3D;&gt; !m.isNotification; // dont include notification messages
const chat &#x3D; window.Store.Chat.get(chatId); const chat &#x3D; window.Store.Chat.get(chatId);
let msgs &#x3D; chat.msgs.models.filter(msgFilter); let msgs &#x3D; chat.msgs.getModelsArray().filter(msgFilter);
if (searchOptions &amp;amp;&amp;amp; searchOptions.limit &gt; 0) { if (searchOptions &amp;amp;&amp;amp; searchOptions.limit &gt; 0) {
while (msgs.length &amp;lt; searchOptions.limit) { while (msgs.length &amp;lt; searchOptions.limit) {
const loadedMessages &#x3D; await chat.loadEarlierMsgs(); const loadedMessages &#x3D; await window.Store.ConversationMsgs.loadEarlierMsgs(chat);
if (!loadedMessages) break; if (!loadedMessages) break;
msgs &#x3D; [...loadedMessages.filter(msgFilter), ...msgs]; msgs &#x3D; [...loadedMessages.filter(msgFilter), ...msgs];
} }
@@ -290,7 +290,7 @@ module.exports &#x3D; Chat;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/ClientInfo.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/ClientInfo.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -51,12 +51,6 @@ class ClientInfo extends Base {
*/ */
this.pushname &#x3D; data.pushname; this.pushname &#x3D; data.pushname;
/**
* @type {object}
* @deprecated Use .wid instead
*/
this.me &#x3D; data.wid;
/** /**
* Current user ID * Current user ID
* @type {object} * @type {object}
@@ -64,18 +58,25 @@ class ClientInfo extends Base {
this.wid &#x3D; data.wid; this.wid &#x3D; data.wid;
/** /**
* Information about the phone this client is connected to * @type {object}
* @deprecated Use .wid instead
*/
this.me &#x3D; data.wid;
/**
* Information about the phone this client is connected to. Not available in multi-device.
* @type {object} * @type {object}
* @property {string} wa_version WhatsApp Version running on the phone * @property {string} wa_version WhatsApp Version running on the phone
* @property {string} os_version OS Version running on the phone (iOS or Android version) * @property {string} os_version OS Version running on the phone (iOS or Android version)
* @property {string} device_manufacturer Device manufacturer * @property {string} device_manufacturer Device manufacturer
* @property {string} device_model Device model * @property {string} device_model Device model
* @property {string} os_build_number OS build number * @property {string} os_build_number OS build number
* @deprecated
*/ */
this.phone &#x3D; data.phone; this.phone &#x3D; data.phone;
/** /**
* Platform the phone is running on * Platform WhatsApp is running on
* @type {string} * @type {string}
*/ */
this.platform &#x3D; data.platform; this.platform &#x3D; data.platform;
@@ -88,6 +89,7 @@ class ClientInfo extends Base {
* @returns {object} batteryStatus * @returns {object} batteryStatus
* @returns {number} batteryStatus.battery - The current battery percentage * @returns {number} batteryStatus.battery - The current battery percentage
* @returns {boolean} batteryStatus.plugged - Indicates if the phone is plugged in (true) or not (false) * @returns {boolean} batteryStatus.plugged - Indicates if the phone is plugged in (true) or not (false)
* @deprecated
*/ */
async getBatteryStatus() { async getBatteryStatus() {
return await this.client.pupPage.evaluate(() &#x3D;&gt; { return await this.client.pupPage.evaluate(() &#x3D;&gt; {
@@ -95,7 +97,6 @@ class ClientInfo extends Base {
return { battery, plugged }; return { battery, plugged };
}); });
} }
} }
module.exports &#x3D; ClientInfo;</code></pre> module.exports &#x3D; ClientInfo;</code></pre>
@@ -108,7 +109,7 @@ module.exports &#x3D; ClientInfo;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Contact.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Contact.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -214,7 +214,8 @@ class Contact extends Base {
*/ */
async getAbout() { async getAbout() {
const about &#x3D; await this.client.pupPage.evaluate(async (contactId) &#x3D;&gt; { const about &#x3D; await this.client.pupPage.evaluate(async (contactId) &#x3D;&gt; {
return window.Store.Wap.statusFind(contactId); const wid &#x3D; window.Store.WidFactory.createWid(contactId);
return window.Store.StatusUtils.getStatus(wid);
}, this.id._serialized); }, this.id._serialized);
if (typeof about.status !&#x3D;&#x3D; &#x27;string&#x27;) if (typeof about.status !&#x3D;&#x3D; &#x27;string&#x27;)
@@ -222,6 +223,14 @@ class Contact extends Base {
return about.status; return about.status;
} }
/**
* Gets the Contact&#x27;s common groups with you. Returns empty array if you don&#x27;t have any common group.
* @returns {Promise&amp;lt;WAWebJS.ChatId[]&gt;}
*/
async getCommonGroups() {
return await this.client.getCommonGroups(this.id._serialized);
}
} }
@@ -236,7 +245,7 @@ module.exports &#x3D; Contact;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/GroupChat.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/GroupChat.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -91,7 +91,9 @@ class GroupChat extends Chat {
*/ */
async addParticipants(participantIds) { async addParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; { return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.addParticipants(chatId, participantIds); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
const participantWids &#x3D; participantIds.map(p &#x3D;&gt; window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendAddParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
@@ -102,7 +104,9 @@ class GroupChat extends Chat {
*/ */
async removeParticipants(participantIds) { async removeParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; { return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.removeParticipants(chatId, participantIds); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
const participantWids &#x3D; participantIds.map(p &#x3D;&gt; window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendRemoveParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
@@ -113,7 +117,9 @@ class GroupChat extends Chat {
*/ */
async promoteParticipants(participantIds) { async promoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; { return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.promoteParticipants(chatId, participantIds); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
const participantWids &#x3D; participantIds.map(p &#x3D;&gt; window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendPromoteParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
@@ -124,39 +130,53 @@ class GroupChat extends Chat {
*/ */
async demoteParticipants(participantIds) { async demoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; { return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.demoteParticipants(chatId, participantIds); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
const participantWids &#x3D; participantIds.map(p &#x3D;&gt; window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendDemoteParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
/** /**
* Updates the group subject * Updates the group subject
* @param {string} subject * @param {string} subject
* @returns {Promise} * @returns {Promise&amp;lt;boolean&gt;} Returns true if the subject was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setSubject(subject) { async setSubject(subject) {
let res &#x3D; await this.client.pupPage.evaluate((chatId, subject) &#x3D;&gt; { const success &#x3D; await this.client.pupPage.evaluate(async (chatId, subject) &#x3D;&gt; {
return window.Store.Wap.changeSubject(chatId, subject); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
try {
return await window.Store.GroupUtils.sendSetGroupSubject(chatWid, subject);
} catch (err) {
if(err.name &#x3D;&#x3D;&#x3D; &#x27;ServerStatusCodeError&#x27;) return false;
throw err;
}
}, this.id._serialized, subject); }, this.id._serialized, subject);
if(res.status &#x3D;&#x3D; 200) { if(!success) return false;
this.name &#x3D; subject; this.name &#x3D; subject;
} return true;
} }
/** /**
* Updates the group description * Updates the group description
* @param {string} description * @param {string} description
* @returns {Promise} * @returns {Promise&amp;lt;boolean&gt;} Returns true if the description was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setDescription(description) { async setDescription(description) {
let res &#x3D; await this.client.pupPage.evaluate((chatId, description) &#x3D;&gt; { const success &#x3D; await this.client.pupPage.evaluate(async (chatId, description) &#x3D;&gt; {
let descId &#x3D; window.Store.GroupMetadata.get(chatId).descId; const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
return window.Store.Wap.setGroupDescription(chatId, description, window.Store.genId(), descId); let descId &#x3D; window.Store.GroupMetadata.get(chatWid).descId;
try {
return await window.Store.GroupUtils.sendSetGroupDescription(chatWid, description, window.Store.MsgKey.newId(), descId);
} catch (err) {
if(err.name &#x3D;&#x3D;&#x3D; &#x27;ServerStatusCodeError&#x27;) return false;
throw err;
}
}, this.id._serialized, description); }, this.id._serialized, description);
if (res.status &#x3D;&#x3D; 200) { if(!success) return false;
this.groupMetadata.desc &#x3D; description; this.groupMetadata.desc &#x3D; description;
} return true;
} }
/** /**
@@ -165,12 +185,18 @@ class GroupChat extends Chat {
* @returns {Promise&amp;lt;boolean&gt;} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions. * @returns {Promise&amp;lt;boolean&gt;} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setMessagesAdminsOnly(adminsOnly&#x3D;true) { async setMessagesAdminsOnly(adminsOnly&#x3D;true) {
let res &#x3D; await this.client.pupPage.evaluate((chatId, value) &#x3D;&gt; { const success &#x3D; await this.client.pupPage.evaluate(async (chatId, adminsOnly) &#x3D;&gt; {
return window.Store.Wap.setGroupProperty(chatId, &#x27;announcement&#x27;, value); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
try {
return await window.Store.GroupUtils.sendSetGroupProperty(chatWid, &#x27;announcement&#x27;, adminsOnly ? 1 : 0);
} catch (err) {
if(err.name &#x3D;&#x3D;&#x3D; &#x27;ServerStatusCodeError&#x27;) return false;
throw err;
}
}, this.id._serialized, adminsOnly); }, this.id._serialized, adminsOnly);
if (res.status !&#x3D;&#x3D; 200) return false; if(!success) return false;
this.groupMetadata.announce &#x3D; adminsOnly; this.groupMetadata.announce &#x3D; adminsOnly;
return true; return true;
} }
@@ -181,11 +207,17 @@ class GroupChat extends Chat {
* @returns {Promise&amp;lt;boolean&gt;} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions. * @returns {Promise&amp;lt;boolean&gt;} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setInfoAdminsOnly(adminsOnly&#x3D;true) { async setInfoAdminsOnly(adminsOnly&#x3D;true) {
let res &#x3D; await this.client.pupPage.evaluate((chatId, value) &#x3D;&gt; { const success &#x3D; await this.client.pupPage.evaluate(async (chatId, adminsOnly) &#x3D;&gt; {
return window.Store.Wap.setGroupProperty(chatId, &#x27;restrict&#x27;, value); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
try {
return await window.Store.GroupUtils.sendSetGroupProperty(chatWid, &#x27;restrict&#x27;, adminsOnly ? 1 : 0);
} catch (err) {
if(err.name &#x3D;&#x3D;&#x3D; &#x27;ServerStatusCodeError&#x27;) return false;
throw err;
}
}, this.id._serialized, adminsOnly); }, this.id._serialized, adminsOnly);
if (res.status !&#x3D;&#x3D; 200) return false; if(!success) return false;
this.groupMetadata.restrict &#x3D; adminsOnly; this.groupMetadata.restrict &#x3D; adminsOnly;
return true; return true;
@@ -196,25 +228,25 @@ class GroupChat extends Chat {
* @returns {Promise&amp;lt;string&gt;} Group&#x27;s invite code * @returns {Promise&amp;lt;string&gt;} Group&#x27;s invite code
*/ */
async getInviteCode() { async getInviteCode() {
let res &#x3D; await this.client.pupPage.evaluate(chatId &#x3D;&gt; { const code &#x3D; await this.client.pupPage.evaluate(async chatId &#x3D;&gt; {
return window.Store.Wap.groupInviteCode(chatId); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
return window.Store.Invite.sendQueryGroupInviteCode(chatWid);
}, this.id._serialized); }, this.id._serialized);
if (res.status &#x3D;&#x3D; 200) { return code;
return res.code;
}
throw new Error(&#x27;Not authorized&#x27;);
} }
/** /**
* Invalidates the current group invite code and generates a new one * Invalidates the current group invite code and generates a new one
* @returns {Promise} * @returns {Promise&amp;lt;string&gt;} New invite code
*/ */
async revokeInvite() { async revokeInvite() {
return await this.client.pupPage.evaluate(chatId &#x3D;&gt; { const code &#x3D; await this.client.pupPage.evaluate(chatId &#x3D;&gt; {
return window.Store.Wap.revokeGroupInvite(chatId); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
return window.Store.Invite.sendRevokeGroupInviteCode(chatWid);
}, this.id._serialized); }, this.id._serialized);
return code;
} }
/** /**
@@ -222,8 +254,9 @@ class GroupChat extends Chat {
* @returns {Promise} * @returns {Promise}
*/ */
async leave() { async leave() {
return await this.client.pupPage.evaluate(chatId &#x3D;&gt; { await this.client.pupPage.evaluate(chatId &#x3D;&gt; {
return window.Store.Wap.leaveGroup(chatId); const chatWid &#x3D; window.Store.WidFactory.createWid(chatId);
return window.Store.GroupUtils.sendExitGroup(chatWid);
}, this.id._serialized); }, this.id._serialized);
} }
@@ -239,7 +272,7 @@ module.exports &#x3D; GroupChat;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/GroupNotification.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/GroupNotification.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -74,7 +74,7 @@ class GroupNotification extends Base {
* *
* @type {string} * @type {string}
*/ */
this.chatId &#x3D; typeof (data.to) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; ? data.to._serialized : data.to; this.chatId &#x3D; typeof (data.id.remote) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; ? data.id.remote._serialized : data.id.remote;
/** /**
* ContactId for the user that produced the GroupNotification. * ContactId for the user that produced the GroupNotification.
@@ -143,7 +143,7 @@ module.exports &#x3D; GroupNotification;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Label.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Label.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -88,7 +88,7 @@ module.exports &#x3D; Label;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/List.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/List.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -118,7 +118,7 @@ module.exports &#x3D; List;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Location.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Location.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -71,7 +71,7 @@ module.exports &#x3D; Location;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Message.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Message.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -50,13 +50,14 @@ class Message extends Base {
} }
_patch(data) { _patch(data) {
this._data &#x3D; data;
/** /**
* MediaKey that represents the sticker &#x27;ID&#x27; * MediaKey that represents the sticker &#x27;ID&#x27;
* @type {string} * @type {string}
*/ */
this.mediaKey &#x3D; data.mediaKey; this.mediaKey &#x3D; data.mediaKey;
/** /**
* ID that represents the message * ID that represents the message
* @type {object} * @type {object}
@@ -81,7 +82,7 @@ class Message extends Base {
*/ */
this.body &#x3D; this.hasMedia ? data.caption || &#x27;&#x27; : data.body || &#x27;&#x27;; this.body &#x3D; this.hasMedia ? data.caption || &#x27;&#x27; : data.body || &#x27;&#x27;;
/** /**
* Message type * Message type
* @type {MessageTypes} * @type {MessageTypes}
*/ */
@@ -101,9 +102,9 @@ class Message extends Base {
/** /**
* ID for who this message is for. * ID for who this message is for.
* *
* If the message is sent by the current user, it will be the Chat to which the message is being sent. * If the message is sent by the current user, it will be the Chat to which the message is being sent.
* If the message is sent by another user, it will be the ID for the current user. * If the message is sent by another user, it will be the ID for the current user.
* @type {string} * @type {string}
*/ */
this.to &#x3D; (typeof (data.to) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; &amp;amp;&amp;amp; data.to !&#x3D;&#x3D; null) ? data.to._serialized : data.to; this.to &#x3D; (typeof (data.to) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; &amp;amp;&amp;amp; data.to !&#x3D;&#x3D; null) ? data.to._serialized : data.to;
@@ -118,8 +119,8 @@ class Message extends Base {
* String that represents from which device type the message was sent * String that represents from which device type the message was sent
* @type {string} * @type {string}
*/ */
this.deviceType &#x3D; data.id.id.length &gt; 21 ? &#x27;android&#x27; : data.id.id.substring(0,2) &#x3D;&#x3D;&#x27;3A&#x27; ? &#x27;ios&#x27; : &#x27;web&#x27;; this.deviceType &#x3D; data.id.id.length &gt; 21 ? &#x27;android&#x27; : data.id.id.substring(0, 2) &#x3D;&#x3D; &#x27;3A&#x27; ? &#x27;ios&#x27; : &#x27;web&#x27;;
/** /**
* Indicates if the message was forwarded * Indicates if the message was forwarded
* @type {boolean} * @type {boolean}
@@ -145,14 +146,14 @@ class Message extends Base {
* @type {boolean} * @type {boolean}
*/ */
this.isStarred &#x3D; data.star; this.isStarred &#x3D; data.star;
/** /**
* Indicates if the message was a broadcast * Indicates if the message was a broadcast
* @type {boolean} * @type {boolean}
*/ */
this.broadcast &#x3D; data.broadcast; this.broadcast &#x3D; data.broadcast;
/** /**
* Indicates if the message was sent by the current user * Indicates if the message was sent by the current user
* @type {boolean} * @type {boolean}
*/ */
@@ -164,6 +165,12 @@ class Message extends Base {
*/ */
this.hasQuotedMsg &#x3D; data.quotedMsg ? true : false; this.hasQuotedMsg &#x3D; data.quotedMsg ? true : false;
/**
* Indicates the duration of the message in seconds
* @type {string}
*/
this.duration &#x3D; data.duration ? data.duration : undefined;
/** /**
* Location information contained in the message, if the message is type &quot;location&quot; * Location information contained in the message, if the message is type &quot;location&quot;
* @type {Location} * @type {Location}
@@ -188,7 +195,7 @@ class Message extends Base {
fromId: data.from._serialized, fromId: data.from._serialized,
toId: data.to._serialized toId: data.to._serialized
} : undefined; } : undefined;
/** /**
* Indicates the mentions in the message body. * Indicates the mentions in the message body.
* @type {Array&amp;lt;string&gt;} * @type {Array&amp;lt;string&gt;}
@@ -245,7 +252,7 @@ class Message extends Base {
/** /**
* Links included in the message. * Links included in the message.
* @type {Array&amp;lt;{link: string, isSuspicious: boolean}&gt;} * @type {Array&amp;lt;{link: string, isSuspicious: boolean}&gt;}
* *
*/ */
this.links &#x3D; data.links; this.links &#x3D; data.links;
@@ -253,7 +260,7 @@ class Message extends Base {
if (data.dynamicReplyButtons) { if (data.dynamicReplyButtons) {
this.dynamicReplyButtons &#x3D; data.dynamicReplyButtons; this.dynamicReplyButtons &#x3D; data.dynamicReplyButtons;
} }
/** Selected Button Id **/ /** Selected Button Id **/
if (data.selectedButtonId) { if (data.selectedButtonId) {
this.selectedButtonId &#x3D; data.selectedButtonId; this.selectedButtonId &#x3D; data.selectedButtonId;
@@ -263,7 +270,7 @@ class Message extends Base {
if (data.listResponse &amp;amp;&amp;amp; data.listResponse.singleSelectReply.selectedRowId) { if (data.listResponse &amp;amp;&amp;amp; data.listResponse.singleSelectReply.selectedRowId) {
this.selectedRowId &#x3D; data.listResponse.singleSelectReply.selectedRowId; this.selectedRowId &#x3D; data.listResponse.singleSelectReply.selectedRowId;
} }
return super._patch(data); return super._patch(data);
} }
@@ -271,6 +278,32 @@ class Message extends Base {
return this.fromMe ? this.to : this.from; return this.fromMe ? this.to : this.from;
} }
/**
* Reloads this Message object&#x27;s data in-place with the latest values from WhatsApp Web.
* Note that the Message must still be in the web app cache for this to work, otherwise will return null.
* @returns {Promise&amp;lt;Message&gt;}
*/
async reload() {
const newData &#x3D; await this.client.pupPage.evaluate((msgId) &#x3D;&gt; {
const msg &#x3D; window.Store.Msg.get(msgId);
if(!msg) return null;
return window.WWebJS.getMessageModel(msg);
}, this.id._serialized);
if(!newData) return null;
this._patch(newData);
return this;
}
/**
* Returns message in a raw format
* @type {Object}
*/
get rawData() {
return this._data;
}
/** /**
* Returns the Chat this message was sent in * Returns the Chat this message was sent in
* @returns {Promise&amp;lt;Chat&gt;} * @returns {Promise&amp;lt;Chat&gt;}
@@ -311,12 +344,12 @@ class Message extends Base {
} }
/** /**
* Sends a message as a reply to this message. If chatId is specified, it will be sent * Sends a message as a reply to this message. If chatId is specified, it will be sent
* through the specified Chat. If not, it will send the message * through the specified Chat. If not, it will send the message
* in the same Chat as the original message was sent. * in the same Chat as the original message was sent.
* *
* @param {string|MessageMedia|Location} content * @param {string|MessageMedia|Location} content
* @param {string} [chatId] * @param {string} [chatId]
* @param {MessageSendOptions} [options] * @param {MessageSendOptions} [options]
* @returns {Promise&amp;lt;Message&gt;} * @returns {Promise&amp;lt;Message&gt;}
*/ */
@@ -340,10 +373,10 @@ class Message extends Base {
async acceptGroupV4Invite() { async acceptGroupV4Invite() {
return await this.client.acceptGroupV4Invite(this.inviteV4); return await this.client.acceptGroupV4Invite(this.inviteV4);
} }
/** /**
* Forwards this message to another chat * Forwards this message to another chat
* *
* @param {string|Chat} chat Chat model or chat ID to which the message will be forwarded * @param {string|Chat} chat Chat model or chat ID to which the message will be forwarded
* @returns {Promise} * @returns {Promise}
*/ */
@@ -373,7 +406,7 @@ class Message extends Base {
if (msg.mediaData.mediaStage !&#x3D; &#x27;RESOLVED&#x27;) { if (msg.mediaData.mediaStage !&#x3D; &#x27;RESOLVED&#x27;) {
// try to resolve media // try to resolve media
await msg.downloadMedia({ await msg.downloadMedia({
downloadEvenIfExpensive: true, downloadEvenIfExpensive: true,
rmrReason: 1 rmrReason: 1
}); });
} }
@@ -393,9 +426,9 @@ class Message extends Base {
type: msg.type, type: msg.type,
signal: (new AbortController).signal signal: (new AbortController).signal
}); });
const data &#x3D; window.WWebJS.arrayBufferToBase64(decryptedMedia); const data &#x3D; window.WWebJS.arrayBufferToBase64(decryptedMedia);
return { return {
data, data,
mimetype: msg.mimetype, mimetype: msg.mimetype,
@@ -420,7 +453,7 @@ class Message extends Base {
let msg &#x3D; window.Store.Msg.get(msgId); let msg &#x3D; window.Store.Msg.get(msgId);
if (everyone &amp;amp;&amp;amp; msg.id.fromMe &amp;amp;&amp;amp; msg._canRevoke()) { if (everyone &amp;amp;&amp;amp; msg.id.fromMe &amp;amp;&amp;amp; msg._canRevoke()) {
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], true); return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], {type: &#x27;Sender&#x27;});
} }
return window.Store.Cmd.sendDeleteMsgs(msg.chat, [msg], true); return window.Store.Cmd.sendDeleteMsgs(msg.chat, [msg], true);
@@ -471,14 +504,10 @@ class Message extends Base {
async getInfo() { async getInfo() {
const info &#x3D; await this.client.pupPage.evaluate(async (msgId) &#x3D;&gt; { const info &#x3D; await this.client.pupPage.evaluate(async (msgId) &#x3D;&gt; {
const msg &#x3D; window.Store.Msg.get(msgId); const msg &#x3D; window.Store.Msg.get(msgId);
if(!msg) return null; if (!msg) return null;
return await window.Store.Wap.queryMsgInfo(msg.id);
}, this.id._serialized);
if(info.status) { return await window.Store.MessageInfo.sendQueryMsgInfo(msg);
return null; }, this.id._serialized);
}
return info; return info;
} }
@@ -489,9 +518,9 @@ class Message extends Base {
*/ */
async getOrder() { async getOrder() {
if (this.type &#x3D;&#x3D;&#x3D; MessageTypes.ORDER) { if (this.type &#x3D;&#x3D;&#x3D; MessageTypes.ORDER) {
const result &#x3D; await this.client.pupPage.evaluate((orderId, token) &#x3D;&gt; { const result &#x3D; await this.client.pupPage.evaluate((orderId, token, chatId) &#x3D;&gt; {
return window.WWebJS.getOrderDetail(orderId, token); return window.WWebJS.getOrderDetail(orderId, token, chatId);
}, this.orderId, this.token); }, this.orderId, this.token, this._getChatId());
if (!result) return undefined; if (!result) return undefined;
return new Order(this.client, result); return new Order(this.client, result);
} }
@@ -525,7 +554,7 @@ module.exports &#x3D; Message;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/MessageMedia.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/MessageMedia.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -142,7 +142,7 @@ module.exports &#x3D; MessageMedia;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Order.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Order.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -90,7 +90,7 @@ module.exports &#x3D; Order;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Payment.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Payment.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -118,7 +118,7 @@ module.exports &#x3D; Payment;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/PrivateChat.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/PrivateChat.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -51,7 +51,7 @@ module.exports &#x3D; PrivateChat;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/PrivateContact.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/PrivateContact.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -51,7 +51,7 @@ module.exports &#x3D; PrivateContact;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/Product.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/Product.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -106,7 +106,7 @@ module.exports &#x3D; Product;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: structures/ProductMetadata.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: structures/ProductMetadata.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -63,7 +63,7 @@ module.exports &#x3D; ProductMetadata;</code></pre>
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: util/Constants.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: util/Constants.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -38,10 +38,7 @@ exports.DefaultOptions &#x3D; {
headless: true, headless: true,
defaultViewport: null defaultViewport: null
}, },
session: false, authTimeoutMs: 0,
qrTimeoutMs: 45000,
qrRefreshIntervalMs: 20000,
authTimeoutMs: 45000,
qrMaxRetries: 0, qrMaxRetries: 0,
takeoverOnConflict: false, takeoverOnConflict: false,
takeoverTimeoutMs: 0, takeoverTimeoutMs: 0,
@@ -200,7 +197,7 @@ exports.MessageAck &#x3D; {
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: util/InterfaceController.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: util/InterfaceController.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -160,7 +160,7 @@ module.exports &#x3D; InterfaceController;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -4,7 +4,7 @@
<head> <head>
<meta name="generator" content="JSDoc 3.6.7"> <meta name="generator" content="JSDoc 3.6.7">
<meta charset="utf-8"> <meta charset="utf-8">
<title>whatsapp-web.js 1.15.6 &raquo; Source: util/Util.js</title> <title>whatsapp-web.js 1.16.7 &raquo; Source: util/Util.js</title>
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css"> <link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
@@ -15,7 +15,7 @@
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar"> <nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
<div id="jsdoc-navbar-container"> <div id="jsdoc-navbar-container">
<div id="jsdoc-navbar-content"> <div id="jsdoc-navbar-content">
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>15.<wbr>6</a> <a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>16.<wbr>7</a>
</div> </div>
</div> </div>
</nav> </nav>
@@ -31,7 +31,6 @@
<article> <article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;; <pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const sharp &#x3D; require(&#x27;sharp&#x27;);
const path &#x3D; require(&#x27;path&#x27;); const path &#x3D; require(&#x27;path&#x27;);
const Crypto &#x3D; require(&#x27;crypto&#x27;); const Crypto &#x3D; require(&#x27;crypto&#x27;);
const { tmpdir } &#x3D; require(&#x27;os&#x27;); const { tmpdir } &#x3D; require(&#x27;os&#x27;);
@@ -45,7 +44,6 @@ const has &#x3D; (o, k) &#x3D;&gt; Object.prototype.hasOwnProperty.call(o, k);
* Utility methods * Utility methods
*/ */
class Util { class Util {
constructor() { constructor() {
throw new Error(&#x60;The ${this.constructor.name} class may not be instantiated.&#x60;); throw new Error(&#x60;The ${this.constructor.name} class may not be instantiated.&#x60;);
} }
@@ -54,7 +52,7 @@ class Util {
var result &#x3D; &#x27;&#x27;; var result &#x3D; &#x27;&#x27;;
var characters &#x3D; &#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&#x27;; var characters &#x3D; &#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&#x27;;
var charactersLength &#x3D; characters.length; var charactersLength &#x3D; characters.length;
for ( var i &#x3D; 0; i &amp;lt; length; i++ ) { for (var i &#x3D; 0; i &amp;lt; length; i++) {
result +&#x3D; characters.charAt(Math.floor(Math.random() * charactersLength)); result +&#x3D; characters.charAt(Math.floor(Math.random() * charactersLength));
} }
return result; return result;
@@ -86,33 +84,19 @@ class Util {
* *
* @returns {Promise&amp;lt;MessageMedia&gt;} media in webp format * @returns {Promise&amp;lt;MessageMedia&gt;} media in webp format
*/ */
static async formatImageToWebpSticker(media) { static async formatImageToWebpSticker(media, pupPage) {
if (!media.mimetype.includes(&#x27;image&#x27;)) if (!media.mimetype.includes(&#x27;image&#x27;))
throw new Error(&#x27;media is not a image&#x27;); throw new Error(&#x27;media is not a image&#x27;);
if (media.mimetype.includes(&#x27;webp&#x27;)) { if (media.mimetype.includes(&#x27;webp&#x27;)) {
return media; return media;
} }
const buff &#x3D; Buffer.from(media.data, &#x27;base64&#x27;); return pupPage.evaluate((media) &#x3D;&gt; {
return window.WWebJS.toStickerData(media);
let sharpImg &#x3D; sharp(buff); }, media);
sharpImg &#x3D; sharpImg.webp();
sharpImg &#x3D; sharpImg.resize(512, 512, {
fit: &#x27;contain&#x27;,
background: { r: 0, g: 0, b: 0, alpha: 0 },
});
let webpBase64 &#x3D; (await sharpImg.toBuffer()).toString(&#x27;base64&#x27;);
return {
mimetype: &#x27;image/webp&#x27;,
data: webpBase64,
filename: media.filename,
};
} }
/** /**
* Formats a video to webp * Formats a video to webp
* @param {MessageMedia} media * @param {MessageMedia} media
@@ -122,14 +106,14 @@ class Util {
static async formatVideoToWebpSticker(media) { static async formatVideoToWebpSticker(media) {
if (!media.mimetype.includes(&#x27;video&#x27;)) if (!media.mimetype.includes(&#x27;video&#x27;))
throw new Error(&#x27;media is not a video&#x27;); throw new Error(&#x27;media is not a video&#x27;);
const videoType &#x3D; media.mimetype.split(&#x27;/&#x27;)[1]; const videoType &#x3D; media.mimetype.split(&#x27;/&#x27;)[1];
const tempFile &#x3D; path.join( const tempFile &#x3D; path.join(
tmpdir(), tmpdir(),
&#x60;${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp&#x60; &#x60;${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp&#x60;
); );
const stream &#x3D; new (require(&#x27;stream&#x27;).Readable)(); const stream &#x3D; new (require(&#x27;stream&#x27;).Readable)();
const buffer &#x3D; Buffer.from( const buffer &#x3D; Buffer.from(
media.data.replace(&#x60;data:${media.mimetype};base64,&#x60;, &#x27;&#x27;), media.data.replace(&#x60;data:${media.mimetype};base64,&#x60;, &#x27;&#x27;),
@@ -166,17 +150,17 @@ class Util {
.toFormat(&#x27;webp&#x27;) .toFormat(&#x27;webp&#x27;)
.save(tempFile); .save(tempFile);
}); });
const data &#x3D; await fs.readFile(tempFile, &#x27;base64&#x27;); const data &#x3D; await fs.readFile(tempFile, &#x27;base64&#x27;);
await fs.unlink(tempFile); await fs.unlink(tempFile);
return { return {
mimetype: &#x27;image/webp&#x27;, mimetype: &#x27;image/webp&#x27;,
data: data, data: data,
filename: media.filename, filename: media.filename,
}; };
} }
/** /**
* Sticker metadata. * Sticker metadata.
* @typedef {Object} StickerMetadata * @typedef {Object} StickerMetadata
@@ -192,14 +176,14 @@ class Util {
* *
* @returns {Promise&amp;lt;MessageMedia&gt;} media in webp format * @returns {Promise&amp;lt;MessageMedia&gt;} media in webp format
*/ */
static async formatToWebpSticker(media, metadata) { static async formatToWebpSticker(media, metadata, pupPage) {
let webpMedia; let webpMedia;
if (media.mimetype.includes(&#x27;image&#x27;)) if (media.mimetype.includes(&#x27;image&#x27;))
webpMedia &#x3D; await this.formatImageToWebpSticker(media); webpMedia &#x3D; await this.formatImageToWebpSticker(media, pupPage);
else if (media.mimetype.includes(&#x27;video&#x27;)) else if (media.mimetype.includes(&#x27;video&#x27;))
webpMedia &#x3D; await this.formatVideoToWebpSticker(media); webpMedia &#x3D; await this.formatVideoToWebpSticker(media);
else else
throw new Error(&#x27;Invalid media format&#x27;); throw new Error(&#x27;Invalid media format&#x27;);
if (metadata.name || metadata.author) { if (metadata.name || metadata.author) {
@@ -242,7 +226,7 @@ module.exports &#x3D; Util;
<footer id="jsdoc-footer" class="jsdoc-footer"> <footer id="jsdoc-footer" class="jsdoc-footer">
<div id="jsdoc-footer-container"> <div id="jsdoc-footer-container">
<p> <p>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on February 8, 2022. Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.7 on June 9, 2022.
</p> </p>
</div> </div>
</footer> </footer>

View File

@@ -1,22 +1,9 @@
const fs = require('fs'); const { Client, Location, List, Buttons, LocalAuth } = require('./index');
const { Client, Location, List, Buttons } = require('./index');
const SESSION_FILE_PATH = './session.json'; const client = new Client({
let sessionCfg; authStrategy: new LocalAuth(),
if (fs.existsSync(SESSION_FILE_PATH)) { puppeteer: { headless: false }
sessionCfg = require(SESSION_FILE_PATH); });
}
const client = new Client({ puppeteer: { headless: false }, session: sessionCfg });
// You can use an existing session and avoid scanning a QR code by adding a "session" object to the client options.
// This object must include WABrowserId, WASecretBundle, WAToken1 and WAToken2.
// You also could connect to an existing instance of a browser
// {
// puppeteer: {
// browserWSEndpoint: `ws://localhost:3000`
// }
// }
client.initialize(); client.initialize();
@@ -25,18 +12,12 @@ client.on('qr', (qr) => {
console.log('QR RECEIVED', qr); console.log('QR RECEIVED', qr);
}); });
client.on('authenticated', (session) => { client.on('authenticated', () => {
console.log('AUTHENTICATED', session); console.log('AUTHENTICATED');
sessionCfg=session;
fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), function (err) {
if (err) {
console.error(err);
}
});
}); });
client.on('auth_failure', msg => { client.on('auth_failure', msg => {
// Fired if session restore was unsuccessfull // Fired if session restore was unsuccessful
console.error('AUTHENTICATION FAILURE', msg); console.error('AUTHENTICATION FAILURE', msg);
}); });
@@ -124,9 +105,8 @@ client.on('message', async msg => {
client.sendMessage(msg.from, ` client.sendMessage(msg.from, `
*Connection info* *Connection info*
User name: ${info.pushname} User name: ${info.pushname}
My number: ${info.me.user} My number: ${info.wid.user}
Platform: ${info.platform} Platform: ${info.platform}
WhatsApp version: ${info.phone.wa_version}
`); `);
} else if (msg.body === '!mediainfo' && msg.hasMedia) { } else if (msg.body === '!mediainfo' && msg.hasMedia) {
const attachmentData = await msg.downloadMedia(); const attachmentData = await msg.downloadMedia();
@@ -267,12 +247,6 @@ client.on('group_update', (notification) => {
console.log('update', notification); console.log('update', notification);
}); });
client.on('change_battery', (batteryInfo) => {
// Battery percentage for attached device has changed
const { battery, plugged } = batteryInfo;
console.log(`Battery: ${battery}% - Charging? ${plugged}`);
});
client.on('change_state', state => { client.on('change_state', state => {
console.log('CHANGE STATE', state ); console.log('CHANGE STATE', state );
}); });

135
index.d.ts vendored
View File

@@ -84,6 +84,9 @@ declare namespace WAWebJS {
/** Returns the contact ID's profile picture URL, if privacy settings allow it */ /** Returns the contact ID's profile picture URL, if privacy settings allow it */
getProfilePicUrl(contactId: string): Promise<string> getProfilePicUrl(contactId: string): Promise<string>
/** Gets the Contact's common groups with you. Returns empty array if you don't have any common group. */
getCommonGroups(contactId: string): Promise<ChatId[]>
/** Gets the current connection state for the client */ /** Gets the current connection state for the client */
getState(): Promise<WAState> getState(): Promise<WAState>
@@ -118,6 +121,9 @@ declare namespace WAWebJS {
/** Marks the client as online */ /** Marks the client as online */
sendPresenceAvailable(): Promise<void> sendPresenceAvailable(): Promise<void>
/** Marks the client as offline */
sendPresenceUnavailable(): Promise<void>
/** Mark as seen for the Chat */ /** Mark as seen for the Chat */
sendSeen(chatId: string): Promise<boolean> sendSeen(chatId: string): Promise<boolean>
@@ -134,7 +140,7 @@ declare namespace WAWebJS {
* Sets the current user's display name * Sets the current user's display name
* @param displayName New display name * @param displayName New display name
*/ */
setDisplayName(displayName: string): Promise<void> setDisplayName(displayName: string): Promise<boolean>
/** Changes and returns the archive state of the Chat */ /** Changes and returns the archive state of the Chat */
unarchiveChat(chatId: string): Promise<boolean> unarchiveChat(chatId: string): Promise<boolean>
@@ -150,11 +156,16 @@ declare namespace WAWebJS {
/** Emitted when authentication is successful */ /** Emitted when authentication is successful */
on(event: 'authenticated', listener: ( on(event: 'authenticated', listener: (
/** Object containing session information. Can be used to restore the session */ /**
session: ClientSession * Object containing session information, when using LegacySessionAuth. Can be used to restore the session
*/
session?: ClientSession
) => void): this ) => void): this
/** Emitted when the battery percentage for the attached device changes */ /**
* Emitted when the battery percentage for the attached device changes
* @deprecated
*/
on(event: 'change_battery', listener: (batteryInfo: BatteryInfo) => void): this on(event: 'change_battery', listener: (batteryInfo: BatteryInfo) => void): this
/** Emitted when the connection state changes */ /** Emitted when the connection state changes */
@@ -256,7 +267,10 @@ declare namespace WAWebJS {
me: ContactId me: ContactId
/** Current user ID */ /** Current user ID */
wid: ContactId wid: ContactId
/** Information about the phone this client is connected to */ /**
* Information about the phone this client is connected to. Not available in multi-device.
* @deprecated
*/
phone: ClientInfoPhone phone: ClientInfoPhone
/** Platform the phone is running on */ /** Platform the phone is running on */
platform: string platform: string
@@ -267,7 +281,10 @@ declare namespace WAWebJS {
getBatteryStatus: () => Promise<BatteryInfo> getBatteryStatus: () => Promise<BatteryInfo>
} }
/** Information about the phone this client is connected to */ /**
* Information about the phone this client is connected to
* @deprecated
*/
export interface ClientInfoPhone { export interface ClientInfoPhone {
/** WhatsApp Version running on the phone */ /** WhatsApp Version running on the phone */
wa_version: string wa_version: string
@@ -284,23 +301,22 @@ declare namespace WAWebJS {
/** Options for initializing the whatsapp client */ /** Options for initializing the whatsapp client */
export interface ClientOptions { export interface ClientOptions {
/** Timeout for authentication selector in puppeteer /** Timeout for authentication selector in puppeteer
* @default 45000 */ * @default 0 */
authTimeoutMs?: number, authTimeoutMs?: number,
/** Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/ */ /** Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/ */
puppeteer?: puppeteer.LaunchOptions & puppeteer.BrowserLaunchArgumentOptions & puppeteer.BrowserConnectOptions puppeteer?: puppeteer.PuppeteerNodeLaunchOptions & puppeteer.ConnectOptions
/** Refresh interval for qr code (how much time to wait before checking if the qr code has changed) /** Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used. */
* @default 20000 */ authStrategy?: AuthStrategy,
qrRefreshIntervalMs?: number /** How many times should the qrcode be refreshed before giving up
/** Timeout for qr code selector in puppeteer
* @default 45000 */
qrTimeoutMs?: number,
/** How many times should the qrcode be refreshed before giving up
* @default 0 (disabled) */ * @default 0 (disabled) */
qrMaxRetries?: number, qrMaxRetries?: number,
/** Restart client with a new session (i.e. use null 'session' var) if authentication fails /**
* @default false */ * @deprecated This option should be set directly on the LegacySessionAuth
*/
restartOnAuthFail?: boolean restartOnAuthFail?: boolean
/** Whatsapp session to restore. If not set, will start a new session */ /**
* @deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.
*/
session?: ClientSession session?: ClientSession
/** If another whatsapp web session is detected (another browser), take over the session in the current browser /** If another whatsapp web session is detected (another browser), take over the session in the current browser
* @default false */ * @default false */
@@ -316,7 +332,54 @@ declare namespace WAWebJS {
ffmpegPath?: string ffmpegPath?: string
} }
/** Represents a Whatsapp client session */ /**
* Base class which all authentication strategies extend
*/
export abstract class AuthStrategy {
setup: (client: Client) => void;
beforeBrowserInitialized: () => Promise<void>;
afterBrowserInitialized: () => Promise<void>;
onAuthenticationNeeded: () => Promise<{
failed?: boolean;
restart?: boolean;
failureEventPayload?: any
}>;
getAuthEventPayload: () => Promise<any>;
logout: () => Promise<void>;
}
/**
* No session restoring functionality
* Will need to authenticate via QR code every time
*/
export class NoAuth extends AuthStrategy {}
/**
* Local directory-based authentication
*/
export class LocalAuth extends AuthStrategy {
public clientId?: string;
public dataPath?: string;
constructor(options?: {
clientId?: string,
dataPath?: string
})
}
/**
* Legacy session auth strategy
* Not compatible with multi-device accounts.
*/
export class LegacySessionAuth extends AuthStrategy {
constructor(options?: {
session?: ClientSession,
restartOnAuthFail?: boolean,
})
}
/**
* Represents a WhatsApp client session
*/
export interface ClientSession { export interface ClientSession {
WABrowserId: string, WABrowserId: string,
WASecretBundle: string, WASecretBundle: string,
@@ -324,6 +387,9 @@ declare namespace WAWebJS {
WAToken2: string, WAToken2: string,
} }
/**
* @deprecated
*/
export interface BatteryInfo { export interface BatteryInfo {
/** The current battery percentage */ /** The current battery percentage */
battery: number, battery: number,
@@ -446,7 +512,6 @@ declare namespace WAWebJS {
LIST = 'list', LIST = 'list',
LIST_RESPONSE = 'list_response', LIST_RESPONSE = 'list_response',
BUTTONS_RESPONSE = 'buttons_response', BUTTONS_RESPONSE = 'buttons_response',
PAYMENT = 'payment',
BROADCAST_NOTIFICATION = 'broadcast_notification', BROADCAST_NOTIFICATION = 'broadcast_notification',
CALL_LOG = 'call_log', CALL_LOG = 'call_log',
CIPHERTEXT = 'ciphertext', CIPHERTEXT = 'ciphertext',
@@ -557,6 +622,8 @@ declare namespace WAWebJS {
hasMedia: boolean, hasMedia: boolean,
/** Indicates if the message was sent as a reply to another message */ /** Indicates if the message was sent as a reply to another message */
hasQuotedMsg: boolean, hasQuotedMsg: boolean,
/** Indicates the duration of the message in seconds */
duration: string,
/** ID that represents the message */ /** ID that represents the message */
id: MessageId, id: MessageId,
/** Indicates if the message was forwarded */ /** Indicates if the message was forwarded */
@@ -609,6 +676,13 @@ declare namespace WAWebJS {
selectedButtonId?: string, selectedButtonId?: string,
/** Selected list row ID */ /** Selected list row ID */
selectedRowId?: string, selectedRowId?: string,
/** Returns message in a raw format */
rawData: object,
/*
* Reloads this Message object's data in-place with the latest values from WhatsApp Web.
* Note that the Message must still be in the web app cache for this to work, otherwise will return null.
*/
reload: () => Promise<Message>,
/** Accept the Group V4 Invite in message */ /** Accept the Group V4 Invite in message */
acceptGroupV4Invite: () => Promise<{status: number}>, acceptGroupV4Invite: () => Promise<{status: number}>,
/** Deletes the message from the chat */ /** Deletes the message from the chat */
@@ -642,11 +716,11 @@ declare namespace WAWebJS {
/** /**
* Gets the order associated with a given message * Gets the order associated with a given message
*/ */
getOrder: () => Order, getOrder: () => Promise<Order>,
/** /**
* Gets the payment details associated with a given message * Gets the payment details associated with a given message
*/ */
getPayment: () => Payment, getPayment: () => Promise<Payment>,
} }
/** ID that represents a message */ /** ID that represents a message */
@@ -680,7 +754,7 @@ declare namespace WAWebJS {
/** Options for sending a message */ /** Options for sending a message */
export interface MessageSendOptions { export interface MessageSendOptions {
/** Show links preview */ /** Show links preview. Has no effect on multi-device accounts. */
linkPreview?: boolean linkPreview?: boolean
/** Send audio as voice message */ /** Send audio as voice message */
sendAudioAsVoice?: boolean sendAudioAsVoice?: boolean
@@ -742,7 +816,7 @@ declare namespace WAWebJS {
static fromUrl: (url: string, options?: MediaFromURLOptions) => Promise<MessageMedia> static fromUrl: (url: string, options?: MediaFromURLOptions) => Promise<MessageMedia>
} }
export type MessageContent = string | MessageMedia | Location | Contact | Contact[] | List | Buttons export type MessageContent = string | MessageMedia | Location | Contact | Contact[] | List | Buttons
/** /**
* Represents a Contact on WhatsApp * Represents a Contact on WhatsApp
@@ -835,6 +909,9 @@ declare namespace WAWebJS {
/** Gets the Contact's current "about" info. Returns null if you don't have permission to read their status. */ /** Gets the Contact's current "about" info. Returns null if you don't have permission to read their status. */
getAbout: () => Promise<string | null>, getAbout: () => Promise<string | null>,
/** Gets the Contact's common groups with you. Returns empty array if you don't have any common group. */
getCommonGroups: () => Promise<ChatId[]>
} }
@@ -978,7 +1055,7 @@ declare namespace WAWebJS {
} }
/** Promotes or demotes participants by IDs to regular users or admins */ /** Promotes or demotes participants by IDs to regular users or admins */
export type ChangeParticipantsPermisions = export type ChangeParticipantsPermissions =
(participantIds: Array<string>) => Promise<{ status: number }> (participantIds: Array<string>) => Promise<{ status: number }>
/** Adds or removes a list of participants by ID to the group */ /** Adds or removes a list of participants by ID to the group */
@@ -1008,13 +1085,13 @@ declare namespace WAWebJS {
/** Removes a list of participants by ID to the group */ /** Removes a list of participants by ID to the group */
removeParticipants: ChangeGroupParticipants; removeParticipants: ChangeGroupParticipants;
/** Promotes participants by IDs to admins */ /** Promotes participants by IDs to admins */
promoteParticipants: ChangeParticipantsPermisions; promoteParticipants: ChangeParticipantsPermissions;
/** Demotes participants by IDs to regular users */ /** Demotes participants by IDs to regular users */
demoteParticipants: ChangeParticipantsPermisions; demoteParticipants: ChangeParticipantsPermissions;
/** Updates the group subject */ /** Updates the group subject */
setSubject: (subject: string) => Promise<void>; setSubject: (subject: string) => Promise<boolean>;
/** Updates the group description */ /** Updates the group description */
setDescription: (description: string) => Promise<void>; setDescription: (description: string) => Promise<boolean>;
/** Updates the group settings to only allow admins to send messages /** Updates the group settings to only allow admins to send messages
* @param {boolean} [adminsOnly=true] Enable or disable this option * @param {boolean} [adminsOnly=true] Enable or disable this option
* @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions. * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.

View File

@@ -21,5 +21,11 @@ module.exports = {
ProductMetadata: require('./src/structures/ProductMetadata'), ProductMetadata: require('./src/structures/ProductMetadata'),
List: require('./src/structures/List'), List: require('./src/structures/List'),
Buttons: require('./src/structures/Buttons'), Buttons: require('./src/structures/Buttons'),
// Auth Strategies
NoAuth: require('./src/authStrategies/NoAuth'),
LocalAuth: require('./src/authStrategies/LocalAuth'),
LegacySessionAuth: require('./src/authStrategies/LegacySessionAuth'),
...Constants ...Constants
}; };

View File

@@ -1,11 +1,11 @@
{ {
"name": "whatsapp-web.js", "name": "whatsapp-web.js",
"version": "1.15.6", "version": "1.16.7",
"description": "Library for interacting with the WhatsApp Web API ", "description": "Library for interacting with the WhatsApp Web API ",
"main": "./index.js", "main": "./index.js",
"typings": "./index.d.ts", "typings": "./index.d.ts",
"scripts": { "scripts": {
"test": "mocha tests --recursive", "test": "mocha tests --recursive --timeout 5000",
"test-single": "mocha", "test-single": "mocha",
"shell": "node --experimental-repl-await ./shell.js", "shell": "node --experimental-repl-await ./shell.js",
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose" "generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose"
@@ -35,12 +35,12 @@
"mime": "^3.0.0", "mime": "^3.0.0",
"node-fetch": "^2.6.5", "node-fetch": "^2.6.5",
"node-webpmux": "^3.1.0", "node-webpmux": "^3.1.0",
"puppeteer": "^13.0.0", "puppeteer": "^13.0.0"
"sharp": "^0.28.3"
}, },
"devDependencies": { "devDependencies": {
"@types/node-fetch": "^2.5.12", "@types/node-fetch": "^2.5.12",
"chai": "^4.3.4", "chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"dotenv": "^16.0.0", "dotenv": "^16.0.0",
"eslint": "^8.4.1", "eslint": "^8.4.1",
"eslint-plugin-mocha": "^10.0.3", "eslint-plugin-mocha": "^10.0.3",

View File

@@ -2,24 +2,17 @@
* ==== wwebjs-shell ==== * ==== wwebjs-shell ====
* Used for quickly testing library features * Used for quickly testing library features
* *
* Running `npm run shell` will start WhatsApp Web in headless mode * Running `npm run shell` will start WhatsApp Web with headless=false
* and then drop you into Node REPL with `client` in its context. * and then drop you into Node REPL with `client` in its context.
*/ */
const repl = require('repl'); const repl = require('repl');
const fs = require('fs');
const { Client } = require('./index'); const { Client, LocalAuth } = require('./index');
const SESSION_FILE_PATH = './session.json';
let sessionCfg;
if (fs.existsSync(SESSION_FILE_PATH)) {
sessionCfg = require(SESSION_FILE_PATH);
}
const client = new Client({ const client = new Client({
puppeteer: { headless: false }, puppeteer: { headless: false },
session: sessionCfg authStrategy: new LocalAuth()
}); });
console.log('Initializing...'); console.log('Initializing...');
@@ -30,6 +23,10 @@ client.on('qr', () => {
console.log('Please scan the QR code on the browser.'); console.log('Please scan the QR code on the browser.');
}); });
client.on('authenticated', (session) => {
console.log(JSON.stringify(session));
});
client.on('ready', () => { client.on('ready', () => {
const shell = repl.start('wwebjs> '); const shell = repl.start('wwebjs> ');
shell.context.client = client; shell.context.client = client;

View File

@@ -3,7 +3,6 @@
const EventEmitter = require('events'); const EventEmitter = require('events');
const puppeteer = require('puppeteer'); const puppeteer = require('puppeteer');
const moduleRaid = require('@pedroslopez/moduleraid/moduleraid'); const moduleRaid = require('@pedroslopez/moduleraid/moduleraid');
const jsQR = require('jsqr');
const Util = require('./util/Util'); const Util = require('./util/Util');
const InterfaceController = require('./util/InterfaceController'); const InterfaceController = require('./util/InterfaceController');
@@ -11,22 +10,20 @@ const { WhatsWebURL, DefaultOptions, Events, WAState } = require('./util/Constan
const { ExposeStore, LoadUtils } = require('./util/Injected'); const { ExposeStore, LoadUtils } = require('./util/Injected');
const ChatFactory = require('./factories/ChatFactory'); const ChatFactory = require('./factories/ChatFactory');
const ContactFactory = require('./factories/ContactFactory'); const ContactFactory = require('./factories/ContactFactory');
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification , Label, Call, Buttons, List} = require('./structures'); const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List } = require('./structures');
const LegacySessionAuth = require('./authStrategies/LegacySessionAuth');
const NoAuth = require('./authStrategies/NoAuth');
/** /**
* Starting point for interacting with the WhatsApp Web API * Starting point for interacting with the WhatsApp Web API
* @extends {EventEmitter} * @extends {EventEmitter}
* @param {object} options - Client options * @param {object} options - Client options
* @param {AuthStrategy} options.authStrategy - Determines how to save and restore sessions. Will use LegacySessionAuth if options.session is set. Otherwise, NoAuth will be used.
* @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer * @param {number} options.authTimeoutMs - Timeout for authentication selector in puppeteer
* @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/ * @param {object} options.puppeteer - Puppeteer launch options. View docs here: https://github.com/puppeteer/puppeteer/
* @param {number} options.qrRefreshIntervalMs - Refresh interval for qr code (how much time to wait before checking if the qr code has changed)
* @param {number} options.qrTimeoutMs - Timeout for qr code selector in puppeteer
* @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up * @param {number} options.qrMaxRetries - How many times should the qrcode be refreshed before giving up
* @param {string} options.restartOnAuthFail - Restart client with a new session (i.e. use null 'session' var) if authentication fails * @param {string} options.restartOnAuthFail - @deprecated This option should be set directly on the LegacySessionAuth.
* @param {object} options.session - Whatsapp session to restore. If not set, will start a new session * @param {object} options.session - @deprecated Only here for backwards-compatibility. You should move to using LocalAuth, or set the authStrategy to LegacySessionAuth explicitly.
* @param {string} options.session.WABrowserId
* @param {string} options.session.WASecretBundle
* @param {string} options.session.WAToken1
* @param {string} options.session.WAToken2
* @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser * @param {number} options.takeoverOnConflict - If another whatsapp web session is detected (another browser), take over the session in the current browser
* @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session * @param {number} options.takeoverTimeoutMs - How much time to wait before taking over the session
* @param {string} options.userAgent - User agent to use in puppeteer * @param {string} options.userAgent - User agent to use in puppeteer
@@ -48,13 +45,33 @@ const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification
* @fires Client#group_update * @fires Client#group_update
* @fires Client#disconnected * @fires Client#disconnected
* @fires Client#change_state * @fires Client#change_state
* @fires Client#change_battery
*/ */
class Client extends EventEmitter { class Client extends EventEmitter {
constructor(options = {}) { constructor(options = {}) {
super(); super();
this.options = Util.mergeDefault(DefaultOptions, options); this.options = Util.mergeDefault(DefaultOptions, options);
if(!this.options.authStrategy) {
if(Object.prototype.hasOwnProperty.call(this.options, 'session')) {
process.emitWarning(
'options.session is deprecated and will be removed in a future release due to incompatibility with multi-device. ' +
'Use the LocalAuth authStrategy, don\'t pass in a session as an option, or suppress this warning by using the LegacySessionAuth strategy explicitly (see https://wwebjs.dev/guide/authentication.html#legacysessionauth-strategy).',
'DeprecationWarning'
);
this.authStrategy = new LegacySessionAuth({
session: this.options.session,
restartOnAuthFail: this.options.restartOnAuthFail
});
} else {
this.authStrategy = new NoAuth();
}
} else {
this.authStrategy = this.options.authStrategy;
}
this.authStrategy.setup(this);
this.pupBrowser = null; this.pupBrowser = null;
this.pupPage = null; this.pupPage = null;
@@ -67,41 +84,25 @@ class Client extends EventEmitter {
*/ */
async initialize() { async initialize() {
let [browser, page] = [null, null]; let [browser, page] = [null, null];
if(this.options.puppeteer && this.options.puppeteer.browserWSEndpoint) { await this.authStrategy.beforeBrowserInitialized();
browser = await puppeteer.connect(this.options.puppeteer);
const puppeteerOpts = this.options.puppeteer;
if (puppeteerOpts && puppeteerOpts.browserWSEndpoint) {
browser = await puppeteer.connect(puppeteerOpts);
page = await browser.newPage(); page = await browser.newPage();
} else { } else {
browser = await puppeteer.launch(this.options.puppeteer); browser = await puppeteer.launch(puppeteerOpts);
page = (await browser.pages())[0]; page = (await browser.pages())[0];
} }
await page.setUserAgent(this.options.userAgent); await page.setUserAgent(this.options.userAgent);
if (this.options.bypassCSP) await page.setBypassCSP(true);
this.pupBrowser = browser; this.pupBrowser = browser;
this.pupPage = page; this.pupPage = page;
// remember me await this.authStrategy.afterBrowserInitialized();
await page.evaluateOnNewDocument(() => {
localStorage.setItem('remember-me', 'true');
});
if (this.options.session) {
await page.evaluateOnNewDocument(
session => {
if(document.referrer === 'https://whatsapp.com/') {
localStorage.clear();
localStorage.setItem('WABrowserId', session.WABrowserId);
localStorage.setItem('WASecretBundle', session.WASecretBundle);
localStorage.setItem('WAToken1', session.WAToken1);
localStorage.setItem('WAToken2', session.WAToken2);
}
}, this.options.session);
}
if(this.options.bypassCSP) {
await page.setBypassCSP(true);
}
await page.goto(WhatsWebURL, { await page.goto(WhatsWebURL, {
waitUntil: 'load', waitUntil: 'load',
@@ -109,56 +110,54 @@ class Client extends EventEmitter {
referer: 'https://whatsapp.com/' referer: 'https://whatsapp.com/'
}); });
const KEEP_PHONE_CONNECTED_IMG_SELECTOR = '[data-icon="intro-md-beta-logo-dark"], [data-icon="intro-md-beta-logo-light"], [data-asset-intro-image-light="true"], [data-asset-intro-image-dark="true"]'; const INTRO_IMG_SELECTOR = '[data-testid="intro-md-beta-logo-dark"], [data-testid="intro-md-beta-logo-light"], [data-asset-intro-image-light="true"], [data-asset-intro-image-dark="true"]';
const INTRO_QRCODE_SELECTOR = 'div[data-ref] canvas';
if (this.options.session) { // Checks which selector appears first
// Check if session restore was successful const needAuthentication = await Promise.race([
try { new Promise(resolve => {
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: this.options.authTimeoutMs }); page.waitForSelector(INTRO_IMG_SELECTOR, { timeout: this.options.authTimeoutMs })
} catch (err) { .then(() => resolve(false))
if (err.name === 'TimeoutError') { .catch((err) => resolve(err));
/** }),
* Emitted when there has been an error while trying to restore an existing session new Promise(resolve => {
* @event Client#auth_failure page.waitForSelector(INTRO_QRCODE_SELECTOR, { timeout: this.options.authTimeoutMs })
* @param {string} message .then(() => resolve(true))
*/ .catch((err) => resolve(err));
this.emit(Events.AUTHENTICATION_FAILURE, 'Unable to log in. Are the session details valid?'); })
browser.close(); ]);
if (this.options.restartOnAuthFail) {
// session restore failed so try again but without session to force new authentication // Checks if an error ocurred on the first found selector. The second will be discarded and ignored by .race;
this.options.session = null; if (needAuthentication instanceof Error) throw needAuthentication;
this.initialize();
} // Scan-qrcode selector was found. Needs authentication
return; if (needAuthentication) {
const { failed, failureEventPayload, restart } = await this.authStrategy.onAuthenticationNeeded();
if(failed) {
/**
* Emitted when there has been an error while trying to restore an existing session
* @event Client#auth_failure
* @param {string} message
*/
this.emit(Events.AUTHENTICATION_FAILURE, failureEventPayload);
await this.destroy();
if (restart) {
// session restore failed so try again but without session to force new authentication
return this.initialize();
} }
return;
throw err;
} }
} else { const QR_CONTAINER = 'div[data-ref]';
const QR_RETRY_BUTTON = 'div[data-ref] > span > button';
let qrRetries = 0; let qrRetries = 0;
await page.exposeFunction('qrChanged', async (qr) => {
const getQrCode = async () => {
// Check if retry button is present
var QR_RETRY_SELECTOR = 'div[data-ref] > span > button';
var qrRetry = await page.$(QR_RETRY_SELECTOR);
if (qrRetry) {
await qrRetry.click();
}
// Wait for QR Code
const QR_CANVAS_SELECTOR = 'canvas';
await page.waitForSelector(QR_CANVAS_SELECTOR, { timeout: this.options.qrTimeoutMs });
const qrImgData = await page.$eval(QR_CANVAS_SELECTOR, canvas => [].slice.call(canvas.getContext('2d').getImageData(0, 0, 264, 264).data));
const qr = jsQR(qrImgData, 264, 264).data;
/** /**
* Emitted when the QR code is received * Emitted when a QR code is received
* @event Client#qr * @event Client#qr
* @param {string} qr QR Code * @param {string} qr QR Code
*/ */
this.emit(Events.QR_RECEIVED, qr); this.emit(Events.QR_RECEIVED, qr);
if (this.options.qrMaxRetries > 0) { if (this.options.qrMaxRetries > 0) {
qrRetries++; qrRetries++;
if (qrRetries > this.options.qrMaxRetries) { if (qrRetries > this.options.qrMaxRetries) {
@@ -166,15 +165,39 @@ class Client extends EventEmitter {
await this.destroy(); await this.destroy();
} }
} }
}; });
getQrCode();
this._qrRefreshInterval = setInterval(getQrCode, this.options.qrRefreshIntervalMs); await page.evaluate(function (selectors) {
const qr_container = document.querySelector(selectors.QR_CONTAINER);
window.qrChanged(qr_container.dataset.ref);
const obs = new MutationObserver((muts) => {
muts.forEach(mut => {
// Listens to qr token change
if (mut.type === 'attributes' && mut.attributeName === 'data-ref') {
window.qrChanged(mut.target.dataset.ref);
} else
// Listens to retry button, when found, click it
if (mut.type === 'childList') {
const retry_button = document.querySelector(selectors.QR_RETRY_BUTTON);
if (retry_button) retry_button.click();
}
});
});
obs.observe(qr_container.parentElement, {
subtree: true,
childList: true,
attributes: true,
attributeFilter: ['data-ref'],
});
}, {
QR_CONTAINER,
QR_RETRY_BUTTON
});
// Wait for code scan // Wait for code scan
try { try {
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: 0 }); await page.waitForSelector(INTRO_IMG_SELECTOR, { timeout: 0 });
clearInterval(this._qrRefreshInterval);
this._qrRefreshInterval = undefined;
} catch(error) { } catch(error) {
if ( if (
error.name === 'ProtocolError' && error.name === 'ProtocolError' &&
@@ -187,44 +210,29 @@ class Client extends EventEmitter {
throw error; throw error;
} }
} }
await page.evaluate(ExposeStore, moduleRaid.toString()); await page.evaluate(ExposeStore, moduleRaid.toString());
const authEventPayload = await this.authStrategy.getAuthEventPayload();
// Get session tokens
const localStorage = JSON.parse(await page.evaluate(() => {
return JSON.stringify(window.localStorage);
}));
const session = {
WABrowserId: localStorage.WABrowserId,
WASecretBundle: localStorage.WASecretBundle,
WAToken1: localStorage.WAToken1,
WAToken2: localStorage.WAToken2
};
/** /**
* Emitted when authentication is successful * Emitted when authentication is successful
* @event Client#authenticated * @event Client#authenticated
* @param {object} session Object containing session information. Can be used to restore the session.
* @param {string} session.WABrowserId
* @param {string} session.WASecretBundle
* @param {string} session.WAToken1
* @param {string} session.WAToken2
*/ */
this.emit(Events.AUTHENTICATED, session); this.emit(Events.AUTHENTICATED, authEventPayload);
// Check window.Store Injection // Check window.Store Injection
await page.waitForFunction('window.Store != undefined'); await page.waitForFunction('window.Store != undefined');
const isMD = await page.evaluate(() => { await page.evaluate(async () => {
return window.Store.Features.features.MD_BACKEND; // safely unregister service workers
const registrations = await navigator.serviceWorker.getRegistrations();
for (let registration of registrations) {
registration.unregister();
}
}); });
if(isMD) {
throw new Error('Multi-device is not yet supported by whatsapp-web.js. Please check out https://github.com/pedroslopez/whatsapp-web.js/pull/889 to follow the progress.');
}
//Load util functions (serializers, helper functions) //Load util functions (serializers, helper functions)
await page.evaluate(LoadUtils); await page.evaluate(LoadUtils);
@@ -234,7 +242,7 @@ class Client extends EventEmitter {
* @type {ClientInfo} * @type {ClientInfo}
*/ */
this.info = new ClientInfo(this, await page.evaluate(() => { this.info = new ClientInfo(this, await page.evaluate(() => {
return window.Store.Conn.serialize(); return { ...window.Store.Conn.serialize(), wid: window.Store.User.getMeUser() };
})); }));
// Add InterfaceController // Add InterfaceController
@@ -398,11 +406,12 @@ class Client extends EventEmitter {
if (battery === undefined) return; if (battery === undefined) return;
/** /**
* Emitted when the battery percentage for the attached device changes * Emitted when the battery percentage for the attached device changes. Will not be sent if using multi-device.
* @event Client#change_battery * @event Client#change_battery
* @param {object} batteryInfo * @param {object} batteryInfo
* @param {number} batteryInfo.battery - The current battery percentage * @param {number} batteryInfo.battery - The current battery percentage
* @param {boolean} batteryInfo.plugged - Indicates if the phone is plugged in (true) or not (false) * @param {boolean} batteryInfo.plugged - Indicates if the phone is plugged in (true) or not (false)
* @deprecated
*/ */
this.emit(Events.BATTERY_CHANGED, { battery, plugged }); this.emit(Events.BATTERY_CHANGED, { battery, plugged });
}); });
@@ -421,14 +430,14 @@ class Client extends EventEmitter {
* @param {boolean} call.webClientShouldHandle - If Waweb should handle * @param {boolean} call.webClientShouldHandle - If Waweb should handle
* @param {object} call.participants - Participants * @param {object} call.participants - Participants
*/ */
const cll = new Call(this,call); const cll = new Call(this, call);
this.emit(Events.INCOMING_CALL, cll); this.emit(Events.INCOMING_CALL, cll);
}); });
await page.evaluate(() => { await page.evaluate(() => {
window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.Msg.on('change:type', (msg) => { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on('change:type', (msg) => { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.Msg.on('change:ack', (msg,ack) => { window.onMessageAckEvent(window.WWebJS.getMessageModel(msg), ack); }); window.Store.Msg.on('change:ack', (msg, ack) => { window.onMessageAckEvent(window.WWebJS.getMessageModel(msg), ack); });
window.Store.Msg.on('change:isUnsentMedia', (msg, unsent) => { if (msg.id.fromMe && !unsent) window.onMessageMediaUploadedEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on('change:isUnsentMedia', (msg, unsent) => { if (msg.id.fromMe && !unsent) window.onMessageMediaUploadedEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.Msg.on('remove', (msg) => { if (msg.isNewMsg) window.onRemoveMessageEvent(window.WWebJS.getMessageModel(msg)); }); window.Store.Msg.on('remove', (msg) => { if (msg.isNewMsg) window.onRemoveMessageEvent(window.WWebJS.getMessageModel(msg)); });
window.Store.AppState.on('change:state', (_AppState, state) => { window.onAppStateChangedEvent(state); }); window.Store.AppState.on('change:state', (_AppState, state) => { window.onAppStateChangedEvent(state); });
@@ -466,9 +475,6 @@ class Client extends EventEmitter {
* Closes the client * Closes the client
*/ */
async destroy() { async destroy() {
if (this._qrRefreshInterval) {
clearInterval(this._qrRefreshInterval);
}
await this.pupBrowser.close(); await this.pupBrowser.close();
} }
@@ -476,9 +482,11 @@ class Client extends EventEmitter {
* Logs out the client, closing the current session * Logs out the client, closing the current session
*/ */
async logout() { async logout() {
return await this.pupPage.evaluate(() => { await this.pupPage.evaluate(() => {
return window.Store.AppState.logout(); return window.Store.AppState.logout();
}); });
await this.authStrategy.logout();
} }
/** /**
@@ -508,7 +516,7 @@ class Client extends EventEmitter {
/** /**
* Message options. * Message options.
* @typedef {Object} MessageSendOptions * @typedef {Object} MessageSendOptions
* @property {boolean} [linkPreview=true] - Show links preview * @property {boolean} [linkPreview=true] - Show links preview. Has no effect on multi-device accounts.
* @property {boolean} [sendAudioAsVoice=false] - Send audio as voice message * @property {boolean} [sendAudioAsVoice=false] - Send audio as voice message
* @property {boolean} [sendVideoAsGif=false] - Send video as gif * @property {boolean} [sendVideoAsGif=false] - Send video as gif
* @property {boolean} [sendMediaAsSticker=false] - Send media as a sticker * @property {boolean} [sendMediaAsSticker=false] - Send media as a sticker
@@ -558,34 +566,36 @@ class Client extends EventEmitter {
} else if (content instanceof Location) { } else if (content instanceof Location) {
internalOptions.location = content; internalOptions.location = content;
content = ''; content = '';
} else if(content instanceof Contact) { } else if (content instanceof Contact) {
internalOptions.contactCard = content.id._serialized; internalOptions.contactCard = content.id._serialized;
content = ''; content = '';
} else if(Array.isArray(content) && content.length > 0 && content[0] instanceof Contact) { } else if (Array.isArray(content) && content.length > 0 && content[0] instanceof Contact) {
internalOptions.contactCardList = content.map(contact => contact.id._serialized); internalOptions.contactCardList = content.map(contact => contact.id._serialized);
content = ''; content = '';
} else if(content instanceof Buttons){ } else if (content instanceof Buttons) {
if(content.type !== 'chat'){internalOptions.attachment = content.body;} if (content.type !== 'chat') { internalOptions.attachment = content.body; }
internalOptions.buttons = content; internalOptions.buttons = content;
content = ''; content = '';
} else if(content instanceof List){ } else if (content instanceof List) {
internalOptions.list = content; internalOptions.list = content;
content = ''; content = '';
} }
if (internalOptions.sendMediaAsSticker && internalOptions.attachment) { if (internalOptions.sendMediaAsSticker && internalOptions.attachment) {
internalOptions.attachment = internalOptions.attachment = await Util.formatToWebpSticker(
await Util.formatToWebpSticker(internalOptions.attachment, { internalOptions.attachment, {
name: options.stickerName, name: options.stickerName,
author: options.stickerAuthor, author: options.stickerAuthor,
categories: options.stickerCategories categories: options.stickerCategories
}); }, this.pupPage
);
} }
const newMessage = await this.pupPage.evaluate(async (chatId, message, options, sendSeen) => { const newMessage = await this.pupPage.evaluate(async (chatId, message, options, sendSeen) => {
const chatWid = window.Store.WidFactory.createWid(chatId); const chatWid = window.Store.WidFactory.createWid(chatId);
const chat = await window.Store.Chat.find(chatWid); const chat = await window.Store.Chat.find(chatWid);
if (sendSeen) { if (sendSeen) {
window.WWebJS.sendSeen(chatId); window.WWebJS.sendSeen(chatId);
} }
@@ -672,7 +682,7 @@ class Client extends EventEmitter {
*/ */
async getInviteInfo(inviteCode) { async getInviteInfo(inviteCode) {
return await this.pupPage.evaluate(inviteCode => { return await this.pupPage.evaluate(inviteCode => {
return window.Store.Wap.groupInviteInfo(inviteCode); return window.Store.InviteInfo.sendQueryGroupInvite(inviteCode);
}, inviteCode); }, inviteCode);
} }
@@ -691,25 +701,25 @@ class Client extends EventEmitter {
/** /**
* Accepts a private invitation to join a group * Accepts a private invitation to join a group
* @param {object} inviteV4 Invite V4 Info * @param {object} inviteInfo Invite V4 Info
* @returns {Promise<Object>} * @returns {Promise<Object>}
*/ */
async acceptGroupV4Invite(inviteInfo) { async acceptGroupV4Invite(inviteInfo) {
if(!inviteInfo.inviteCode) throw 'Invalid invite code, try passing the message.inviteV4 object'; if (!inviteInfo.inviteCode) throw 'Invalid invite code, try passing the message.inviteV4 object';
if (inviteInfo.inviteCodeExp == 0) throw 'Expired invite code'; if (inviteInfo.inviteCodeExp == 0) throw 'Expired invite code';
return await this.pupPage.evaluate(async inviteInfo => { return this.pupPage.evaluate(async inviteInfo => {
let { groupId, fromId, inviteCode, inviteCodeExp, toId } = inviteInfo; let { groupId, fromId, inviteCode, inviteCodeExp } = inviteInfo;
return await window.Store.Wap.acceptGroupV4Invite(groupId, fromId, inviteCode, String(inviteCodeExp), toId); return await window.Store.JoinInviteV4.sendJoinGroupViaInviteV4(inviteCode, String(inviteCodeExp), groupId, fromId);
}, inviteInfo); }, inviteInfo);
} }
/** /**
* Sets the current user's status message * Sets the current user's status message
* @param {string} status New status message * @param {string} status New status message
*/ */
async setStatus(status) { async setStatus(status) {
await this.pupPage.evaluate(async status => { await this.pupPage.evaluate(async status => {
return await window.Store.Wap.sendSetStatus(status); return await window.Store.StatusUtils.setMyStatus(status);
}, status); }, status);
} }
@@ -717,11 +727,22 @@ class Client extends EventEmitter {
* Sets the current user's display name. * Sets the current user's display name.
* This is the name shown to WhatsApp users that have not added you as a contact beside your number in groups and in your profile. * This is the name shown to WhatsApp users that have not added you as a contact beside your number in groups and in your profile.
* @param {string} displayName New display name * @param {string} displayName New display name
* @returns {Promise<Boolean>}
*/ */
async setDisplayName(displayName) { async setDisplayName(displayName) {
await this.pupPage.evaluate(async displayName => { const couldSet = await this.pupPage.evaluate(async displayName => {
return await window.Store.Wap.setPushname(displayName); if(!window.Store.Conn.canSetMyPushname()) return false;
if(window.Store.MDBackend) {
// TODO
return false;
} else {
const res = await window.Store.Wap.setPushname(displayName);
return !res.status || res.status === 200;
}
}, displayName); }, displayName);
return couldSet;
} }
/** /**
@@ -740,7 +761,16 @@ class Client extends EventEmitter {
*/ */
async sendPresenceAvailable() { async sendPresenceAvailable() {
return await this.pupPage.evaluate(() => { return await this.pupPage.evaluate(() => {
return window.Store.Wap.sendPresenceAvailable(); return window.Store.PresenceUtils.sendPresenceAvailable();
});
}
/**
* Marks the client as unavailable
*/
async sendPresenceUnavailable() {
return await this.pupPage.evaluate(() => {
return window.Store.PresenceUtils.sendPresenceUnavailable();
}); });
} }
@@ -779,8 +809,9 @@ class Client extends EventEmitter {
return true; return true;
} }
const MAX_PIN_COUNT = 3; const MAX_PIN_COUNT = 3;
if (window.Store.Chat.models.length > MAX_PIN_COUNT) { const chatModels = window.Store.Chat.getModelsArray();
let maxPinned = window.Store.Chat.models[MAX_PIN_COUNT - 1].pin; if (chatModels.length > MAX_PIN_COUNT) {
let maxPinned = chatModels[MAX_PIN_COUNT - 1].pin;
if (maxPinned) { if (maxPinned) {
return false; return false;
} }
@@ -846,13 +877,43 @@ class Client extends EventEmitter {
* @returns {Promise<string>} * @returns {Promise<string>}
*/ */
async getProfilePicUrl(contactId) { async getProfilePicUrl(contactId) {
const profilePic = await this.pupPage.evaluate((contactId) => { const profilePic = await this.pupPage.evaluate(async contactId => {
return window.Store.Wap.profilePicFind(contactId); try {
const chatWid = window.Store.WidFactory.createWid(contactId);
return await window.Store.ProfilePic.profilePicFind(chatWid);
} catch (err) {
if(err.name === 'ServerStatusCodeError') return undefined;
throw err;
}
}, contactId); }, contactId);
return profilePic ? profilePic.eurl : undefined; return profilePic ? profilePic.eurl : undefined;
} }
/**
* Gets the Contact's common groups with you. Returns empty array if you don't have any common group.
* @param {string} contactId the whatsapp user's ID (_serialized format)
* @returns {Promise<WAWebJS.ChatId[]>}
*/
async getCommonGroups(contactId) {
const commonGroups = await this.pupPage.evaluate(async (contactId) => {
const contact = window.Store.Contact.get(contactId);
if (contact.commonGroups) {
return contact.commonGroups.serialize();
}
const status = await window.Store.findCommonGroups(contact);
if (status) {
return contact.commonGroups.serialize();
}
return [];
}, contactId);
const chats = [];
for (const group of commonGroups) {
chats.push(group.id);
}
return chats;
}
/** /**
* Force reset of connection state for the client * Force reset of connection state for the client
*/ */
@@ -868,10 +929,7 @@ class Client extends EventEmitter {
* @returns {Promise<Boolean>} * @returns {Promise<Boolean>}
*/ */
async isRegisteredUser(id) { async isRegisteredUser(id) {
return await this.pupPage.evaluate(async (id) => { return Boolean(await this.getNumberId(id));
let result = await window.Store.Wap.queryExist(id);
return result.jid !== undefined;
}, id);
} }
/** /**
@@ -881,14 +939,15 @@ class Client extends EventEmitter {
* @returns {Promise<Object|null>} * @returns {Promise<Object|null>}
*/ */
async getNumberId(number) { async getNumberId(number) {
if (!number.endsWith('@c.us')) number += '@c.us'; if (!number.endsWith('@c.us')) {
try { number += '@c.us';
return await this.pupPage.evaluate(async numberId => {
return window.WWebJS.getNumberId(numberId);
}, number);
} catch(_) {
return null;
} }
return await this.pupPage.evaluate(async number => {
const result = await window.Store.QueryExist(number);
if (!result || result.wid === undefined) return null;
return result.wid;
}, number);
} }
/** /**
@@ -897,14 +956,14 @@ class Client extends EventEmitter {
* @returns {Promise<string>} * @returns {Promise<string>}
*/ */
async getFormattedNumber(number) { async getFormattedNumber(number) {
if(!number.endsWith('@s.whatsapp.net')) number = number.replace('c.us', 's.whatsapp.net'); if (!number.endsWith('@s.whatsapp.net')) number = number.replace('c.us', 's.whatsapp.net');
if(!number.includes('@s.whatsapp.net')) number = `${number}@s.whatsapp.net`; if (!number.includes('@s.whatsapp.net')) number = `${number}@s.whatsapp.net`;
return await this.pupPage.evaluate(async numberId => { return await this.pupPage.evaluate(async numberId => {
return window.Store.NumberInfo.formattedPhoneNumber(numberId); return window.Store.NumberInfo.formattedPhoneNumber(numberId);
}, number); }, number);
} }
/** /**
* Get the country code of a WhatsApp ID. * Get the country code of a WhatsApp ID.
* @param {string} number Number or ID * @param {string} number Number or ID
@@ -917,7 +976,7 @@ class Client extends EventEmitter {
return window.Store.NumberInfo.findCC(numberId); return window.Store.NumberInfo.findCC(numberId);
}, number); }, number);
} }
/** /**
* Create a new group * Create a new group
* @param {string} name group title * @param {string} name group title
@@ -936,12 +995,9 @@ class Client extends EventEmitter {
} }
const createRes = await this.pupPage.evaluate(async (name, participantIds) => { const createRes = await this.pupPage.evaluate(async (name, participantIds) => {
const res = await window.Store.Wap.createGroup(name, participantIds); const participantWIDs = participantIds.map(p => window.Store.WidFactory.createWid(p));
console.log(res); const id = window.Store.MsgKey.newId();
if (!res.status === 200) { const res = await window.Store.GroupUtils.sendCreateGroup(name, participantWIDs, undefined, id);
throw 'An error occurred while creating the group!';
}
return res; return res;
}, name, participants); }, name, participants);
@@ -962,9 +1018,9 @@ class Client extends EventEmitter {
async getLabels() { async getLabels() {
const labels = await this.pupPage.evaluate(async () => { const labels = await this.pupPage.evaluate(async () => {
return window.WWebJS.getLabels(); return window.WWebJS.getLabels();
}); });
return labels.map(data => new Label(this , data)); return labels.map(data => new Label(this, data));
} }
/** /**
@@ -975,7 +1031,7 @@ class Client extends EventEmitter {
async getLabelById(labelId) { async getLabelById(labelId) {
const label = await this.pupPage.evaluate(async (labelId) => { const label = await this.pupPage.evaluate(async (labelId) => {
return window.WWebJS.getLabel(labelId); return window.WWebJS.getLabel(labelId);
}, labelId); }, labelId);
return new Label(this, label); return new Label(this, label);
} }
@@ -985,12 +1041,12 @@ class Client extends EventEmitter {
* @param {string} chatId * @param {string} chatId
* @returns {Promise<Array<Label>>} * @returns {Promise<Array<Label>>}
*/ */
async getChatLabels(chatId){ async getChatLabels(chatId) {
const labels = await this.pupPage.evaluate(async (chatId) => { const labels = await this.pupPage.evaluate(async (chatId) => {
return window.WWebJS.getChatLabels(chatId); return window.WWebJS.getChatLabels(chatId);
}, chatId); }, chatId);
return labels.map(data => new Label(this, data)); return labels.map(data => new Label(this, data));
} }
/** /**
@@ -998,16 +1054,16 @@ class Client extends EventEmitter {
* @param {string} labelId * @param {string} labelId
* @returns {Promise<Array<Chat>>} * @returns {Promise<Array<Chat>>}
*/ */
async getChatsByLabelId(labelId){ async getChatsByLabelId(labelId) {
const chatIds = await this.pupPage.evaluate(async (labelId) => { const chatIds = await this.pupPage.evaluate(async (labelId) => {
const label = window.Store.Label.get(labelId); const label = window.Store.Label.get(labelId);
const labelItems = label.labelItemCollection.models; const labelItems = label.labelItemCollection.getModelsArray();
return labelItems.reduce((result, item) => { return labelItems.reduce((result, item) => {
if(item.parentType === 'Chat'){ if (item.parentType === 'Chat') {
result.push(item.parentId); result.push(item.parentId);
} }
return result; return result;
},[]); }, []);
}, labelId); }, labelId);
return Promise.all(chatIds.map(id => this.getChatById(id))); return Promise.all(chatIds.map(id => this.getChatById(id)));
@@ -1019,8 +1075,8 @@ class Client extends EventEmitter {
*/ */
async getBlockedContacts() { async getBlockedContacts() {
const blockedContacts = await this.pupPage.evaluate(() => { const blockedContacts = await this.pupPage.evaluate(() => {
let chatIds = window.Store.Blocklist.models.map(a => a.id._serialized); let chatIds = window.Store.Blocklist.getModelsArray().map(a => a.id._serialized);
return Promise.all(chatIds.map(id => window.WWebJS.getContact(id))); return Promise.all(chatIds.map(id => window.WWebJS.getContact(id)));
}); });
return blockedContacts.map(contact => ContactFactory.create(this.client, contact)); return blockedContacts.map(contact => ContactFactory.create(this.client, contact));

View File

@@ -0,0 +1,24 @@
'use strict';
/**
* Base class which all authentication strategies extend
*/
class BaseAuthStrategy {
constructor() {}
setup(client) {
this.client = client;
}
async beforeBrowserInitialized() {}
async afterBrowserInitialized() {}
async onAuthenticationNeeded() {
return {
failed: false,
restart: false,
failureEventPayload: undefined
};
}
async getAuthEventPayload() {}
async logout() {}
}
module.exports = BaseAuthStrategy;

View File

@@ -0,0 +1,72 @@
'use strict';
const BaseAuthStrategy = require('./BaseAuthStrategy');
/**
* Legacy session auth strategy
* Not compatible with multi-device accounts.
* @param {object} options - options
* @param {string} options.restartOnAuthFail - Restart client with a new session (i.e. use null 'session' var) if authentication fails
* @param {object} options.session - Whatsapp session to restore. If not set, will start a new session
* @param {string} options.session.WABrowserId
* @param {string} options.session.WASecretBundle
* @param {string} options.session.WAToken1
* @param {string} options.session.WAToken2
*/
class LegacySessionAuth extends BaseAuthStrategy {
constructor({ session, restartOnAuthFail }={}) {
super();
this.session = session;
this.restartOnAuthFail = restartOnAuthFail;
}
async afterBrowserInitialized() {
if(this.session) {
await this.client.pupPage.evaluateOnNewDocument(session => {
if (document.referrer === 'https://whatsapp.com/') {
localStorage.clear();
localStorage.setItem('WABrowserId', session.WABrowserId);
localStorage.setItem('WASecretBundle', session.WASecretBundle);
localStorage.setItem('WAToken1', session.WAToken1);
localStorage.setItem('WAToken2', session.WAToken2);
}
localStorage.setItem('remember-me', 'true');
}, this.session);
}
}
async onAuthenticationNeeded() {
if(this.session) {
this.session = null;
return {
failed: true,
restart: this.restartOnAuthFail,
failureEventPayload: 'Unable to log in. Are the session details valid?'
};
}
return { failed: false };
}
async getAuthEventPayload() {
const isMD = await this.client.pupPage.evaluate(() => {
return window.Store.MDBackend;
});
if(isMD) throw new Error('Authenticating via JSON session is not supported for MultiDevice-enabled WhatsApp accounts.');
const localStorage = JSON.parse(await this.client.pupPage.evaluate(() => {
return JSON.stringify(window.localStorage);
}));
return {
WABrowserId: localStorage.WABrowserId,
WASecretBundle: localStorage.WASecretBundle,
WAToken1: localStorage.WAToken1,
WAToken2: localStorage.WAToken2
};
}
}
module.exports = LegacySessionAuth;

View File

@@ -0,0 +1,53 @@
'use strict';
const path = require('path');
const fs = require('fs');
const BaseAuthStrategy = require('./BaseAuthStrategy');
/**
* Local directory-based authentication
* @param {object} options - options
* @param {string} options.clientId - Client id to distinguish instances if you are using multiple, otherwise keep null if you are using only one instance
* @param {string} options.dataPath - Change the default path for saving session files, default is: "./.wwebjs_auth/"
*/
class LocalAuth extends BaseAuthStrategy {
constructor({ clientId, dataPath }={}) {
super();
const idRegex = /^[-_\w]+$/i;
if(clientId && !idRegex.test(clientId)) {
throw new Error('Invalid clientId. Only alphanumeric characters, underscores and hyphens are allowed.');
}
this.dataPath = path.resolve(dataPath || './.wwebjs_auth/');
this.clientId = clientId;
}
async beforeBrowserInitialized() {
const puppeteerOpts = this.client.options.puppeteer;
const sessionDirName = this.clientId ? `session-${this.clientId}` : 'session';
const dirPath = path.join(this.dataPath, sessionDirName);
if(puppeteerOpts.userDataDir && puppeteerOpts.userDataDir !== dirPath) {
throw new Error('LocalAuth is not compatible with a user-supplied userDataDir.');
}
fs.mkdirSync(dirPath, { recursive: true });
this.client.options.puppeteer = {
...puppeteerOpts,
userDataDir: dirPath
};
this.userDataDir = dirPath;
}
async logout() {
if (this.userDataDir) {
return (fs.rmSync ? fs.rmSync : fs.rmdirSync).call(this, this.userDataDir, { recursive: true });
}
}
}
module.exports = LocalAuth;

View File

@@ -0,0 +1,12 @@
'use strict';
const BaseAuthStrategy = require('./BaseAuthStrategy');
/**
* No session restoring functionality
* Will need to authenticate via QR code every time
*/
class NoAuth extends BaseAuthStrategy { }
module.exports = NoAuth;

View File

@@ -179,11 +179,11 @@ class Chat extends Base {
const msgFilter = m => !m.isNotification; // dont include notification messages const msgFilter = m => !m.isNotification; // dont include notification messages
const chat = window.Store.Chat.get(chatId); const chat = window.Store.Chat.get(chatId);
let msgs = chat.msgs.models.filter(msgFilter); let msgs = chat.msgs.getModelsArray().filter(msgFilter);
if (searchOptions && searchOptions.limit > 0) { if (searchOptions && searchOptions.limit > 0) {
while (msgs.length < searchOptions.limit) { while (msgs.length < searchOptions.limit) {
const loadedMessages = await chat.loadEarlierMsgs(); const loadedMessages = await window.Store.ConversationMsgs.loadEarlierMsgs(chat);
if (!loadedMessages) break; if (!loadedMessages) break;
msgs = [...loadedMessages.filter(msgFilter), ...msgs]; msgs = [...loadedMessages.filter(msgFilter), ...msgs];
} }

View File

@@ -20,12 +20,6 @@ class ClientInfo extends Base {
*/ */
this.pushname = data.pushname; this.pushname = data.pushname;
/**
* @type {object}
* @deprecated Use .wid instead
*/
this.me = data.wid;
/** /**
* Current user ID * Current user ID
* @type {object} * @type {object}
@@ -33,18 +27,25 @@ class ClientInfo extends Base {
this.wid = data.wid; this.wid = data.wid;
/** /**
* Information about the phone this client is connected to * @type {object}
* @deprecated Use .wid instead
*/
this.me = data.wid;
/**
* Information about the phone this client is connected to. Not available in multi-device.
* @type {object} * @type {object}
* @property {string} wa_version WhatsApp Version running on the phone * @property {string} wa_version WhatsApp Version running on the phone
* @property {string} os_version OS Version running on the phone (iOS or Android version) * @property {string} os_version OS Version running on the phone (iOS or Android version)
* @property {string} device_manufacturer Device manufacturer * @property {string} device_manufacturer Device manufacturer
* @property {string} device_model Device model * @property {string} device_model Device model
* @property {string} os_build_number OS build number * @property {string} os_build_number OS build number
* @deprecated
*/ */
this.phone = data.phone; this.phone = data.phone;
/** /**
* Platform the phone is running on * Platform WhatsApp is running on
* @type {string} * @type {string}
*/ */
this.platform = data.platform; this.platform = data.platform;
@@ -57,6 +58,7 @@ class ClientInfo extends Base {
* @returns {object} batteryStatus * @returns {object} batteryStatus
* @returns {number} batteryStatus.battery - The current battery percentage * @returns {number} batteryStatus.battery - The current battery percentage
* @returns {boolean} batteryStatus.plugged - Indicates if the phone is plugged in (true) or not (false) * @returns {boolean} batteryStatus.plugged - Indicates if the phone is plugged in (true) or not (false)
* @deprecated
*/ */
async getBatteryStatus() { async getBatteryStatus() {
return await this.client.pupPage.evaluate(() => { return await this.client.pupPage.evaluate(() => {
@@ -64,7 +66,6 @@ class ClientInfo extends Base {
return { battery, plugged }; return { battery, plugged };
}); });
} }
} }
module.exports = ClientInfo; module.exports = ClientInfo;

View File

@@ -183,7 +183,8 @@ class Contact extends Base {
*/ */
async getAbout() { async getAbout() {
const about = await this.client.pupPage.evaluate(async (contactId) => { const about = await this.client.pupPage.evaluate(async (contactId) => {
return window.Store.Wap.statusFind(contactId); const wid = window.Store.WidFactory.createWid(contactId);
return window.Store.StatusUtils.getStatus(wid);
}, this.id._serialized); }, this.id._serialized);
if (typeof about.status !== 'string') if (typeof about.status !== 'string')
@@ -191,6 +192,14 @@ class Contact extends Base {
return about.status; return about.status;
} }
/**
* Gets the Contact's common groups with you. Returns empty array if you don't have any common group.
* @returns {Promise<WAWebJS.ChatId[]>}
*/
async getCommonGroups() {
return await this.client.getCommonGroups(this.id._serialized);
}
} }

View File

@@ -60,7 +60,9 @@ class GroupChat extends Chat {
*/ */
async addParticipants(participantIds) { async addParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => { return await this.client.pupPage.evaluate((chatId, participantIds) => {
return window.Store.Wap.addParticipants(chatId, participantIds); const chatWid = window.Store.WidFactory.createWid(chatId);
const participantWids = participantIds.map(p => window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendAddParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
@@ -71,7 +73,9 @@ class GroupChat extends Chat {
*/ */
async removeParticipants(participantIds) { async removeParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => { return await this.client.pupPage.evaluate((chatId, participantIds) => {
return window.Store.Wap.removeParticipants(chatId, participantIds); const chatWid = window.Store.WidFactory.createWid(chatId);
const participantWids = participantIds.map(p => window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendRemoveParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
@@ -82,7 +86,9 @@ class GroupChat extends Chat {
*/ */
async promoteParticipants(participantIds) { async promoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => { return await this.client.pupPage.evaluate((chatId, participantIds) => {
return window.Store.Wap.promoteParticipants(chatId, participantIds); const chatWid = window.Store.WidFactory.createWid(chatId);
const participantWids = participantIds.map(p => window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendPromoteParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
@@ -93,39 +99,53 @@ class GroupChat extends Chat {
*/ */
async demoteParticipants(participantIds) { async demoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => { return await this.client.pupPage.evaluate((chatId, participantIds) => {
return window.Store.Wap.demoteParticipants(chatId, participantIds); const chatWid = window.Store.WidFactory.createWid(chatId);
const participantWids = participantIds.map(p => window.Store.WidFactory.createWid(p));
return window.Store.GroupParticipants.sendDemoteParticipants(chatWid, participantWids);
}, this.id._serialized, participantIds); }, this.id._serialized, participantIds);
} }
/** /**
* Updates the group subject * Updates the group subject
* @param {string} subject * @param {string} subject
* @returns {Promise} * @returns {Promise<boolean>} Returns true if the subject was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setSubject(subject) { async setSubject(subject) {
let res = await this.client.pupPage.evaluate((chatId, subject) => { const success = await this.client.pupPage.evaluate(async (chatId, subject) => {
return window.Store.Wap.changeSubject(chatId, subject); const chatWid = window.Store.WidFactory.createWid(chatId);
try {
return await window.Store.GroupUtils.sendSetGroupSubject(chatWid, subject);
} catch (err) {
if(err.name === 'ServerStatusCodeError') return false;
throw err;
}
}, this.id._serialized, subject); }, this.id._serialized, subject);
if(res.status == 200) { if(!success) return false;
this.name = subject; this.name = subject;
} return true;
} }
/** /**
* Updates the group description * Updates the group description
* @param {string} description * @param {string} description
* @returns {Promise} * @returns {Promise<boolean>} Returns true if the description was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setDescription(description) { async setDescription(description) {
let res = await this.client.pupPage.evaluate((chatId, description) => { const success = await this.client.pupPage.evaluate(async (chatId, description) => {
let descId = window.Store.GroupMetadata.get(chatId).descId; const chatWid = window.Store.WidFactory.createWid(chatId);
return window.Store.Wap.setGroupDescription(chatId, description, window.Store.genId(), descId); let descId = window.Store.GroupMetadata.get(chatWid).descId;
try {
return await window.Store.GroupUtils.sendSetGroupDescription(chatWid, description, window.Store.MsgKey.newId(), descId);
} catch (err) {
if(err.name === 'ServerStatusCodeError') return false;
throw err;
}
}, this.id._serialized, description); }, this.id._serialized, description);
if (res.status == 200) { if(!success) return false;
this.groupMetadata.desc = description; this.groupMetadata.desc = description;
} return true;
} }
/** /**
@@ -134,12 +154,18 @@ class GroupChat extends Chat {
* @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions. * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setMessagesAdminsOnly(adminsOnly=true) { async setMessagesAdminsOnly(adminsOnly=true) {
let res = await this.client.pupPage.evaluate((chatId, value) => { const success = await this.client.pupPage.evaluate(async (chatId, adminsOnly) => {
return window.Store.Wap.setGroupProperty(chatId, 'announcement', value); const chatWid = window.Store.WidFactory.createWid(chatId);
try {
return await window.Store.GroupUtils.sendSetGroupProperty(chatWid, 'announcement', adminsOnly ? 1 : 0);
} catch (err) {
if(err.name === 'ServerStatusCodeError') return false;
throw err;
}
}, this.id._serialized, adminsOnly); }, this.id._serialized, adminsOnly);
if (res.status !== 200) return false; if(!success) return false;
this.groupMetadata.announce = adminsOnly; this.groupMetadata.announce = adminsOnly;
return true; return true;
} }
@@ -150,11 +176,17 @@ class GroupChat extends Chat {
* @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions. * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
*/ */
async setInfoAdminsOnly(adminsOnly=true) { async setInfoAdminsOnly(adminsOnly=true) {
let res = await this.client.pupPage.evaluate((chatId, value) => { const success = await this.client.pupPage.evaluate(async (chatId, adminsOnly) => {
return window.Store.Wap.setGroupProperty(chatId, 'restrict', value); const chatWid = window.Store.WidFactory.createWid(chatId);
try {
return await window.Store.GroupUtils.sendSetGroupProperty(chatWid, 'restrict', adminsOnly ? 1 : 0);
} catch (err) {
if(err.name === 'ServerStatusCodeError') return false;
throw err;
}
}, this.id._serialized, adminsOnly); }, this.id._serialized, adminsOnly);
if (res.status !== 200) return false; if(!success) return false;
this.groupMetadata.restrict = adminsOnly; this.groupMetadata.restrict = adminsOnly;
return true; return true;
@@ -165,25 +197,25 @@ class GroupChat extends Chat {
* @returns {Promise<string>} Group's invite code * @returns {Promise<string>} Group's invite code
*/ */
async getInviteCode() { async getInviteCode() {
let res = await this.client.pupPage.evaluate(chatId => { const code = await this.client.pupPage.evaluate(async chatId => {
return window.Store.Wap.groupInviteCode(chatId); const chatWid = window.Store.WidFactory.createWid(chatId);
return window.Store.Invite.sendQueryGroupInviteCode(chatWid);
}, this.id._serialized); }, this.id._serialized);
if (res.status == 200) { return code;
return res.code;
}
throw new Error('Not authorized');
} }
/** /**
* Invalidates the current group invite code and generates a new one * Invalidates the current group invite code and generates a new one
* @returns {Promise} * @returns {Promise<string>} New invite code
*/ */
async revokeInvite() { async revokeInvite() {
return await this.client.pupPage.evaluate(chatId => { const code = await this.client.pupPage.evaluate(chatId => {
return window.Store.Wap.revokeGroupInvite(chatId); const chatWid = window.Store.WidFactory.createWid(chatId);
return window.Store.Invite.sendRevokeGroupInviteCode(chatWid);
}, this.id._serialized); }, this.id._serialized);
return code;
} }
/** /**
@@ -191,8 +223,9 @@ class GroupChat extends Chat {
* @returns {Promise} * @returns {Promise}
*/ */
async leave() { async leave() {
return await this.client.pupPage.evaluate(chatId => { await this.client.pupPage.evaluate(chatId => {
return window.Store.Wap.leaveGroup(chatId); const chatWid = window.Store.WidFactory.createWid(chatId);
return window.Store.GroupUtils.sendExitGroup(chatWid);
}, this.id._serialized); }, this.id._serialized);
} }

View File

@@ -43,7 +43,7 @@ class GroupNotification extends Base {
* *
* @type {string} * @type {string}
*/ */
this.chatId = typeof (data.to) === 'object' ? data.to._serialized : data.to; this.chatId = typeof (data.id.remote) === 'object' ? data.id.remote._serialized : data.id.remote;
/** /**
* ContactId for the user that produced the GroupNotification. * ContactId for the user that produced the GroupNotification.

View File

@@ -19,13 +19,14 @@ class Message extends Base {
} }
_patch(data) { _patch(data) {
this._data = data;
/** /**
* MediaKey that represents the sticker 'ID' * MediaKey that represents the sticker 'ID'
* @type {string} * @type {string}
*/ */
this.mediaKey = data.mediaKey; this.mediaKey = data.mediaKey;
/** /**
* ID that represents the message * ID that represents the message
* @type {object} * @type {object}
@@ -50,7 +51,7 @@ class Message extends Base {
*/ */
this.body = this.hasMedia ? data.caption || '' : data.body || ''; this.body = this.hasMedia ? data.caption || '' : data.body || '';
/** /**
* Message type * Message type
* @type {MessageTypes} * @type {MessageTypes}
*/ */
@@ -70,9 +71,9 @@ class Message extends Base {
/** /**
* ID for who this message is for. * ID for who this message is for.
* *
* If the message is sent by the current user, it will be the Chat to which the message is being sent. * If the message is sent by the current user, it will be the Chat to which the message is being sent.
* If the message is sent by another user, it will be the ID for the current user. * If the message is sent by another user, it will be the ID for the current user.
* @type {string} * @type {string}
*/ */
this.to = (typeof (data.to) === 'object' && data.to !== null) ? data.to._serialized : data.to; this.to = (typeof (data.to) === 'object' && data.to !== null) ? data.to._serialized : data.to;
@@ -87,8 +88,8 @@ class Message extends Base {
* String that represents from which device type the message was sent * String that represents from which device type the message was sent
* @type {string} * @type {string}
*/ */
this.deviceType = data.id.id.length > 21 ? 'android' : data.id.id.substring(0,2) =='3A' ? 'ios' : 'web'; this.deviceType = data.id.id.length > 21 ? 'android' : data.id.id.substring(0, 2) == '3A' ? 'ios' : 'web';
/** /**
* Indicates if the message was forwarded * Indicates if the message was forwarded
* @type {boolean} * @type {boolean}
@@ -114,14 +115,14 @@ class Message extends Base {
* @type {boolean} * @type {boolean}
*/ */
this.isStarred = data.star; this.isStarred = data.star;
/** /**
* Indicates if the message was a broadcast * Indicates if the message was a broadcast
* @type {boolean} * @type {boolean}
*/ */
this.broadcast = data.broadcast; this.broadcast = data.broadcast;
/** /**
* Indicates if the message was sent by the current user * Indicates if the message was sent by the current user
* @type {boolean} * @type {boolean}
*/ */
@@ -133,6 +134,12 @@ class Message extends Base {
*/ */
this.hasQuotedMsg = data.quotedMsg ? true : false; this.hasQuotedMsg = data.quotedMsg ? true : false;
/**
* Indicates the duration of the message in seconds
* @type {string}
*/
this.duration = data.duration ? data.duration : undefined;
/** /**
* Location information contained in the message, if the message is type "location" * Location information contained in the message, if the message is type "location"
* @type {Location} * @type {Location}
@@ -157,7 +164,7 @@ class Message extends Base {
fromId: data.from._serialized, fromId: data.from._serialized,
toId: data.to._serialized toId: data.to._serialized
} : undefined; } : undefined;
/** /**
* Indicates the mentions in the message body. * Indicates the mentions in the message body.
* @type {Array<string>} * @type {Array<string>}
@@ -214,7 +221,7 @@ class Message extends Base {
/** /**
* Links included in the message. * Links included in the message.
* @type {Array<{link: string, isSuspicious: boolean}>} * @type {Array<{link: string, isSuspicious: boolean}>}
* *
*/ */
this.links = data.links; this.links = data.links;
@@ -222,7 +229,7 @@ class Message extends Base {
if (data.dynamicReplyButtons) { if (data.dynamicReplyButtons) {
this.dynamicReplyButtons = data.dynamicReplyButtons; this.dynamicReplyButtons = data.dynamicReplyButtons;
} }
/** Selected Button Id **/ /** Selected Button Id **/
if (data.selectedButtonId) { if (data.selectedButtonId) {
this.selectedButtonId = data.selectedButtonId; this.selectedButtonId = data.selectedButtonId;
@@ -232,7 +239,7 @@ class Message extends Base {
if (data.listResponse && data.listResponse.singleSelectReply.selectedRowId) { if (data.listResponse && data.listResponse.singleSelectReply.selectedRowId) {
this.selectedRowId = data.listResponse.singleSelectReply.selectedRowId; this.selectedRowId = data.listResponse.singleSelectReply.selectedRowId;
} }
return super._patch(data); return super._patch(data);
} }
@@ -240,6 +247,32 @@ class Message extends Base {
return this.fromMe ? this.to : this.from; return this.fromMe ? this.to : this.from;
} }
/**
* Reloads this Message object's data in-place with the latest values from WhatsApp Web.
* Note that the Message must still be in the web app cache for this to work, otherwise will return null.
* @returns {Promise<Message>}
*/
async reload() {
const newData = await this.client.pupPage.evaluate((msgId) => {
const msg = window.Store.Msg.get(msgId);
if(!msg) return null;
return window.WWebJS.getMessageModel(msg);
}, this.id._serialized);
if(!newData) return null;
this._patch(newData);
return this;
}
/**
* Returns message in a raw format
* @type {Object}
*/
get rawData() {
return this._data;
}
/** /**
* Returns the Chat this message was sent in * Returns the Chat this message was sent in
* @returns {Promise<Chat>} * @returns {Promise<Chat>}
@@ -280,12 +313,12 @@ class Message extends Base {
} }
/** /**
* Sends a message as a reply to this message. If chatId is specified, it will be sent * Sends a message as a reply to this message. If chatId is specified, it will be sent
* through the specified Chat. If not, it will send the message * through the specified Chat. If not, it will send the message
* in the same Chat as the original message was sent. * in the same Chat as the original message was sent.
* *
* @param {string|MessageMedia|Location} content * @param {string|MessageMedia|Location} content
* @param {string} [chatId] * @param {string} [chatId]
* @param {MessageSendOptions} [options] * @param {MessageSendOptions} [options]
* @returns {Promise<Message>} * @returns {Promise<Message>}
*/ */
@@ -309,10 +342,10 @@ class Message extends Base {
async acceptGroupV4Invite() { async acceptGroupV4Invite() {
return await this.client.acceptGroupV4Invite(this.inviteV4); return await this.client.acceptGroupV4Invite(this.inviteV4);
} }
/** /**
* Forwards this message to another chat * Forwards this message to another chat
* *
* @param {string|Chat} chat Chat model or chat ID to which the message will be forwarded * @param {string|Chat} chat Chat model or chat ID to which the message will be forwarded
* @returns {Promise} * @returns {Promise}
*/ */
@@ -342,7 +375,7 @@ class Message extends Base {
if (msg.mediaData.mediaStage != 'RESOLVED') { if (msg.mediaData.mediaStage != 'RESOLVED') {
// try to resolve media // try to resolve media
await msg.downloadMedia({ await msg.downloadMedia({
downloadEvenIfExpensive: true, downloadEvenIfExpensive: true,
rmrReason: 1 rmrReason: 1
}); });
} }
@@ -362,9 +395,9 @@ class Message extends Base {
type: msg.type, type: msg.type,
signal: (new AbortController).signal signal: (new AbortController).signal
}); });
const data = window.WWebJS.arrayBufferToBase64(decryptedMedia); const data = window.WWebJS.arrayBufferToBase64(decryptedMedia);
return { return {
data, data,
mimetype: msg.mimetype, mimetype: msg.mimetype,
@@ -389,7 +422,7 @@ class Message extends Base {
let msg = window.Store.Msg.get(msgId); let msg = window.Store.Msg.get(msgId);
if (everyone && msg.id.fromMe && msg._canRevoke()) { if (everyone && msg.id.fromMe && msg._canRevoke()) {
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], true); return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], {type: 'Sender'});
} }
return window.Store.Cmd.sendDeleteMsgs(msg.chat, [msg], true); return window.Store.Cmd.sendDeleteMsgs(msg.chat, [msg], true);
@@ -440,14 +473,10 @@ class Message extends Base {
async getInfo() { async getInfo() {
const info = await this.client.pupPage.evaluate(async (msgId) => { const info = await this.client.pupPage.evaluate(async (msgId) => {
const msg = window.Store.Msg.get(msgId); const msg = window.Store.Msg.get(msgId);
if(!msg) return null; if (!msg) return null;
return await window.Store.Wap.queryMsgInfo(msg.id);
}, this.id._serialized);
if(info.status) { return await window.Store.MessageInfo.sendQueryMsgInfo(msg);
return null; }, this.id._serialized);
}
return info; return info;
} }
@@ -458,9 +487,9 @@ class Message extends Base {
*/ */
async getOrder() { async getOrder() {
if (this.type === MessageTypes.ORDER) { if (this.type === MessageTypes.ORDER) {
const result = await this.client.pupPage.evaluate((orderId, token) => { const result = await this.client.pupPage.evaluate((orderId, token, chatId) => {
return window.WWebJS.getOrderDetail(orderId, token); return window.WWebJS.getOrderDetail(orderId, token, chatId);
}, this.orderId, this.token); }, this.orderId, this.token, this._getChatId());
if (!result) return undefined; if (!result) return undefined;
return new Order(this.client, result); return new Order(this.client, result);
} }

View File

@@ -7,10 +7,7 @@ exports.DefaultOptions = {
headless: true, headless: true,
defaultViewport: null defaultViewport: null
}, },
session: false, authTimeoutMs: 0,
qrTimeoutMs: 45000,
qrRefreshIntervalMs: 20000,
authTimeoutMs: 45000,
qrMaxRetries: 0, qrMaxRetries: 0,
takeoverOnConflict: false, takeoverOnConflict: false,
takeoverTimeoutMs: 0, takeoverTimeoutMs: 0,

View File

@@ -6,38 +6,61 @@ exports.ExposeStore = (moduleRaidStr) => {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
window.mR = moduleRaid(); window.mR = moduleRaid();
window.Store = Object.assign({}, window.mR.findModule(m => m.default && m.default.Chat)[0].default); window.Store = Object.assign({}, window.mR.findModule(m => m.default && m.default.Chat)[0].default);
window.Store.AppState = window.mR.findModule('STREAM')[0].Socket; window.Store.AppState = window.mR.findModule('Socket')[0].Socket;
window.Store.Conn = window.mR.findModule('Conn')[0].Conn; window.Store.Conn = window.mR.findModule('Conn')[0].Conn;
window.Store.Wap = window.mR.findModule('queryLinkPreview')[0].default; window.Store.BlockContact = window.mR.findModule('blockContact')[0];
window.Store.SendSeen = window.mR.findModule('sendSeen')[0]; window.Store.Call = window.mR.findModule('CallCollection')[0].CallCollection;
window.Store.SendClear = window.mR.findModule('sendClear')[0]; window.Store.Cmd = window.mR.findModule('Cmd')[0].Cmd;
window.Store.SendDelete = window.mR.findModule('sendDelete')[0]; window.Store.CryptoLib = window.mR.findModule('decryptE2EMedia')[0];
window.Store.genId = window.mR.findModule('randomId')[0].randomId; window.Store.DownloadManager = window.mR.findModule('downloadManager')[0].downloadManager;
window.Store.SendMessage = window.mR.findModule('addAndSendMsgToChat')[0]; window.Store.MDBackend = window.mR.findModule('isMDBackend')[0].isMDBackend();
window.Store.MsgKey = window.mR.findModule((module) => module.default && module.default.fromString)[0].default; window.Store.Features = window.mR.findModule('FEATURE_CHANGE_EVENT')[0].LegacyPhoneFeatures;
window.Store.GroupMetadata = window.mR.findModule((module) => module.default && module.default.handlePendingInvite)[0].default;
window.Store.Invite = window.mR.findModule('sendJoinGroupViaInvite')[0]; window.Store.Invite = window.mR.findModule('sendJoinGroupViaInvite')[0];
window.Store.OpaqueData = window.mR.findModule(module => module.default && module.default.createFromData)[0].default; window.Store.InviteInfo = window.mR.findModule('sendQueryGroupInvite')[0];
window.Store.Label = window.mR.findModule('LabelCollection')[0].LabelCollection;
window.Store.MediaPrep = window.mR.findModule('MediaPrep')[0]; window.Store.MediaPrep = window.mR.findModule('MediaPrep')[0];
window.Store.MediaObject = window.mR.findModule('getOrCreateMediaObject')[0]; window.Store.MediaObject = window.mR.findModule('getOrCreateMediaObject')[0];
window.Store.MediaUpload = window.mR.findModule('uploadMedia')[0];
window.Store.NumberInfo = window.mR.findModule('formattedPhoneNumber')[0]; window.Store.NumberInfo = window.mR.findModule('formattedPhoneNumber')[0];
window.Store.Cmd = window.mR.findModule('Cmd')[0].Cmd;
window.Store.MediaTypes = window.mR.findModule('msgToMediaType')[0]; window.Store.MediaTypes = window.mR.findModule('msgToMediaType')[0];
window.Store.VCard = window.mR.findModule('vcardFromContactModel')[0]; window.Store.MediaUpload = window.mR.findModule('uploadMedia')[0];
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].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];
window.Store.SendDelete = window.mR.findModule('sendDelete')[0];
window.Store.SendMessage = window.mR.findModule('addAndSendMsgToChat')[0];
window.Store.SendSeen = window.mR.findModule('sendSeen')[0];
window.Store.User = window.mR.findModule('getMaybeMeUser')[0];
window.Store.UploadUtils = window.mR.findModule((module) => (module.default && module.default.encryptAndUpload) ? module.default : null)[0].default;
window.Store.UserConstructor = window.mR.findModule((module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null)[0].default; window.Store.UserConstructor = window.mR.findModule((module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null)[0].default;
window.Store.Validators = window.mR.findModule('findLinks')[0]; window.Store.Validators = window.mR.findModule('findLinks')[0];
window.Store.VCard = window.mR.findModule('vcardFromContactModel')[0];
window.Store.Wap = window.mR.findModule('queryLinkPreview')[0].default;
window.Store.WidFactory = window.mR.findModule('createWid')[0]; window.Store.WidFactory = window.mR.findModule('createWid')[0];
window.Store.BlockContact = window.mR.findModule('blockContact')[0]; window.Store.ProfilePic = window.mR.findModule('profilePicResync')[0];
window.Store.GroupMetadata = window.mR.findModule((module) => module.default && module.default.handlePendingInvite)[0].default; window.Store.PresenceUtils = window.mR.findModule('sendPresenceAvailable')[0];
window.Store.UploadUtils = window.mR.findModule((module) => (module.default && module.default.encryptAndUpload) ? module.default : null)[0].default; window.Store.ChatState = window.mR.findModule('sendChatStateComposing')[0];
window.Store.Label = window.mR.findModule('LabelCollection')[0].LabelCollection; window.Store.GroupParticipants = window.mR.findModule('sendPromoteParticipants')[0];
window.Store.Features = window.mR.findModule('FEATURE_CHANGE_EVENT')[0].GK; window.Store.JoinInviteV4 = window.mR.findModule('sendJoinGroupViaInviteV4')[0];
window.Store.QueryOrder = window.mR.findModule('queryOrder')[0]; window.Store.findCommonGroups = window.mR.findModule('findCommonGroups')[0].findCommonGroups;
window.Store.QueryProduct = window.mR.findModule('queryProduct')[0]; window.Store.StatusUtils = window.mR.findModule('setMyStatus')[0];
window.Store.DownloadManager = window.mR.findModule('downloadManager')[0].downloadManager; window.Store.ConversationMsgs = window.mR.findModule('loadEarlierMsgs')[0];
window.Store.Call = window.mR.findModule('CallCollection')[0].CallCollection; window.Store.StickerTools = {
...window.mR.findModule('toWebpSticker')[0],
...window.mR.findModule('addWebpMetadata')[0]
};
window.Store.GroupUtils = {
...window.mR.findModule('sendCreateGroup')[0],
...window.mR.findModule('sendSetGroupSubject')[0],
...window.mR.findModule('markExited')[0]
};
if(!window.Store.Chat._find) { if (!window.Store.Chat._find) {
window.Store.Chat._find = e => { window.Store.Chat._find = e => {
const target = window.Store.Chat.get(e); const target = window.Store.Chat.get(e);
return target ? Promise.resolve(target) : Promise.resolve({ return target ? Promise.resolve(target) : Promise.resolve({
@@ -50,14 +73,6 @@ exports.ExposeStore = (moduleRaidStr) => {
exports.LoadUtils = () => { exports.LoadUtils = () => {
window.WWebJS = {}; window.WWebJS = {};
window.WWebJS.getNumberId = async (id) => {
let result = await window.Store.Wap.queryExist(id);
if (result.jid === undefined)
throw 'The number provided is not a registered whatsapp user';
return result.jid;
};
window.WWebJS.sendSeen = async (chatId) => { window.WWebJS.sendSeen = async (chatId) => {
let chat = window.Store.Chat.get(chatId); let chat = window.Store.Chat.get(chatId);
if (chat !== undefined) { if (chat !== undefined) {
@@ -67,14 +82,14 @@ exports.LoadUtils = () => {
return false; return false;
}; };
window.WWebJS.sendMessage = async (chat, content, options = {}) => { window.WWebJS.sendMessage = async (chat, content, options = {}) => {
let attOptions = {}; let attOptions = {};
if (options.attachment) { if (options.attachment) {
attOptions = options.sendMediaAsSticker attOptions = options.sendMediaAsSticker
? await window.WWebJS.processStickerData(options.attachment) ? await window.WWebJS.processStickerData(options.attachment)
: await window.WWebJS.processMediaData(options.attachment, { : await window.WWebJS.processMediaData(options.attachment, {
forceVoice: options.sendAudioAsVoice, forceVoice: options.sendAudioAsVoice,
forceDocument: options.sendMediaAsDocument, forceDocument: options.sendMediaAsDocument,
forceGif: options.sendVideoAsGif forceGif: options.sendVideoAsGif
}); });
@@ -144,22 +159,26 @@ exports.LoadUtils = () => {
if (options.linkPreview) { if (options.linkPreview) {
delete options.linkPreview; delete options.linkPreview;
const link = window.Store.Validators.findLink(content);
if (link) { // Not supported yet by WhatsApp Web on MD
const preview = await window.Store.Wap.queryLinkPreview(link.url); if(!window.Store.MDBackend) {
preview.preview = true; const link = window.Store.Validators.findLink(content);
preview.subtype = 'url'; if (link) {
options = { ...options, ...preview }; const preview = await window.Store.Wap.queryLinkPreview(link.url);
preview.preview = true;
preview.subtype = 'url';
options = { ...options, ...preview };
}
} }
} }
let buttonOptions = {}; let buttonOptions = {};
if(options.buttons){ if(options.buttons){
let caption; let caption;
if(options.buttons.type === 'chat') { if (options.buttons.type === 'chat') {
content = options.buttons.body; content = options.buttons.body;
caption = content; caption = content;
}else{ } else {
caption = options.caption ? options.caption : ' '; //Caption can't be empty caption = options.caption ? options.caption : ' '; //Caption can't be empty
} }
buttonOptions = { buttonOptions = {
@@ -192,11 +211,16 @@ exports.LoadUtils = () => {
delete options.list; delete options.list;
delete listOptions.list.footer; delete listOptions.list.footer;
} }
const meUser = window.Store.User.getMaybeMeUser();
const isMD = window.Store.MDBackend;
const newMsgId = new window.Store.MsgKey({ const newMsgId = new window.Store.MsgKey({
fromMe: true, from: meUser,
remote: chat.id, to: chat.id,
id: window.Store.genId(), id: window.Store.MsgKey.newId(),
participant: isMD && chat.id.isGroup() ? meUser : undefined,
selfDir: 'out',
}); });
const extraOptions = options.extraOptions || {}; const extraOptions = options.extraOptions || {};
@@ -213,7 +237,7 @@ exports.LoadUtils = () => {
id: newMsgId, id: newMsgId,
ack: 0, ack: 0,
body: content, body: content,
from: window.Store.Conn.wid, from: meUser,
to: chat.id, to: chat.id,
local: true, local: true,
self: 'out', self: 'out',
@@ -234,11 +258,25 @@ exports.LoadUtils = () => {
return window.Store.Msg.get(newMsgId._serialized); return window.Store.Msg.get(newMsgId._serialized);
}; };
window.WWebJS.toStickerData = async (mediaInfo) => {
if (mediaInfo.mimetype == 'image/webp') return mediaInfo;
const file = window.WWebJS.mediaInfoToFile(mediaInfo);
const webpSticker = await window.Store.StickerTools.toWebpSticker(file);
const webpBuffer = await webpSticker.arrayBuffer();
const data = window.WWebJS.arrayBufferToBase64(webpBuffer);
return {
mimetype: 'image/webp',
data
};
};
window.WWebJS.processStickerData = async (mediaInfo) => { window.WWebJS.processStickerData = async (mediaInfo) => {
if (mediaInfo.mimetype !== 'image/webp') throw new Error('Invalid media type'); if (mediaInfo.mimetype !== 'image/webp') throw new Error('Invalid media type');
const file = window.WWebJS.mediaInfoToFile(mediaInfo); const file = window.WWebJS.mediaInfoToFile(mediaInfo);
let filehash = await window.WWebJS.getFileHash(file); let filehash = await window.WWebJS.getFileHash(file);
let mediaKey = await window.WWebJS.generateHash(32); let mediaKey = await window.WWebJS.generateHash(32);
const controller = new AbortController(); const controller = new AbortController();
@@ -324,11 +362,11 @@ exports.LoadUtils = () => {
window.WWebJS.getMessageModel = message => { window.WWebJS.getMessageModel = message => {
const msg = message.serialize(); const msg = message.serialize();
msg.isEphemeral = message.isEphemeral; msg.isEphemeral = message.isEphemeral;
msg.isStatusV3 = message.isStatusV3; msg.isStatusV3 = message.isStatusV3;
msg.links = (message.getLinks()).map(link => ({ msg.links = (message.getLinks()).map(link => ({
link: link.href, link: link.href,
isSuspicious: Boolean(link.suspiciousCharacters && link.suspiciousCharacters.size) isSuspicious: Boolean(link.suspiciousCharacters && link.suspiciousCharacters.size)
})); }));
@@ -338,28 +376,30 @@ exports.LoadUtils = () => {
if (msg.dynamicReplyButtons) { if (msg.dynamicReplyButtons) {
msg.dynamicReplyButtons = JSON.parse(JSON.stringify(msg.dynamicReplyButtons)); msg.dynamicReplyButtons = JSON.parse(JSON.stringify(msg.dynamicReplyButtons));
} }
if(msg.replyButtons) { if (msg.replyButtons) {
msg.replyButtons = JSON.parse(JSON.stringify(msg.replyButtons)); msg.replyButtons = JSON.parse(JSON.stringify(msg.replyButtons));
} }
if(typeof msg.id.remote === 'object') { if (typeof msg.id.remote === 'object') {
msg.id = Object.assign({}, msg.id, {remote: msg.id.remote._serialized}); msg.id = Object.assign({}, msg.id, { remote: msg.id.remote._serialized });
} }
delete msg.pendingAckUpdate; delete msg.pendingAckUpdate;
return msg; return msg;
}; };
window.WWebJS.getChatModel = async chat => { window.WWebJS.getChatModel = async chat => {
let res = chat.serialize(); let res = chat.serialize();
res.isGroup = chat.isGroup; res.isGroup = chat.isGroup;
res.formattedTitle = chat.formattedTitle; res.formattedTitle = chat.formattedTitle;
res.isMuted = chat.mute && chat.mute.isMuted; res.isMuted = chat.mute && chat.mute.isMuted;
if (chat.groupMetadata) { if (chat.groupMetadata) {
await window.Store.GroupMetadata.update(chat.id._serialized); const chatWid = window.Store.WidFactory.createWid((chat.id._serialized));
await window.Store.GroupMetadata.update(chatWid);
res.groupMetadata = chat.groupMetadata.serialize(); res.groupMetadata = chat.groupMetadata.serialize();
} }
@@ -377,7 +417,7 @@ exports.LoadUtils = () => {
}; };
window.WWebJS.getChats = async () => { window.WWebJS.getChats = async () => {
const chats = window.Store.Chat.models; const chats = window.Store.Chat.getModelsArray();
const chatPromises = chats.map(chat => window.WWebJS.getChatModel(chat)); const chatPromises = chats.map(chat => window.WWebJS.getChatModel(chat));
return await Promise.all(chatPromises); return await Promise.all(chatPromises);
@@ -409,12 +449,12 @@ exports.LoadUtils = () => {
}; };
window.WWebJS.getContacts = () => { window.WWebJS.getContacts = () => {
const contacts = window.Store.Contact.models; const contacts = window.Store.Contact.getModelsArray();
return contacts.map(contact => window.WWebJS.getContactModel(contact)); return contacts.map(contact => window.WWebJS.getContactModel(contact));
}; };
window.WWebJS.mediaInfoToFile = ({ data, mimetype, filename }) => { window.WWebJS.mediaInfoToFile = ({ data, mimetype, filename }) => {
const binaryData = atob(data); const binaryData = window.atob(data);
const buffer = new ArrayBuffer(binaryData.length); const buffer = new ArrayBuffer(binaryData.length);
const view = new Uint8Array(buffer); const view = new Uint8Array(buffer);
@@ -431,15 +471,15 @@ exports.LoadUtils = () => {
window.WWebJS.arrayBufferToBase64 = (arrayBuffer) => { window.WWebJS.arrayBufferToBase64 = (arrayBuffer) => {
let binary = ''; let binary = '';
const bytes = new Uint8Array( arrayBuffer ); const bytes = new Uint8Array(arrayBuffer);
const len = bytes.byteLength; const len = bytes.byteLength;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] ); binary += String.fromCharCode(bytes[i]);
} }
return window.btoa( binary ); return window.btoa(binary);
}; };
window.WWebJS.getFileHash = async (data) => { window.WWebJS.getFileHash = async (data) => {
let buffer = await data.arrayBuffer(); let buffer = await data.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer); const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
return btoa(String.fromCharCode(...new Uint8Array(hashBuffer))); return btoa(String.fromCharCode(...new Uint8Array(hashBuffer)));
@@ -449,7 +489,7 @@ exports.LoadUtils = () => {
var result = ''; var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length; var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) { for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength)); result += characters.charAt(Math.floor(Math.random() * charactersLength));
} }
return result; return result;
@@ -474,15 +514,18 @@ exports.LoadUtils = () => {
}; };
window.WWebJS.sendChatstate = async (state, chatId) => { window.WWebJS.sendChatstate = async (state, chatId) => {
if (window.Store.MDBackend) {
chatId = window.Store.WidFactory.createWid(chatId);
}
switch (state) { switch (state) {
case 'typing': case 'typing':
await window.Store.Wap.sendChatstateComposing(chatId); await window.Store.ChatState.sendChatStateComposing(chatId);
break; break;
case 'recording': case 'recording':
await window.Store.Wap.sendChatstateRecording(chatId); await window.Store.ChatState.sendChatStateRecording(chatId);
break; break;
case 'stop': case 'stop':
await window.Store.Wap.sendChatstatePaused(chatId); await window.Store.ChatState.sendChatStatePaused(chatId);
break; break;
default: default:
throw 'Invalid chatstate'; throw 'Invalid chatstate';
@@ -494,12 +537,12 @@ exports.LoadUtils = () => {
window.WWebJS.getLabelModel = label => { window.WWebJS.getLabelModel = label => {
let res = label.serialize(); let res = label.serialize();
res.hexColor = label.hexColor; res.hexColor = label.hexColor;
return res; return res;
}; };
window.WWebJS.getLabels = () => { window.WWebJS.getLabels = () => {
const labels = window.Store.Label.models; const labels = window.Store.Label.getModelsArray();
return labels.map(label => window.WWebJS.getLabelModel(label)); return labels.map(label => window.WWebJS.getLabelModel(label));
}; };
@@ -513,8 +556,9 @@ exports.LoadUtils = () => {
return (chat.labels || []).map(id => window.WWebJS.getLabel(id)); return (chat.labels || []).map(id => window.WWebJS.getLabel(id));
}; };
window.WWebJS.getOrderDetail = async (orderId, token) => { window.WWebJS.getOrderDetail = async (orderId, token, chatId) => {
return window.Store.QueryOrder.queryOrder(orderId, 80, 80, token); const chatWid = window.Store.WidFactory.createWid(chatId);
return window.Store.QueryOrder.queryOrder(chatWid, orderId, 80, 80, token);
}; };
window.WWebJS.getProductMetadata = async (productId) => { window.WWebJS.getProductMetadata = async (productId) => {
@@ -527,20 +571,3 @@ exports.LoadUtils = () => {
return undefined; return undefined;
}; };
}; };
exports.MarkAllRead = () => {
let Chats = window.Store.Chat.models;
for (let chatIndex in Chats) {
if (isNaN(chatIndex)) {
continue;
}
let chat = Chats[chatIndex];
if (chat.unreadCount > 0) {
chat.markSeen();
window.Store.Wap.sendConversationSeen(chat.id, chat.getLastMsgKeyForAction(), chat.unreadCount - chat.pendingSeenCount);
}
}
};

View File

@@ -1,6 +1,5 @@
'use strict'; 'use strict';
const sharp = require('sharp');
const path = require('path'); const path = require('path');
const Crypto = require('crypto'); const Crypto = require('crypto');
const { tmpdir } = require('os'); const { tmpdir } = require('os');
@@ -14,7 +13,6 @@ const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
* Utility methods * Utility methods
*/ */
class Util { class Util {
constructor() { constructor() {
throw new Error(`The ${this.constructor.name} class may not be instantiated.`); throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
} }
@@ -23,7 +21,7 @@ class Util {
var result = ''; var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length; var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) { for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength)); result += characters.charAt(Math.floor(Math.random() * charactersLength));
} }
return result; return result;
@@ -55,33 +53,19 @@ class Util {
* *
* @returns {Promise<MessageMedia>} media in webp format * @returns {Promise<MessageMedia>} media in webp format
*/ */
static async formatImageToWebpSticker(media) { static async formatImageToWebpSticker(media, pupPage) {
if (!media.mimetype.includes('image')) if (!media.mimetype.includes('image'))
throw new Error('media is not a image'); throw new Error('media is not a image');
if (media.mimetype.includes('webp')) { if (media.mimetype.includes('webp')) {
return media; return media;
} }
const buff = Buffer.from(media.data, 'base64'); return pupPage.evaluate((media) => {
return window.WWebJS.toStickerData(media);
let sharpImg = sharp(buff); }, media);
sharpImg = sharpImg.webp();
sharpImg = sharpImg.resize(512, 512, {
fit: 'contain',
background: { r: 0, g: 0, b: 0, alpha: 0 },
});
let webpBase64 = (await sharpImg.toBuffer()).toString('base64');
return {
mimetype: 'image/webp',
data: webpBase64,
filename: media.filename,
};
} }
/** /**
* Formats a video to webp * Formats a video to webp
* @param {MessageMedia} media * @param {MessageMedia} media
@@ -91,14 +75,14 @@ class Util {
static async formatVideoToWebpSticker(media) { static async formatVideoToWebpSticker(media) {
if (!media.mimetype.includes('video')) if (!media.mimetype.includes('video'))
throw new Error('media is not a video'); throw new Error('media is not a video');
const videoType = media.mimetype.split('/')[1]; const videoType = media.mimetype.split('/')[1];
const tempFile = path.join( const tempFile = path.join(
tmpdir(), tmpdir(),
`${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp` `${Crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`
); );
const stream = new (require('stream').Readable)(); const stream = new (require('stream').Readable)();
const buffer = Buffer.from( const buffer = Buffer.from(
media.data.replace(`data:${media.mimetype};base64,`, ''), media.data.replace(`data:${media.mimetype};base64,`, ''),
@@ -135,17 +119,17 @@ class Util {
.toFormat('webp') .toFormat('webp')
.save(tempFile); .save(tempFile);
}); });
const data = await fs.readFile(tempFile, 'base64'); const data = await fs.readFile(tempFile, 'base64');
await fs.unlink(tempFile); await fs.unlink(tempFile);
return { return {
mimetype: 'image/webp', mimetype: 'image/webp',
data: data, data: data,
filename: media.filename, filename: media.filename,
}; };
} }
/** /**
* Sticker metadata. * Sticker metadata.
* @typedef {Object} StickerMetadata * @typedef {Object} StickerMetadata
@@ -161,14 +145,14 @@ class Util {
* *
* @returns {Promise<MessageMedia>} media in webp format * @returns {Promise<MessageMedia>} media in webp format
*/ */
static async formatToWebpSticker(media, metadata) { static async formatToWebpSticker(media, metadata, pupPage) {
let webpMedia; let webpMedia;
if (media.mimetype.includes('image')) if (media.mimetype.includes('image'))
webpMedia = await this.formatImageToWebpSticker(media); webpMedia = await this.formatImageToWebpSticker(media, pupPage);
else if (media.mimetype.includes('video')) else if (media.mimetype.includes('video'))
webpMedia = await this.formatVideoToWebpSticker(media); webpMedia = await this.formatVideoToWebpSticker(media);
else else
throw new Error('Invalid media format'); throw new Error('Invalid media format');
if (metadata.name || metadata.author) { if (metadata.name || metadata.author) {

View File

@@ -3,8 +3,12 @@
These tests require an authenticated WhatsApp Web session, as well as an additional phone that you can send messages to. These tests require an authenticated WhatsApp Web session, as well as an additional phone that you can send messages to.
This can be configured using the following environment variables: This can be configured using the following environment variables:
- `WWEBJS_TEST_SESSION`: A JSON-formatted string with the session details. Must include `WABrowserId`, `WASecretBundle`, `WAToken1` and `WAToken2`. - `WWEBJS_TEST_SESSION`: A JSON-formatted string with legacy auth session details. Must include `WABrowserId`, `WASecretBundle`, `WAToken1` and `WAToken2`.
- `WWEBJS_TEST_SESSION_PATH`: Path to a JSON file that contains the session details. Must include `WABrowserId`, `WASecretBundle`, `WAToken1` and `WAToken2`. - `WWEBJS_TEST_SESSION_PATH`: Path to a JSON file that contains the legacy auth session details. Must include `WABrowserId`, `WASecretBundle`, `WAToken1` and `WAToken2`.
- `WWEBJS_TEST_CLIENT_ID`: `clientId` to use for local file based authentication.
- `WWEBJS_TEST_REMOTE_ID`: A valid WhatsApp ID that you can send messages to, e.g. `123456789@c.us`. It should be different from the ID used by the provided session. - `WWEBJS_TEST_REMOTE_ID`: A valid WhatsApp ID that you can send messages to, e.g. `123456789@c.us`. It should be different from the ID used by the provided session.
You *must* set `WWEBJS_TEST_REMOTE_ID` **and** either `WWEBJS_TEST_SESSION` or `WWEBJS_TEST_SESSION_PATH` for the tests to run properly. You *must* set `WWEBJS_TEST_REMOTE_ID` **and** either `WWEBJS_TEST_SESSION`, `WWEBJS_TEST_SESSION_PATH` or `WWEBJS_TEST_CLIENT_ID` for the tests to run properly.
### Multidevice
Some of the tested functionality depends on whether the account has multidevice enabled or not. If you are using multidevice, you should set `WWEBJS_TEST_MD=1`.

View File

@@ -1,4 +1,5 @@
const {expect} = require('chai'); const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const sinon = require('sinon'); const sinon = require('sinon');
const helper = require('./helper'); const helper = require('./helper');
@@ -7,9 +8,14 @@ const Contact = require('../src/structures/Contact');
const Message = require('../src/structures/Message'); const Message = require('../src/structures/Message');
const MessageMedia = require('../src/structures/MessageMedia'); const MessageMedia = require('../src/structures/MessageMedia');
const Location = require('../src/structures/Location'); const Location = require('../src/structures/Location');
const LegacySessionAuth = require('../src/authStrategies/LegacySessionAuth');
const { MessageTypes, WAState } = require('../src/util/Constants'); const { MessageTypes, WAState } = require('../src/util/Constants');
const expect = chai.expect;
chai.use(chaiAsPromised);
const remoteId = helper.remoteId; const remoteId = helper.remoteId;
const isMD = helper.isMD();
describe('Client', function() { describe('Client', function() {
describe('Authentication', function() { describe('Authentication', function() {
@@ -47,76 +53,6 @@ describe('Client', function() {
expect(disconnectedCallback.calledOnceWith('Max qrcode retries reached')).to.eql(true); expect(disconnectedCallback.calledOnceWith('Max qrcode retries reached')).to.eql(true);
}); });
it('should fail auth if session is invalid', async function() {
this.timeout(40000);
const authFailCallback = sinon.spy();
const qrCallback = sinon.spy();
const readyCallback = sinon.spy();
const client = helper.createClient({
options: {
session: {
WABrowserId: 'invalid',
WASecretBundle: 'invalid',
WAToken1: 'invalid',
WAToken2: 'invalid'
},
authTimeoutMs: 10000,
restartOnAuthFail: false
}
});
client.on('qr', qrCallback);
client.on('auth_failure', authFailCallback);
client.on('ready', readyCallback);
client.initialize();
await helper.sleep(25000);
expect(authFailCallback.called).to.equal(true);
expect(authFailCallback.args[0][0]).to.equal('Unable to log in. Are the session details valid?');
expect(readyCallback.called).to.equal(false);
expect(qrCallback.called).to.equal(false);
await client.destroy();
});
it('can restart without a session if session was invalid and restartOnAuthFail=true', async function() {
this.timeout(40000);
const authFailCallback = sinon.spy();
const qrCallback = sinon.spy();
const client = helper.createClient({
options:{
session: {
WABrowserId: 'invalid',
WASecretBundle: 'invalid',
WAToken1: 'invalid',
WAToken2: 'invalid'
},
authTimeoutMs: 10000,
restartOnAuthFail: true
}
});
client.on('auth_failure', authFailCallback);
client.on('qr', qrCallback);
client.initialize();
await helper.sleep(35000);
expect(authFailCallback.called).to.equal(true);
expect(qrCallback.called).to.equal(true);
expect(qrCallback.args[0][0]).to.have.lengthOf(152);
await client.destroy();
});
it('should authenticate with existing session', async function() { it('should authenticate with existing session', async function() {
this.timeout(40000); this.timeout(40000);
@@ -124,7 +60,10 @@ describe('Client', function() {
const qrCallback = sinon.spy(); const qrCallback = sinon.spy();
const readyCallback = sinon.spy(); const readyCallback = sinon.spy();
const client = helper.createClient({withSession: true}); const client = helper.createClient({
authenticated: true,
});
client.on('qr', qrCallback); client.on('qr', qrCallback);
client.on('authenticated', authenticatedCallback); client.on('authenticated', authenticatedCallback);
client.on('ready', readyCallback); client.on('ready', readyCallback);
@@ -132,59 +71,139 @@ describe('Client', function() {
await client.initialize(); await client.initialize();
expect(authenticatedCallback.called).to.equal(true); expect(authenticatedCallback.called).to.equal(true);
const newSession = authenticatedCallback.args[0][0];
expect(newSession).to.have.key([ if(helper.isUsingLegacySession()) {
'WABrowserId', const newSession = authenticatedCallback.args[0][0];
'WASecretBundle', expect(newSession).to.have.key([
'WAToken1', 'WABrowserId',
'WAToken2' 'WASecretBundle',
]); 'WAToken1',
expect(authenticatedCallback.called).to.equal(true); 'WAToken2'
]);
}
expect(readyCallback.called).to.equal(true); expect(readyCallback.called).to.equal(true);
expect(qrCallback.called).to.equal(false); expect(qrCallback.called).to.equal(false);
await client.destroy(); await client.destroy();
});
it('can take over if client was logged in somewhere else with takeoverOnConflict=true', async function() {
this.timeout(40000);
const readyCallback1 = sinon.spy();
const readyCallback2 = sinon.spy();
const disconnectedCallback1 = sinon.spy();
const disconnectedCallback2 = sinon.spy();
const client1 = helper.createClient({
withSession: true,
options: { takeoverOnConflict: true, takeoverTimeoutMs: 5000 }
});
const client2 = helper.createClient({withSession: true});
client1.on('ready', readyCallback1);
client2.on('ready', readyCallback2);
client1.on('disconnected', disconnectedCallback1);
client2.on('disconnected', disconnectedCallback2);
await client1.initialize();
expect(readyCallback1.called).to.equal(true);
expect(readyCallback2.called).to.equal(false);
expect(disconnectedCallback1.called).to.equal(false);
expect(disconnectedCallback2.called).to.equal(false);
await client2.initialize();
expect(readyCallback2.called).to.equal(true);
expect(disconnectedCallback1.called).to.equal(false);
expect(disconnectedCallback2.called).to.equal(false);
// wait for takeoverTimeoutMs to kick in
await helper.sleep(5200);
expect(disconnectedCallback1.called).to.equal(false);
expect(disconnectedCallback2.called).to.equal(true);
expect(disconnectedCallback2.calledWith(WAState.CONFLICT)).to.equal(true);
await client1.destroy();
}); });
describe('LegacySessionAuth', function () {
it('should fail auth if session is invalid', async function() {
this.timeout(40000);
const authFailCallback = sinon.spy();
const qrCallback = sinon.spy();
const readyCallback = sinon.spy();
const client = helper.createClient({
options: {
authStrategy: new LegacySessionAuth({
session: {
WABrowserId: 'invalid',
WASecretBundle: 'invalid',
WAToken1: 'invalid',
WAToken2: 'invalid'
},
restartOnAuthFail: false,
}),
}
});
client.on('qr', qrCallback);
client.on('auth_failure', authFailCallback);
client.on('ready', readyCallback);
client.initialize();
await helper.sleep(25000);
expect(authFailCallback.called).to.equal(true);
expect(authFailCallback.args[0][0]).to.equal('Unable to log in. Are the session details valid?');
expect(readyCallback.called).to.equal(false);
expect(qrCallback.called).to.equal(false);
await client.destroy();
});
it('can restart without a session if session was invalid and restartOnAuthFail=true', async function() {
this.timeout(40000);
const authFailCallback = sinon.spy();
const qrCallback = sinon.spy();
const client = helper.createClient({
options: {
authStrategy: new LegacySessionAuth({
session: {
WABrowserId: 'invalid',
WASecretBundle: 'invalid',
WAToken1: 'invalid',
WAToken2: 'invalid'
},
restartOnAuthFail: true,
}),
}
});
client.on('auth_failure', authFailCallback);
client.on('qr', qrCallback);
client.initialize();
await helper.sleep(35000);
expect(authFailCallback.called).to.equal(true);
expect(qrCallback.called).to.equal(true);
expect(qrCallback.args[0][0]).to.have.lengthOf(152);
await client.destroy();
});
});
describe('Non-MD only', function () {
if(!isMD) {
it('can take over if client was logged in somewhere else with takeoverOnConflict=true', async function() {
this.timeout(40000);
const readyCallback1 = sinon.spy();
const readyCallback2 = sinon.spy();
const disconnectedCallback1 = sinon.spy();
const disconnectedCallback2 = sinon.spy();
const client1 = helper.createClient({
authenticated: true,
options: { takeoverOnConflict: true, takeoverTimeoutMs: 5000 }
});
const client2 = helper.createClient({authenticated: true});
client1.on('ready', readyCallback1);
client2.on('ready', readyCallback2);
client1.on('disconnected', disconnectedCallback1);
client2.on('disconnected', disconnectedCallback2);
await client1.initialize();
expect(readyCallback1.called).to.equal(true);
expect(readyCallback2.called).to.equal(false);
expect(disconnectedCallback1.called).to.equal(false);
expect(disconnectedCallback2.called).to.equal(false);
await client2.initialize();
expect(readyCallback2.called).to.equal(true);
expect(disconnectedCallback1.called).to.equal(false);
expect(disconnectedCallback2.called).to.equal(false);
// wait for takeoverTimeoutMs to kick in
await helper.sleep(5200);
expect(disconnectedCallback1.called).to.equal(false);
expect(disconnectedCallback2.called).to.equal(true);
expect(disconnectedCallback2.calledWith(WAState.CONFLICT)).to.equal(true);
await client1.destroy();
});
}
});
}); });
describe('Authenticated', function() { describe('Authenticated', function() {
@@ -192,7 +211,7 @@ describe('Client', function() {
before(async function() { before(async function() {
this.timeout(35000); this.timeout(35000);
client = helper.createClient({withSession: true}); client = helper.createClient({authenticated: true});
await client.initialize(); await client.initialize();
}); });
@@ -221,35 +240,46 @@ describe('Client', function() {
'BlockContact', 'BlockContact',
'Call', 'Call',
'Chat', 'Chat',
'ChatState',
'Cmd', 'Cmd',
'Conn', 'Conn',
'Contact', 'Contact',
'DownloadManager', 'DownloadManager',
'Features', 'Features',
'GroupMetadata', 'GroupMetadata',
'GroupParticipants',
'GroupUtils',
'Invite', 'Invite',
'InviteInfo',
'JoinInviteV4',
'Label', 'Label',
'MediaObject', 'MediaObject',
'MediaPrep', 'MediaPrep',
'MediaTypes', 'MediaTypes',
'MediaUpload', 'MediaUpload',
'MessageInfo',
'Msg', 'Msg',
'MsgKey', 'MsgKey',
'OpaqueData', 'OpaqueData',
'QueryOrder', 'QueryOrder',
'QueryProduct', 'QueryProduct',
'PresenceUtils',
'QueryExist',
'QueryProduct',
'QueryOrder',
'SendClear', 'SendClear',
'SendDelete', 'SendDelete',
'SendMessage', 'SendMessage',
'SendSeen', 'SendSeen',
'Sticker', 'StatusUtils',
'UploadUtils', 'UploadUtils',
'UserConstructor', 'UserConstructor',
'VCard', 'VCard',
'Validators', 'Validators',
'Wap', 'Wap',
'WidFactory', 'WidFactory',
'genId' 'findCommonGroups',
'ProfilePic',
]; ];
const loadedModules = await client.pupPage.evaluate((expectedModules) => { const loadedModules = await client.pupPage.evaluate((expectedModules) => {
@@ -535,8 +565,6 @@ END:VCARD`;
describe('Search messages', function () { describe('Search messages', function () {
it('can search for messages', async function () { it('can search for messages', async function () {
this.timeout(5000);
const m1 = await client.sendMessage(remoteId, 'I\'m searching for Super Mario Brothers'); const m1 = await client.sendMessage(remoteId, 'I\'m searching for Super Mario Brothers');
const m2 = await client.sendMessage(remoteId, 'This also contains Mario'); const m2 = await client.sendMessage(remoteId, 'This also contains Mario');
const m3 = await client.sendMessage(remoteId, 'Nothing of interest here, just Luigi'); const m3 = await client.sendMessage(remoteId, 'Nothing of interest here, just Luigi');
@@ -581,4 +609,4 @@ END:VCARD`;
}); });
}); });
}); });
}); });

View File

@@ -1,13 +1,24 @@
const path = require('path'); const path = require('path');
const Client = require('../src/Client'); const { Client, LegacySessionAuth, LocalAuth } = require('..');
const Util = require('../src/util/Util');
require('dotenv').config(); require('dotenv').config();
const remoteId = process.env.WWEBJS_TEST_REMOTE_ID; const remoteId = process.env.WWEBJS_TEST_REMOTE_ID;
if(!remoteId) throw new Error('The WWEBJS_TEST_REMOTE_ID environment variable has not been set.'); if(!remoteId) throw new Error('The WWEBJS_TEST_REMOTE_ID environment variable has not been set.');
function isUsingLegacySession() {
return Boolean(process.env.WWEBJS_TEST_SESSION || process.env.WWEBJS_TEST_SESSION_PATH);
}
function isMD() {
return Boolean(process.env.WWEBJS_TEST_MD);
}
if(isUsingLegacySession() && isMD()) throw 'Cannot use legacy sessions with WWEBJS_TEST_MD=true';
function getSessionFromEnv() { function getSessionFromEnv() {
if (!isUsingLegacySession()) return null;
const envSession = process.env.WWEBJS_TEST_SESSION; const envSession = process.env.WWEBJS_TEST_SESSION;
if(envSession) return JSON.parse(envSession); if(envSession) return JSON.parse(envSession);
@@ -16,17 +27,28 @@ function getSessionFromEnv() {
const absPath = path.resolve(process.cwd(), envSessionPath); const absPath = path.resolve(process.cwd(), envSessionPath);
return require(absPath); return require(absPath);
} }
throw new Error('No session found in environment.');
} }
function createClient({withSession, options: additionalOpts}={}) { function createClient({authenticated, options: additionalOpts}={}) {
const options = {}; const options = {};
if(withSession) {
options.session = getSessionFromEnv(); if(authenticated) {
const legacySession = getSessionFromEnv();
if(legacySession) {
options.authStrategy = new LegacySessionAuth({
session: legacySession
});
} else {
const clientId = process.env.WWEBJS_TEST_CLIENT_ID;
if(!clientId) throw new Error('No session found in environment.');
options.authStrategy = new LocalAuth({
clientId
});
}
} }
return new Client(Util.mergeDefault(options, additionalOpts || {})); const allOpts = {...options, ...(additionalOpts || {})};
return new Client(allOpts);
} }
function sleep(ms) { function sleep(ms) {
@@ -36,5 +58,7 @@ function sleep(ms) {
module.exports = { module.exports = {
sleep, sleep,
createClient, createClient,
remoteId isUsingLegacySession,
isMD,
remoteId,
}; };

View File

@@ -13,7 +13,7 @@ describe('Chat', function () {
before(async function() { before(async function() {
this.timeout(35000); this.timeout(35000);
client = helper.createClient({ withSession: true }); client = helper.createClient({ authenticated: true });
await client.initialize(); await client.initialize();
chat = await client.getChatById(remoteId); chat = await client.getChatById(remoteId);
}); });
@@ -32,9 +32,9 @@ describe('Chat', function () {
}); });
it('can fetch messages sent in a chat', async function () { it('can fetch messages sent in a chat', async function () {
this.timeout(5000);
await helper.sleep(1000); await helper.sleep(1000);
const msg = await chat.sendMessage('another message'); const msg = await chat.sendMessage('another message');
await helper.sleep(500);
const messages = await chat.fetchMessages(); const messages = await chat.fetchMessages();
expect(messages.length).to.be.greaterThanOrEqual(2); expect(messages.length).to.be.greaterThanOrEqual(2);
@@ -49,6 +49,7 @@ describe('Chat', function () {
it('can use a limit when fetching messages sent in a chat', async function () { it('can use a limit when fetching messages sent in a chat', async function () {
await helper.sleep(1000); await helper.sleep(1000);
const msg = await chat.sendMessage('yet another message'); const msg = await chat.sendMessage('yet another message');
await helper.sleep(500);
const messages = await chat.fetchMessages({limit: 1}); const messages = await chat.fetchMessages({limit: 1});
expect(messages).to.have.lengthOf(1); expect(messages).to.have.lengthOf(1);
@@ -80,6 +81,8 @@ describe('Chat', function () {
const res = await chat.sendSeen(); const res = await chat.sendSeen();
expect(res).to.equal(true); expect(res).to.equal(true);
await helper.sleep(1000);
// refresh chat // refresh chat
chat = await client.getChatById(remoteId); chat = await client.getChatById(remoteId);
expect(chat.unreadCount).to.equal(0); expect(chat.unreadCount).to.equal(0);
@@ -137,6 +140,8 @@ describe('Chat', function () {
it('can mute a chat forever', async function() { it('can mute a chat forever', async function() {
await chat.mute(); await chat.mute();
await helper.sleep(1000);
// refresh chat // refresh chat
chat = await client.getChatById(remoteId); chat = await client.getChatById(remoteId);
expect(chat.isMuted).to.equal(true); expect(chat.isMuted).to.equal(true);
@@ -147,6 +152,8 @@ describe('Chat', function () {
const unmuteDate = new Date(new Date().getTime() + (1000*60*60)); const unmuteDate = new Date(new Date().getTime() + (1000*60*60));
await chat.mute(unmuteDate); await chat.mute(unmuteDate);
await helper.sleep(1000);
// refresh chat // refresh chat
chat = await client.getChatById(remoteId); chat = await client.getChatById(remoteId);
expect(chat.isMuted).to.equal(true); expect(chat.isMuted).to.equal(true);
@@ -168,9 +175,7 @@ describe('Chat', function () {
// eslint-disable-next-line mocha/no-skipped-tests // eslint-disable-next-line mocha/no-skipped-tests
describe.skip('Destructive operations', function () { describe.skip('Destructive operations', function () {
it('can clear all messages from chat', async function () { it('can clear all messages from chat', async function () {
this.timeout(5000);
const res = await chat.clearMessages(); const res = await chat.clearMessages();
expect(res).to.equal(true); expect(res).to.equal(true);

227
tests/structures/group.js Normal file
View File

@@ -0,0 +1,227 @@
const { expect } = require('chai');
const helper = require('../helper');
const remoteId = helper.remoteId;
describe('Group', function() {
let client;
let group;
before(async function() {
this.timeout(35000);
client = helper.createClient({
authenticated: true,
});
await client.initialize();
const createRes = await client.createGroup('My Awesome Group', [remoteId]);
expect(createRes.gid).to.exist;
await helper.sleep(500);
group = await client.getChatById(createRes.gid._serialized);
expect(group).to.exist;
});
beforeEach(async function () {
await helper.sleep(500);
});
describe('Settings', function () {
it('can change the group subject', async function () {
expect(group.name).to.equal('My Awesome Group');
const res = await group.setSubject('My Amazing Group');
expect(res).to.equal(true);
await helper.sleep(1000);
// reload
group = await client.getChatById(group.id._serialized);
expect(group.name).to.equal('My Amazing Group');
});
it('can change the group description', async function () {
expect(group.description).to.equal(undefined);
const res = await group.setDescription('some description');
expect(res).to.equal(true);
expect(group.description).to.equal('some description');
await helper.sleep(1000);
// reload
group = await client.getChatById(group.id._serialized);
expect(group.description).to.equal('some description');
});
it('can set only admins able to send messages', async function () {
expect(group.groupMetadata.announce).to.equal(false);
const res = await group.setMessagesAdminsOnly();
expect(res).to.equal(true);
expect(group.groupMetadata.announce).to.equal(true);
await helper.sleep(1000);
// reload
group = await client.getChatById(group.id._serialized);
expect(group.groupMetadata.announce).to.equal(true);
});
it('can set all participants able to send messages', async function () {
expect(group.groupMetadata.announce).to.equal(true);
const res = await group.setMessagesAdminsOnly(false);
expect(res).to.equal(true);
expect(group.groupMetadata.announce).to.equal(false);
await helper.sleep(1000);
// reload
group = await client.getChatById(group.id._serialized);
expect(group.groupMetadata.announce).to.equal(false);
});
it('can set only admins able to set group info', async function () {
expect(group.groupMetadata.restrict).to.equal(false);
const res = await group.setInfoAdminsOnly();
expect(res).to.equal(true);
expect(group.groupMetadata.restrict).to.equal(true);
await helper.sleep(1000);
// reload
group = await client.getChatById(group.id._serialized);
expect(group.groupMetadata.restrict).to.equal(true);
});
it('can set all participants able to set group info', async function () {
expect(group.groupMetadata.restrict).to.equal(true);
const res = await group.setInfoAdminsOnly(false);
expect(res).to.equal(true);
expect(group.groupMetadata.restrict).to.equal(false);
await helper.sleep(1000);
// reload
group = await client.getChatById(group.id._serialized);
expect(group.groupMetadata.restrict).to.equal(false);
});
});
describe('Invites', function () {
it('can get the invite code', async function () {
const code = await group.getInviteCode();
expect(typeof code).to.equal('string');
});
it('can get invite info', async function () {
const code = await group.getInviteCode();
const info = await client.getInviteInfo(code);
expect(info.id._serialized).to.equal(group.id._serialized);
expect(info.participants.length).to.equal(2);
});
it('can revoke the invite code', async function () {
const code = await group.getInviteCode();
const newCode = await group.revokeInvite();
expect(typeof newCode).to.equal('string');
expect(newCode).to.not.equal(code);
});
});
describe('Participants', function () {
it('can promote a user to admin', async function () {
let participant = group.participants.find(p => p.id._serialized === remoteId);
expect(participant).to.exist;
expect(participant.isAdmin).to.equal(false);
const res = await group.promoteParticipants([remoteId]);
expect(res.status).to.be.greaterThanOrEqual(200);
await helper.sleep(1000);
// reload and check
group = await client.getChatById(group.id._serialized);
participant = group.participants.find(p => p.id._serialized=== remoteId);
expect(participant).to.exist;
expect(participant.isAdmin).to.equal(true);
});
it('can demote a user', async function () {
let participant = group.participants.find(p => p.id._serialized=== remoteId);
expect(participant).to.exist;
expect(participant.isAdmin).to.equal(true);
const res = await group.demoteParticipants([remoteId]);
expect(res.status).to.be.greaterThanOrEqual(200);
await helper.sleep(1000);
// reload and check
group = await client.getChatById(group.id._serialized);
participant = group.participants.find(p => p.id._serialized=== remoteId);
expect(participant).to.exist;
expect(participant.isAdmin).to.equal(false);
});
it('can remove a user from the group', async function () {
let participant = group.participants.find(p => p.id._serialized=== remoteId);
expect(participant).to.exist;
const res = await group.removeParticipants([remoteId]);
expect(res.status).to.be.greaterThanOrEqual(200);
await helper.sleep(1000);
// reload and check
group = await client.getChatById(group.id._serialized);
participant = group.participants.find(p => p.id._serialized=== remoteId);
expect(participant).to.not.exist;
});
it('can add back a user to the group', async function () {
let participant = group.participants.find(p => p.id._serialized=== remoteId);
expect(participant).to.not.exist;
const res = await group.addParticipants([remoteId]);
expect(res.status).to.be.greaterThanOrEqual(200);
await helper.sleep(1000);
// reload and check
group = await client.getChatById(group.id._serialized);
participant = group.participants.find(p => p.id._serialized=== remoteId);
expect(participant).to.exist;
});
});
describe('Leave / re-join', function () {
let code;
before(async function () {
code = await group.getInviteCode();
});
it('can leave the group', async function () {
expect(group.isReadOnly).to.equal(false);
await group.leave();
await helper.sleep(1000);
// reload and check
group = await client.getChatById(group.id._serialized);
expect(group.isReadOnly).to.equal(true);
});
it('can join a group via invite code', async function () {
const chatId = await client.acceptInvite(code);
expect(chatId).to.equal(group.id._serialized);
await helper.sleep(1000);
// reload and check
group = await client.getChatById(group.id._serialized);
expect(group.isReadOnly).to.equal(false);
});
});
after(async function () {
await client.destroy();
});
});

112
tests/structures/message.js Normal file
View File

@@ -0,0 +1,112 @@
const { expect } = require('chai');
const sinon = require('sinon');
const helper = require('../helper');
const { Contact, Chat } = require('../../src/structures');
const remoteId = helper.remoteId;
describe('Message', function () {
let client;
let chat;
let message;
before(async function() {
this.timeout(35000);
client = helper.createClient({ authenticated: true });
await client.initialize();
chat = await client.getChatById(remoteId);
message = await chat.sendMessage('this is only a test');
// wait for message to be sent
await helper.sleep(1000);
});
after(async function () {
await client.destroy();
});
it('can get the related chat', async function () {
const chat = await message.getChat();
expect(chat).to.be.instanceOf(Chat);
expect(chat.id._serialized).to.equal(remoteId);
});
it('can get the related contact', async function () {
const contact = await message.getContact();
expect(contact).to.be.instanceOf(Contact);
expect(contact.id._serialized).to.equal(client.info.wid._serialized);
});
it('can get message info', async function () {
const info = await message.getInfo();
expect(typeof info).to.equal('object');
expect(Array.isArray(info.played)).to.equal(true);
expect(Array.isArray(info.read)).to.equal(true);
expect(Array.isArray(info.delivery)).to.equal(true);
});
describe('Replies', function () {
let replyMsg;
it('can reply to a message', async function () {
replyMsg = await message.reply('this is my reply');
expect(replyMsg.hasQuotedMsg).to.equal(true);
});
it('can get the quoted message', async function () {
const quotedMsg = await replyMsg.getQuotedMessage();
expect(quotedMsg.id._serialized).to.equal(message.id._serialized);
});
});
describe('Star', function () {
it('can star a message', async function () {
expect(message.isStarred).to.equal(false);
await message.star();
// reload and check
await message.reload();
expect(message.isStarred).to.equal(true);
});
it('can un-star a message', async function () {
expect(message.isStarred).to.equal(true);
await message.unstar();
// reload and check
await message.reload();
expect(message.isStarred).to.equal(false);
});
});
describe('Delete', function () {
it('can delete a message for me', async function () {
await message.delete();
await helper.sleep(1000);
expect(await message.reload()).to.equal(null);
});
it('can delete a message for everyone', async function () {
message = await chat.sendMessage('sneaky message');
await helper.sleep(1000);
const callback = sinon.spy();
client.once('message_revoke_everyone', callback);
await message.delete(true);
await helper.sleep(1000);
expect(await message.reload()).to.equal(null);
expect(callback.called).to.equal(true);
const [ revokeMsg, originalMsg ] = callback.args[0];
expect(revokeMsg.id._serialized).to.equal(originalMsg.id._serialized);
expect(originalMsg.body).to.equal('sneaky message');
expect(originalMsg.type).to.equal('chat');
expect(revokeMsg.body).to.equal('');
expect(revokeMsg.type).to.equal('revoked');
});
});
});

View File

@@ -1 +1 @@
2.2202.12 2.2220.8