Compare commits

...

92 Commits

Author SHA1 Message Date
Pedro Lopez
539849732c chore: mark version v1.2.1 2020-03-13 17:46:39 -04:00
Pedro Lopez
4fe7fa93b9 fix: delegate all event handlers
Attaching these events directly to puppeteer functions apparently blocks and causes CPU usage to go up, slowing everything down.

related #88, 8bdecad
2020-03-13 17:44:20 -04:00
Pedro Lopez
2820d3e72a chore: bump version to v1.2.2-post 2020-03-13 00:18:30 -04:00
Pedro Lopez
cde5719bb6 chrore: mark version v1.2.2 2020-03-13 00:13:46 -04:00
Pedro Lopez
8bdecadba4 fix: don't call event handler for new messages directly to puppeteer
This was creating performance issues, specially on startup when the initial set of messages were being loaded for a client with many chats.
2020-03-13 00:09:43 -04:00
Pedro Lopez
b41414cfbf chore: bump version to 1.2.1-post 2020-03-05 21:23:48 -04:00
Pedro Lopez
c61f447a93 chore: mark version v1.2.1 2020-03-05 21:20:53 -04:00
Pedro Lopez
49aacec4a7 fix: correctly splice and merge fetched messages
This was eliminating messages in the middle of the array instead of eliminating older messages to reach the specified limit.

close #97
2020-03-05 21:18:10 -04:00
Pedro S. Lopez
d7a3e1a9a3 chore: update supported whatsapp web version 2020-03-02 23:57:24 -04:00
Pedro Lopez
e14b49c5df chore: bump version to v1.2.0-post 2020-03-01 15:14:06 -04:00
Pedro Lopez
f34902dfdd chore: mark version v1.2.0 2020-03-01 15:00:15 -04:00
Pedro Lopez
6e76fece91 docs: add jsdoc strings for group events 2020-03-01 14:58:06 -04:00
sahalMoidu
98458f760e feat : send conversation seen (#66)
After this commit, chats will be automatically marked as seen when a message is sent to it. If this is not the intended behavior, `sendSeen: false` can be set as part of the options object. 

You can also manually mark a conversation as seen by calling the sendSeen() function on the Chat.

Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2020-03-01 14:42:35 -04:00
Aliyss Snow
48b9ae1e81 feat: listen to group events (#90)
This allows you to listen for user joins or leaves, description updates, subject updates, picture updates, and group settings updates.

Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2020-03-01 14:32:58 -04:00
Aliyss Snow
588dc93c17 chore: added index.js for structures (#91)
- Allows for a cleaner integration (imo) in Client.js
2020-03-01 13:59:09 -04:00
Pedro Lopez
16fe865a9c feat: fetch chat messages
This will automatically fetch messages until it reaches the specified limit or there are no more messages. In the future, this should be extended to fetch messages before, after or around a specific message/date by adding props to the searchOptions object.

close #51
2020-02-29 16:01:13 -04:00
Pedro Lopez
b07b38bbe8 feat: Simulate recording audio in chat, clear recording/typing state, standardize chatstate change function names 2020-02-29 14:07:47 -04:00
Anderson de Oliveira Machado
d35f101fac feat: send typing in chat (#87)
Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2020-02-29 13:55:27 -04:00
Gabriel
72441beb37 feat(example): better sesion data save (#79)
For more consistency whenever I have a successful authentication I write
to the json file the session data
2020-02-28 17:02:10 -04:00
Jan Vlach
794c9e16fc feat: force state update (#77)
Whatsapp web will not update state until some action, this will force update client state.
First will set state to TIMEOUT, then to current state
2020-02-28 17:00:24 -04:00
Pedro Lopez
05f57d2f39 chore: bump version to v1.1.0-post 2020-02-26 23:50:55 -04:00
Pedro Lopez
130da046f5 chore: mark version v1.1.0 2020-02-26 23:34:01 -04:00
Pedro Lopez
bb40218c66 docs: use MessageAck type 2020-02-26 23:33:11 -04:00
Pedro S. Lopez
ad3834e575 Update MessageAck constant for consistancy 2020-02-26 23:31:10 -04:00
Pedro Lopez
e6ef5929fc added ack constants and brief example 2020-02-26 23:18:09 -04:00
João Vitor Miranda
bb4ad11bfa feat: added ACK events (#73)
Implements ack change detection, making it possible to know when messages have been delivered, read, etc.

Co-authored-by: Pedro S. Lopez <pedroslopez@me.com>
2020-02-26 22:59:46 -04:00
Pedro Lopez
1ebaf56617 Merge branch 'master' of https://github.com/pedroslopez/whatsapp-web.js 2020-02-26 00:40:51 -04:00
Pedro Lopez
60ee2ca522 feat: delete chat, clear chat 2020-02-26 00:39:33 -04:00
Aliyss Snow
132424ea08 feat: archive chats (#63) 2020-02-25 20:06:46 -04:00
sahalMoidu
5c9e76e23f feat: refresh qr code (#68)
close #60
2020-02-23 12:20:11 -04:00
Pedro S. Lopez
37932d9a69 Update README.md 2020-02-22 17:43:57 -04:00
Pedro Lopez
3c500a6474 Merge branch 'master' of https://github.com/pedroslopez/whatsapp-web.js 2020-02-22 17:28:15 -04:00
Pedro Lopez
1c60c83e80 feat: Delete messages 2020-02-22 17:28:03 -04:00
Pedro S. Lopez
69d7b3e50b update supported whatsapp web version 2020-02-22 16:12:13 -04:00
Pedro S. Lopez
0b1f06a932 update supported whatsapp web version 2020-02-22 16:11:51 -04:00
sahalMoidu
1840826e2b feat : Check if the given number is a whatsapp number (#54)
* feat : Check if the given number is a whatsapp number

- Avoids sending message to non whatsapp number
- Gets the id of the user from whatsapp server rather than generating on client
2020-02-17 09:10:07 -04:00
sahalMoidu
6ade08e814 Implemented changes mentioned in SimiPrambos PR#28 (#52)
* Implemented changes mentioned in SimiPrambos PR#28
To reflect new code structure
2020-02-14 17:53:28 -04:00
Pedro S. Lopez
9891d85b35 Update README.md 2020-02-13 20:10:51 -04:00
Pedro Lopez
67784bc797 feat: get current connection state
Note: This only partly works, since the state may not be updated on WhatsApp's end. In the case of not being able to reach the phone, the state is only updated when the user performs an action, such as sending a message. This means that the state may be CONNECTED when we check, but the phone's really not connected.

ref #43
2020-02-11 22:26:33 -04:00
Fernando Cardoso
e385563883 Initialize the Script with the first browser tab (#47)
Suggestion for the script to start under the first tab of the browser, in order to reduce memory consumption.
2020-02-11 13:53:18 -04:00
Pedro Lopez
d5a26add20 chore: bump version v1.0.2-post 2020-02-10 21:56:21 -04:00
Pedro Lopez
4bc67b0f99 chore: mark version v1.0.2 2020-02-10 21:53:33 -04:00
Pedro Lopez
d44fd5d76a new event on connection state changed 2020-02-10 21:51:58 -04:00
Pedro Lopez
a293146ed8 fix: added timeout to accepted states
This makes the client more reliable since it doesn't quit as soon as it looses conection from the phone for a second. Messages should be queued by WhatsApp Web.
2020-02-10 21:44:56 -04:00
Pedro Lopez
3c774d6553 chore: bump version to v1.0.1-post 2020-02-09 21:35:47 -04:00
Pedro Lopez
dd0a4c6cc3 chore: mark version v1.0.1 2020-02-09 21:33:27 -04:00
Pedro Lopez
ffe803306e fix: send message media
In some cases, the mediaBlob was not resolved correctly

ref: #38
2020-02-09 21:30:28 -04:00
Pedro Lopez
74cfc69367 fix location example 2020-02-09 20:10:56 -04:00
Pedro Lopez
2607e6df3a fix: send message media in options object
An inconsistency in variable names was preventing media sent through the options object from being processed
2020-02-09 02:49:21 -04:00
Pedro Lopez
5fbd8ddf68 feat(example): auto restore session
This is as suggested in #29. Mainly implemeted to ease work while developing, but also serves as an example.
2020-02-09 01:52:38 -04:00
Pedro Lopez
6f44fc586b chore: mark post release 2020-02-09 01:16:28 -04:00
Pedro Lopez
7deef27800 chore: mark version v1.0.0 2020-02-09 00:58:10 -04:00
Pedro Lopez
f947f75725 docs: add location to supported content types 2020-02-09 00:53:43 -04:00
Pedro Lopez
d1dba0f4c0 add disconnect reason 2020-02-09 00:53:00 -04:00
Pedro Lopez
64ed2c125b more message types 2020-02-09 00:46:00 -04:00
Pedro Lopez
5616613807 feat: Mention users, get user number from Contact model 2020-02-08 03:19:51 -04:00
Pedro Lopez
ef80f966ea fix: correctly get message contact in group chats 2020-02-08 03:18:32 -04:00
Pedro Lopez
edc2c7022d feat: change status message 2020-02-08 01:32:15 -04:00
Pedro Lopez
f2b286a319 feat: get contact's profile picture 2020-02-08 01:23:29 -04:00
Pedro Lopez
004312a99f expose some more fields on contacts 2020-02-08 01:17:06 -04:00
Pedro Lopez
2896aeb382 fix some doc related stuff 2020-02-08 01:01:33 -04:00
Pedro Lopez
065a9212ba add another location example 2020-02-08 00:54:21 -04:00
Pedro Lopez
7b229a39a4 feat: Send and receive location 2020-02-08 00:46:55 -04:00
Aliyss Snow
4b1768450f Get Mentions (#35) 2020-02-06 15:47:46 -04:00
depfu[bot]
0cbc24fc6c Update puppeteer to version 2.1.1 (#36) 2020-02-06 11:51:11 -04:00
Pedro Lopez
a247b39f81 docs(readme): add whatsapp web version tested 2020-02-05 02:22:02 -04:00
Pedro Lopez
bf70eb1b87 docs: regenerate docs 2020-02-05 02:17:19 -04:00
Pedro Lopez
1ad9cac682 docs: better readme 2020-02-05 02:16:49 -04:00
Pedro Lopez
4c05e47027 mark post release 2020-02-05 01:43:11 -04:00
Pedro Lopez
62e264231d docs: add generated docs 2020-02-05 01:07:56 -04:00
Pedro Lopez
2f0480c80e docs: add more documentation 2020-02-04 23:04:51 -04:00
Pedro Lopez
a098d61b03 feat: send messages with attachments
close #3
2020-02-04 21:11:20 -04:00
Pedro Lopez
e717915f94 fix: don't get chat after accepting invite
This will now only return the chatId, since getting the chat at this point is unreliable.
2020-02-02 20:37:51 -04:00
Aliyss Snow
e2351db722 Added Contact Model (#34) 2020-02-02 19:08:36 -04:00
Aliyss Snow
b597e4a504 Added delete event message(#33)
* A hacky way of doing things but seems to work. Also after client restart.
2020-02-02 19:00:23 -04:00
Pedro S. Lopez
b99744afa2 Create lint.yml 2020-02-02 14:52:49 -04:00
Pedro Lopez
cc477f9545 Add eslint config and fix linting issues 2020-02-02 14:50:04 -04:00
Pedro Lopez
8eb461ed32 Update puppeteer to v2.1.0
This fixes the library not working on the latest versions of macOS
2020-02-02 13:53:33 -04:00
Pedro Lopez
7243240568 fix !quoteinfo example 2020-02-02 13:52:25 -04:00
Pedro Lopez
5b9413de5c [FIX] Expose Wap module
Setting group description and title did not work due to whatsapp no longer exposing it as it was previously.
2020-02-02 13:44:54 -04:00
Pedro Lopez
8ddf4c29be Add .editorconfig (close #25) 2020-02-02 13:33:08 -04:00
Pedro Lopez
caa8598ec1 [+] Join groups by invite code 2020-02-02 00:52:51 -04:00
Pedro Lopez
a6cc5e5bf2 [+] Get quoted message
[FIX] Properly reply to messages sent by the current user
2020-02-01 22:41:53 -04:00
Pedro S. Lopez
ba8edc8d40 [+] Expose information about the logged in client (#19) 2020-02-01 21:16:03 -04:00
Pedro Lopez
88c56b1371 Return new message after sending 2020-02-01 19:34:28 -04:00
Pedro S. Lopez
2a3f404244 Merge pull request #32 from gabriel-tandil/master
Improvement in KEEP_PHONE_CONNECTED_IMG_SELECTOR
2020-01-31 19:54:46 -04:00
Gabriel Alvarez
d2889a8f03 Improvement in KEEP_PHONE_CONNECTED_IMG_SELECTOR
I change the selector from 'class' to 'attribute = value' to try to get
more permanent results
2020-01-31 16:17:58 -03:00
Pedro Lopez
3c55fbf2ca 0.3.2 2020-01-17 22:06:19 -04:00
Pedro Lopez
6b1b51eacd Increase successful connection timeout 2020-01-17 22:06:04 -04:00
Pedro Lopez
2dc53e0820 [FIX] Connection success detection selector changed
close #31
2020-01-17 22:05:05 -04:00
Pedro Lopez
9043e61c40 0.3.1 2019-12-04 03:00:04 -04:00
Pedro Lopez
bea1ebf480 [FIX] Get QR code directly from canvas element (fix #26) 2019-12-04 02:58:55 -04:00
67 changed files with 12859 additions and 229 deletions

8
.editorconfig Normal file
View File

@@ -0,0 +1,8 @@
root = true
[*]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false

34
.eslintrc.json Normal file
View File

@@ -0,0 +1,34 @@
{
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}

24
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: Lint
on:
push:
pull_request:
jobs:
eslint:
name: eslint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: install node v12
uses: actions/setup-node@v1
with:
node-version: 12
- name: npm install
run: npm install
- name: eslint
uses: icrawl/action-eslint@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
job-name: eslint

26
.jsdoc.json Normal file
View File

@@ -0,0 +1,26 @@
{
"tags": {
"allowUnknownTags": true,
"dictionaries": ["jsdoc"]
},
"source": {
"include": ["src", "package.json", "README.md"],
"includePattern": ".js$",
"excludePattern": "(node_modules/|docs)"
},
"plugins": [
"plugins/markdown"
],
"templates": {
"cleverLinks": false,
"monospaceLinks": true,
"useLongnameInNav": false,
"showInheritedInNav": true
},
"opts": {
"destination": "./docs/",
"encoding": "utf8",
"recurse": true,
"template": "./node_modules/jsdoc-baseline"
}
}

View File

@@ -1,4 +1,5 @@
[![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js)
[![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 0.4.1296](https://img.shields.io/badge/WhatsApp_Web-0.4.1296-brightgreen.svg)
# whatsapp-web.js
A WhatsApp API client that connects through the WhatsApp Web browser app
@@ -6,8 +7,70 @@ It uses Puppeteer to run a real instance of Whatsapp Web to avoid getting blocke
**NOTE:** I can't guarantee you will not be blocked by using this method, although it has worked for me. WhatsApp does not allow bots or unofficial clients on their platform, so this shouldn't be considered totally safe.
This is still very much a work in progress, but you can check out [example.js](./example.js) to see how to read and send messages.
## Installation
The module is now available on npm! `npm i whatsapp-web.js`
Please note that Node v8+ is required due to Puppeteer.
## Example usage
```js
const { Client } = require('whatsapp-web.js');
const client = new Client();
client.on('qr', (qr) => {
// Generate and scan this code with your phone
console.log('QR RECEIVED', qr);
});
client.on('ready', () => {
console.log('Client is ready!');
});
client.on('message', msg => {
if (msg.body == '!ping') {
msg.reply('pong');
}
});
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.
## Supported features
| Feature | Status |
| ------------- | ------------- |
| Send messages | ✅ |
| Receive messages | ✅ |
| Send media (images/audio/documents) | ✅ |
| Send media (video) | ✅ (requires google chrome) |
| Send stickers | _pending_ |
| Receive media (images/audio/video/documents) | ✅ |
| Send contact cards | _pending_ |
| Send location | ✅ |
| Receive location | ✅ |
| Message replies | ✅ |
| Join groups by invite | ✅ |
| Get invite for group | ✅ |
| Modify group info (subject, description) | ✅ |
| Add group participants | ✅ |
| Kick group participants | ✅ |
| Promote/demote group participants | ✅ |
| Mention users | ✅ |
| Get contact info | ✅ |
| Get profile pictures | ✅ |
| Set user status message | ✅ |
Something missing? Make an issue and let us know!
## Links
* [Documentation](https://pedroslopez.me/whatsapp-web.js) _(preview)_
* [GitHub](https://github.com/pedroslopez/whatsapp-web.js)
## Contributing
Pull requests are welcome! If you see something you'd like to add, please do. For drastic changes, please open an issue first.

BIN
docs/._Contact.html Normal file

Binary file not shown.

BIN
docs/._index.html Normal file

Binary file not shown.

65
docs/Base.html Normal file
View File

@@ -0,0 +1,65 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">Base</span></h1>
<p class="source-link">Source: <a href="structures_Base.js.html#source-line-7">structures/<wbr>Base.<wbr>js:7</a></p>
<div class="symbol-classdesc">
<p>Represents a WhatsApp data structure</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
</section>
<section>
<h2 id="Base">new&nbsp;<span class="symbol-name">Base</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.3 on March 13, 2020.
</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>

242
docs/BusinessContact.html Normal file
View File

@@ -0,0 +1,242 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">BusinessContact</span></h1>
<p class="source-link">Source: <a href="structures_BusinessContact.js.html#source-line-9">structures/<wbr>BusinessContact.<wbr>js:9</a></p>
<div class="symbol-classdesc">
<p>Represents a Business Contact on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="BusinessContact.html#businessProfile">businessProfile</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#id">id</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#isBusiness">isBusiness</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#isEnterprise">isEnterprise</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#isGroup">isGroup</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="BusinessContact.html#isMe">isMe</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#isMyContact">isMyContact</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#isUser">isUser</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#isWAContact">isWAContact</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#name">name</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="BusinessContact.html#number">number</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#pushname">pushname</a></dt>
<dd>
</dd>
<dt><a href="BusinessContact.html#shortName">shortName</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Method</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="BusinessContact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
</div>
<div class="summary-column">
</div>
</div>
</div>
</section>
<section>
<h2 id="BusinessContact">new&nbsp;<span class="symbol-name">BusinessContact</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Contact.html">Contact</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="businessProfile"><span class="symbol-name">businessProfile</span></h3>
<p>The contact's business profile</p>
<dl class="dl-compact">
</dl>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>ID that represents the contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#id">Contact#id</a></dd>
</dl>
<h3 id="isBusiness"><span class="symbol-name">isBusiness</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is a business contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isBusiness">Contact#isBusiness</a></dd>
</dl>
<h3 id="isEnterprise"><span class="symbol-name">isEnterprise</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is an enterprise contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isEnterprise">Contact#isEnterprise</a></dd>
</dl>
<h3 id="isGroup"><span class="symbol-name">isGroup</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is a group contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isGroup">Contact#isGroup</a></dd>
</dl>
<h3 id="isMe"><span class="symbol-name">isMe</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is the current user's contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isMe">Contact#isMe</a></dd>
</dl>
<h3 id="isMyContact"><span class="symbol-name">isMyContact</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the number is saved in the current phone's contacts</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isMyContact">Contact#isMyContact</a></dd>
</dl>
<h3 id="isUser"><span class="symbol-name">isUser</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is a user contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isUser">Contact#isUser</a></dd>
</dl>
<h3 id="isWAContact"><span class="symbol-name">isWAContact</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the number is registered on WhatsApp</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isWAContact">Contact#isWAContact</a></dd>
</dl>
<h3 id="name"><span class="symbol-name">name</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>The contact's name, as saved by the current user</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#name">Contact#name</a></dd>
</dl>
<h3 id="number"><span class="symbol-name">number</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Contact's phone number</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#number">Contact#number</a></dd>
</dl>
<h3 id="pushname"><span class="symbol-name">pushname</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>The name that the contact has configured to be shown publically</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#pushname">Contact#pushname</a></dd>
</dl>
<h3 id="shortName"><span class="symbol-name">shortName</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>A shortened version of name</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#shortName">Contact#shortName</a></dd>
</dl>
</section>
<h2>Method</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getProfilePicUrl"><span class="symbol-name">getProfilePicUrl</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 profile picture URL, if privacy settings allow it</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#getProfilePicUrl">Contact#getProfilePicUrl</a></dd>
<dt>Returns</dt>
<dd></dd>
</dl>
</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.3 on March 13, 2020.
</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>

365
docs/Chat.html Normal file
View File

@@ -0,0 +1,365 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">Chat</span></h1>
<p class="source-link">Source: <a href="structures_Chat.js.html#source-line-11">structures/<wbr>Chat.<wbr>js:11</a></p>
<div class="symbol-classdesc">
<p>Represents a Chat on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Chat.html#archived">archived</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#id">id</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#isGroup">isGroup</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Chat.html#isReadOnly">isReadOnly</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#name">name</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#timestamp">timestamp</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Chat.html#unreadCount">unreadCount</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Methods</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Chat.html#archive">archive()</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#clearMessages">clearMessages()</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#clearState">clearState()</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#delete">delete()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Chat.html#fetchMessages">fetchMessages(searchOptions)</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#sendMessage">sendMessage(content, options)</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#sendSeen">sendSeen()</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#sendStateRecording">sendStateRecording()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Chat.html#sendStateTyping">sendStateTyping()</a></dt>
<dd>
</dd>
<dt><a href="Chat.html#unarchive">unarchive()</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
</section>
<section>
<h2 id="Chat">new&nbsp;<span class="symbol-name">Chat</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Base.html">Base</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="archived"><span class="symbol-name">archived</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the Chat is archived</p>
<dl class="dl-compact">
</dl>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;object</small></h3>
<p>ID that represents the chat</p>
<dl class="dl-compact">
</dl>
<h3 id="isGroup"><span class="symbol-name">isGroup</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the Chat is a Group Chat</p>
<dl class="dl-compact">
</dl>
<h3 id="isReadOnly"><span class="symbol-name">isReadOnly</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the Chat is readonly</p>
<dl class="dl-compact">
</dl>
<h3 id="name"><span class="symbol-name">name</span><small class="property-type">
&nbsp;string</small></h3>
<p>Title of the chat</p>
<dl class="dl-compact">
</dl>
<h3 id="timestamp"><span class="symbol-name">timestamp</span><small class="property-type">
&nbsp;number</small></h3>
<p>Unix timestamp for when the chat was created</p>
<dl class="dl-compact">
</dl>
<h3 id="unreadCount"><span class="symbol-name">unreadCount</span><small class="property-type">
&nbsp;number</small></h3>
<p>Amount of messages unread</p>
<dl class="dl-compact">
</dl>
</section>
<h2>Methods</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="archive"><span class="symbol-name">archive</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Archives this chat</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="clearMessages"><span class="symbol-name">clearMessages</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Clears all messages from the chat</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Boolean</code> <p>result</p>
</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="clearState"><span class="symbol-name">clearState</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Stops typing or recording in chat immediately.</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="delete"><span class="symbol-name">delete</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Deletes the chat</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Boolean</code> <p>result</p>
</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="fetchMessages"><span class="symbol-name">fetchMessages</span><span class="signature"><span class="signature-params">(searchOptions)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of <a href="Message.html">Message</a></span></span></h3>
<p>Loads chat messages, sorted from earliest to latest.</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>searchOptions</p>
</td>
<td>
<p>Object</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Options for searching messages. Right now only limit is supported.</p>
<p>Values in <code>searchOptions</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>limit</p>
</td>
<td>
<p>Number</p>
</td>
<td>
<p>Yes</p>
</td>
<td>
<p>The amount of messages to return. Note that the actual number of returned messages may be smaller if there aren't enough messages in the conversation. Set this to Infinity to load all messages.</p>
<p>Defaults to <code>50</code>.</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Array of <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="sendMessage"><span class="symbol-name">sendMessage</span><span class="signature"><span class="signature-params">(content, options)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3>
<p>Send a message to this chat</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>content</p>
</td>
<td>
<p>(string, <a href="MessageMedia.html">MessageMedia</a>, or <a href="Location.html">Location</a>)</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>object</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Message.html">Message</a></code> <p>Message that was just sent</p>
</p>
</dd>
</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">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Set the message as seen</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Boolean</code> <p>result</p>
</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendStateRecording"><span class="symbol-name">sendStateRecording</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Simulate recording audio in chat. This will last for 25 seconds.</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendStateTyping"><span class="symbol-name">sendStateTyping</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Simulate typing in chat. This will last for 25 seconds.</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="unarchive"><span class="symbol-name">unarchive</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>un-archives this chat</p>
<dl class="dl-compact">
</dl>
</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.3 on March 13, 2020.
</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>

972
docs/Client.html Normal file
View File

@@ -0,0 +1,972 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">Client</span></h1>
<p class="source-link">Source: <a href="Client.js.html#source-line-33">Client.<wbr>js:33</a></p>
<div class="symbol-classdesc">
<p>Starting point for interacting with the WhatsApp Web API</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Methods</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Client.html#acceptInvite">acceptInvite(inviteCode)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#archiveChat">archiveChat()</a></dt>
<dd>
</dd>
<dt><a href="Client.html#destroy">destroy()</a></dt>
<dd>
</dd>
<dt><a href="Client.html#getChatById">getChatById(chatId)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#getChats">getChats()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Client.html#getContactById">getContactById(contactId)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#getContacts">getContacts()</a></dt>
<dd>
</dd>
<dt><a href="Client.html#getState">getState()</a></dt>
<dd>
</dd>
<dt><a href="Client.html#initialize">initialize()</a></dt>
<dd>
</dd>
<dt><a href="Client.html#resetState">resetState()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Client.html#sendMessage">sendMessage(chatId, content, options)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#sendSeen">sendSeen(chatId)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#setStatus">setStatus(status)</a></dt>
<dd>
</dd>
<dt><a href="Client.html#unarchiveChat">unarchiveChat()</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Events</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Client.html#event:auth_failure">auth_failure</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:authenticated">authenticated</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:change_state">change_state</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:disconnected">disconnected</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:group_join">group_join</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Client.html#event:group_leave">group_leave</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:group_update">group_update</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:message">message</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:message_ack">message_ack</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:message_create">message_create</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Client.html#event:message_revoke_everyone">message_revoke_everyone</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:message_revoke_me">message_revoke_me</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:qr">qr</a></dt>
<dd>
</dd>
<dt><a href="Client.html#event:ready">ready</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
</section>
<section>
<h2 id="Client">new&nbsp;<span class="symbol-name">Client</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd>EventEmitter</dd>
<dt>Fires</dt>
<dd><a href="Client.html#event:qr">Client#event:qr</a></dd>
<dd><a href="Client.html#event:authenticated">Client#event:authenticated</a></dd>
<dd><a href="Client.html#event:auth_failure">Client#event:auth_failure</a></dd>
<dd><a href="Client.html#event:ready">Client#event:ready</a></dd>
<dd><a href="Client.html#event:message">Client#event:message</a></dd>
<dd><a href="Client.html#event:message_ack">Client#event:message_ack</a></dd>
<dd><a href="Client.html#event:message_create">Client#event:message_create</a></dd>
<dd><a href="Client.html#event:message_revoke_me">Client#event:message_revoke_me</a></dd>
<dd><a href="Client.html#event:message_revoke_everyone">Client#event:message_revoke_everyone</a></dd>
<dd><a href="Client.html#event:group_join">Client#event:group_join</a></dd>
<dd><a href="Client.html#event:group_leave">Client#event:group_leave</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:change_state">Client#event:change_state</a></dd>
</dl>
</section>
<section>
<h2>Methods</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="acceptInvite"><span class="symbol-name">acceptInvite</span><span class="signature"><span class="signature-params">(inviteCode)</span></span></h3>
<p>Accepts an invitation to join a 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>inviteCode</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Invitation code</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="archiveChat"><span class="symbol-name">archiveChat</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> boolean</span></span></h3>
<p>Enables and returns the archive state of the Chat</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>boolean</code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="destroy"><span class="symbol-name">destroy</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Closes the client</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getChatById"><span class="symbol-name">getChatById</span><span class="signature"><span class="signature-params">(chatId)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Chat.html">Chat</a></span></span></h3>
<p>Get chat instance by ID</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>chatId</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Chat.html">Chat</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getChats"><span class="symbol-name">getChats</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of <a href="Chat.html">Chat</a></span></span></h3>
<p>Get all current chat instances</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Array of <a href="Chat.html">Chat</a></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>
<p>Get contact instance by ID</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>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Contact.html">Contact</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getContacts"><span class="symbol-name">getContacts</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of <a href="Contact.html">Contact</a></span></span></h3>
<p>Get all current contact instances</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Array of <a href="Contact.html">Contact</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getState"><span class="symbol-name">getState</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> <a href="global.html#WAState">WAState</a></span></span></h3>
<p>Gets the current connection state for the client</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code><a href="global.html#WAState">WAState</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="initialize"><span class="symbol-name">initialize</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Sets up events and requirements, kicks off authentication request</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="resetState"><span class="symbol-name">resetState</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Force reset of connection state for the client</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendMessage"><span class="symbol-name">sendMessage</span><span class="signature"><span class="signature-params">(chatId, content, options)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3>
<p>Send a message to a specific chatId</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>chatId</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>content</p>
</td>
<td>
<p>(string, <a href="MessageMedia.html">MessageMedia</a>, or <a href="Location.html">Location</a>)</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>object</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Message.html">Message</a></code> <p>Message that was just sent</p>
</p>
</dd>
</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>
<p>Mark as seen for the Chat</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>chatId</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing boolean</code> <p>result</p>
</p>
</dd>
</dl>
<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>
<p>Sets the current user's status message</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>status</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>New status message</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="unarchiveChat"><span class="symbol-name">unarchiveChat</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> boolean</span></span></h3>
<p>Changes and returns the archive state of the Chat</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>boolean</code> </p>
</dd>
</dl>
</section>
<h2>Events</h2>
<section>
<h3 id="event:auth_failure"><span class="symbol-name">auth_failure</span></h3>
<p>Emitted when there has been an error while trying to restore an existing session</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>message</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:authenticated"><span class="symbol-name">authenticated</span></h3>
<p>Emitted when authentication is successful</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>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>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:change_state"><span class="symbol-name">change_state</span></h3>
<p>Emitted when the connection state changes</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>state</p>
</td>
<td>
<p><a href="global.html#WAState">WAState</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>the new connection state</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:disconnected"><span class="symbol-name">disconnected</span></h3>
<p>Emitted when the client has been disconnected</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>reason</p>
</td>
<td>
<p><a href="global.html#WAState">WAState</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>state that caused the disconnect</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:group_join"><span class="symbol-name">group_join</span></h3>
<p>Emitted when a user joins the chat via invite link or is added by an admin.</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>notification</p>
</td>
<td>
<p><a href="GroupNotification.html">GroupNotification</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>GroupNotification with more information about the action</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:group_leave"><span class="symbol-name">group_leave</span></h3>
<p>Emitted when a user leaves the chat or is removed by an admin.</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>notification</p>
</td>
<td>
<p><a href="GroupNotification.html">GroupNotification</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>GroupNotification with more information about the action</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:group_update"><span class="symbol-name">group_update</span></h3>
<p>Emitted when group settings are updated, such as subject, description or picture.</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>notification</p>
</td>
<td>
<p><a href="GroupNotification.html">GroupNotification</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>GroupNotification with more information about the action</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:message"><span class="symbol-name">message</span></h3>
<p>Emitted when a new message is received.</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>message</p>
</td>
<td>
<p><a href="Message.html">Message</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>The message that was received</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:message_ack"><span class="symbol-name">message_ack</span></h3>
<p>Emitted when an ack event occurrs on message type.</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>message</p>
</td>
<td>
<p><a href="Message.html">Message</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>The message that was affected</p>
</td>
</tr>
<tr>
<td>
<p>ack</p>
</td>
<td>
<p><a href="global.html#MessageAck">MessageAck</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>The new ACK value</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:message_create"><span class="symbol-name">message_create</span></h3>
<p>Emitted when a new message is created, which may include the current user's own messages.</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>message</p>
</td>
<td>
<p><a href="Message.html">Message</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>The message that was created</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:message_revoke_everyone"><span class="symbol-name">message_revoke_everyone</span></h3>
<p>Emitted when a message is deleted for everyone in the chat.</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>message</p>
</td>
<td>
<p><a href="Message.html">Message</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>The message that was revoked, in its current state. It will not contain the original message's data.</p>
</td>
</tr>
<tr>
<td>
<p>revoked_msg</p>
</td>
<td>
<p><a href="Message.html">Message</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>The message that was revoked, before it was revoked. It will contain the message's original data.
Note that due to the way this data is captured, it may be possible that this param will be undefined.</p>
<p>Value can be null.</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:message_revoke_me"><span class="symbol-name">message_revoke_me</span></h3>
<p>Emitted when a message is deleted by the current user.</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>message</p>
</td>
<td>
<p><a href="Message.html">Message</a></p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>The message that was revoked</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:qr"><span class="symbol-name">qr</span></h3>
<p>Emitted when the QR code is received</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>qr</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>QR Code</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="event:ready"><span class="symbol-name">ready</span></h3>
<p>Emitted when the client has initialized and is ready to receive messages.</p>
<dl class="dl-compact">
</dl>
</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.3 on March 13, 2020.
</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>

548
docs/Client.js.html Normal file
View File

@@ -0,0 +1,548 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: Client.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const EventEmitter &#x3D; require(&#x27;events&#x27;);
const puppeteer &#x3D; require(&#x27;puppeteer&#x27;);
const moduleRaid &#x3D; require(&#x27;moduleraid/moduleraid&#x27;);
const jsQR &#x3D; require(&#x27;jsqr&#x27;);
const Util &#x3D; require(&#x27;./util/Util&#x27;);
const { WhatsWebURL, UserAgent, DefaultOptions, Events, WAState } &#x3D; require(&#x27;./util/Constants&#x27;);
const { ExposeStore, LoadUtils } &#x3D; require(&#x27;./util/Injected&#x27;);
const ChatFactory &#x3D; require(&#x27;./factories/ChatFactory&#x27;);
const ContactFactory &#x3D; require(&#x27;./factories/ContactFactory&#x27;);
const { ClientInfo, Message, MessageMedia, Location, GroupNotification } &#x3D; require(&#x27;./structures&#x27;);
/**
* Starting point for interacting with the WhatsApp Web API
* @extends {EventEmitter}
* @fires Client#qr
* @fires Client#authenticated
* @fires Client#auth_failure
* @fires Client#ready
* @fires Client#message
* @fires Client#message_ack
* @fires Client#message_create
* @fires Client#message_revoke_me
* @fires Client#message_revoke_everyone
* @fires Client#group_join
* @fires Client#group_leave
* @fires Client#group_update
* @fires Client#disconnected
* @fires Client#change_state
*/
class Client extends EventEmitter {
constructor(options &#x3D; {}) {
super();
this.options &#x3D; Util.mergeDefault(DefaultOptions, options);
this.pupBrowser &#x3D; null;
this.pupPage &#x3D; null;
}
/**
* Sets up events and requirements, kicks off authentication request
*/
async initialize() {
const browser &#x3D; await puppeteer.launch(this.options.puppeteer);
const page &#x3D; (await browser.pages())[0];
page.setUserAgent(UserAgent);
if (this.options.session) {
await page.evaluateOnNewDocument(
session &#x3D;&gt; {
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);
}
await page.goto(WhatsWebURL);
const KEEP_PHONE_CONNECTED_IMG_SELECTOR &#x3D; &#x27;[data-asset-intro-image&#x3D;&quot;true&quot;]&#x27;;
if (this.options.session) {
// Check if session restore was successfull
try {
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: 15000 });
} catch (err) {
if (err.name &#x3D;&#x3D;&#x3D; &#x27;TimeoutError&#x27;) {
/**
* 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, &#x27;Unable to log in. Are the session details valid?&#x27;);
browser.close();
return;
}
throw err;
}
} else {
const getQrCode &#x3D; async () &#x3D;&gt; {
// Check if retry button is present
var QR_RETRY_SELECTOR &#x3D; &#x27;div[data-ref] &gt; span &gt; div&#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);
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
* @event Client#qr
* @param {string} qr QR Code
*/
this.emit(Events.QR_RECEIVED, qr);
};
getQrCode();
let retryInterval &#x3D; setInterval(getQrCode, 20000); // check for qr code every 20 seconds
// Wait for code scan
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: 0 });
clearInterval(retryInterval);
}
await page.evaluate(ExposeStore, moduleRaid.toString());
// 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
* @event Client#authenticated
* @param {object} session Object containing session information. Can be used to restore the session.
*/
this.emit(Events.AUTHENTICATED, session);
// Check window.Store Injection
await page.waitForFunction(&#x27;window.Store !&#x3D; undefined&#x27;);
//Load util functions (serializers, helper functions)
await page.evaluate(LoadUtils);
// Expose client info
this.info &#x3D; new ClientInfo(this, await page.evaluate(() &#x3D;&gt; {
return window.Store.Conn.serialize();
}));
// Register events
await page.exposeFunction(&#x27;onAddMessageEvent&#x27;, msg &#x3D;&gt; {
if (!msg.isNewMsg) return;
if (msg.type &#x3D;&#x3D;&#x3D; &#x27;gp2&#x27;) {
const notification &#x3D; new GroupNotification(this, msg);
if (msg.subtype &#x3D;&#x3D;&#x3D; &#x27;add&#x27; || msg.subtype &#x3D;&#x3D;&#x3D; &#x27;invite&#x27;) {
/**
* Emitted when a user joins the chat via invite link or is added by an admin.
* @event Client#group_join
* @param {GroupNotification} notification GroupNotification with more information about the action
*/
this.emit(Events.GROUP_JOIN, notification);
} else if (msg.subtype &#x3D;&#x3D;&#x3D; &#x27;remove&#x27; || msg.subtype &#x3D;&#x3D;&#x3D; &#x27;leave&#x27;) {
/**
* Emitted when a user leaves the chat or is removed by an admin.
* @event Client#group_leave
* @param {GroupNotification} notification GroupNotification with more information about the action
*/
this.emit(Events.GROUP_LEAVE, notification);
} else {
/**
* Emitted when group settings are updated, such as subject, description or picture.
* @event Client#group_update
* @param {GroupNotification} notification GroupNotification with more information about the action
*/
this.emit(Events.GROUP_UPDATE, notification);
}
return;
}
const message &#x3D; new Message(this, msg);
/**
* Emitted when a new message is created, which may include the current user&#x27;s own messages.
* @event Client#message_create
* @param {Message} message The message that was created
*/
this.emit(Events.MESSAGE_CREATE, message);
if (msg.id.fromMe) return;
/**
* Emitted when a new message is received.
* @event Client#message
* @param {Message} message The message that was received
*/
this.emit(Events.MESSAGE_RECEIVED, message);
});
let last_message;
await page.exposeFunction(&#x27;onChangeMessageTypeEvent&#x27;, (msg) &#x3D;&gt; {
if (msg.type &#x3D;&#x3D;&#x3D; &#x27;revoked&#x27;) {
const message &#x3D; new Message(this, msg);
let revoked_msg;
if (last_message &amp;amp;&amp;amp; msg.id.id &#x3D;&#x3D;&#x3D; last_message.id.id) {
revoked_msg &#x3D; new Message(this, last_message);
}
/**
* Emitted when a message is deleted for everyone in the chat.
* @event Client#message_revoke_everyone
* @param {Message} message The message that was revoked, in its current state. It will not contain the original message&#x27;s data.
* @param {?Message} revoked_msg The message that was revoked, before it was revoked. It will contain the message&#x27;s original data.
* Note that due to the way this data is captured, it may be possible that this param will be undefined.
*/
this.emit(Events.MESSAGE_REVOKED_EVERYONE, message, revoked_msg);
}
});
await page.exposeFunction(&#x27;onChangeMessageEvent&#x27;, (msg) &#x3D;&gt; {
if (msg.type !&#x3D;&#x3D; &#x27;revoked&#x27;) {
last_message &#x3D; msg;
}
});
await page.exposeFunction(&#x27;onRemoveMessageEvent&#x27;, (msg) &#x3D;&gt; {
if (!msg.isNewMsg) return;
const message &#x3D; new Message(this, msg);
/**
* Emitted when a message is deleted by the current user.
* @event Client#message_revoke_me
* @param {Message} message The message that was revoked
*/
this.emit(Events.MESSAGE_REVOKED_ME, message);
});
await page.exposeFunction(&#x27;onMessageAckEvent&#x27;, (msg, ack) &#x3D;&gt; {
const message &#x3D; new Message(this, msg);
/**
* Emitted when an ack event occurrs on message type.
* @event Client#message_ack
* @param {Message} message The message that was affected
* @param {MessageAck} ack The new ACK value
*/
this.emit(Events.MESSAGE_ACK, message, ack);
});
await page.exposeFunction(&#x27;onAppStateChangedEvent&#x27;, (state) &#x3D;&gt; {
/**
* Emitted when the connection state changes
* @event Client#change_state
* @param {WAState} state the new connection state
*/
this.emit(Events.STATE_CHANGED, state);
const ACCEPTED_STATES &#x3D; [WAState.CONNECTED, WAState.OPENING, WAState.PAIRING, WAState.TIMEOUT];
if (!ACCEPTED_STATES.includes(state)) {
/**
* Emitted when the client has been disconnected
* @event Client#disconnected
* @param {WAState} reason state that caused the disconnect
*/
this.emit(Events.DISCONNECTED, state);
this.destroy();
}
});
await page.evaluate(() &#x3D;&gt; {
window.Store.Msg.on(&#x27;add&#x27;, (msg) &#x3D;&gt; { if(msg.isNewMsg) window.onAddMessageEvent(msg); });
window.Store.Msg.on(&#x27;change&#x27;, (msg) &#x3D;&gt; { window.onChangeMessageEvent(msg); });
window.Store.Msg.on(&#x27;change:type&#x27;, (msg) &#x3D;&gt; { window.onChangeMessageTypeEvent(msg); });
window.Store.Msg.on(&#x27;change:ack&#x27;, (msg, ack) &#x3D;&gt; { window.onMessageAckEvent(msg, ack); });
window.Store.Msg.on(&#x27;remove&#x27;, (msg) &#x3D;&gt; { if(msg.isNewMsg) window.onRemoveMessageEvent(msg); });
window.Store.AppState.on(&#x27;change:state&#x27;, (_AppState, state) &#x3D;&gt; { window.onAppStateChangedEvent(state); });
});
this.pupBrowser &#x3D; browser;
this.pupPage &#x3D; page;
/**
* Emitted when the client has initialized and is ready to receive messages.
* @event Client#ready
*/
this.emit(Events.READY);
}
/**
* Closes the client
*/
async destroy() {
await this.pupBrowser.close();
}
/**
* Mark as seen for the Chat
* @param {string} chatId
* @returns {Promise&amp;lt;boolean&gt;} result
*
*/
async sendSeen(chatId) {
const result &#x3D; await this.pupPage.evaluate(async (chatId) &#x3D;&gt; {
return window.WWebJS.sendSeen(chatId);
}, chatId);
return result;
}
/**
* Send a message to a specific chatId
* @param {string} chatId
* @param {string|MessageMedia|Location} content
* @param {object} options
* @returns {Promise&amp;lt;Message&gt;} Message that was just sent
*/
async sendMessage(chatId, content, options &#x3D; {}) {
let internalOptions &#x3D; {
caption: options.caption,
quotedMessageId: options.quotedMessageId,
mentionedJidList: Array.isArray(options.mentions) ? options.mentions.map(contact &#x3D;&gt; contact.id._serialized) : []
};
const sendSeen &#x3D; typeof options.sendSeen &#x3D;&#x3D;&#x3D; &#x27;undefined&#x27; ? true : options.sendSeen;
if (content instanceof MessageMedia) {
internalOptions.attachment &#x3D; content;
content &#x3D; &#x27;&#x27;;
} else if (options.media instanceof MessageMedia) {
internalOptions.attachment &#x3D; options.media;
internalOptions.caption &#x3D; content;
} else if (content instanceof Location) {
internalOptions.location &#x3D; content;
content &#x3D; &#x27;&#x27;;
}
const newMessage &#x3D; await this.pupPage.evaluate(async (chatId, message, options, sendSeen) &#x3D;&gt; {
let chat &#x3D; window.Store.Chat.get(chatId);
let msg;
if (!chat) { // The chat is not available in the previously chatted list
let newChatId &#x3D; await window.WWebJS.getNumberId(chatId);
if (newChatId) {
//get the topmost chat object and assign the new chatId to it .
//This is just a workaround.May cause problem if there are no chats at all. Need to dig in and emulate how whatsapp web does
let chat &#x3D; window.Store.Chat.models[0];
if (!chat)
throw &#x27;Chat List empty! Need at least one open conversation with any of your contact&#x27;;
let originalChatObjId &#x3D; chat.id;
chat.id &#x3D; newChatId;
msg &#x3D; await window.WWebJS.sendMessage(chat, message, options);
chat.id &#x3D; originalChatObjId; //replace the chat with its original id
}
}
else {
if(sendSeen) {
window.WWebJS.sendSeen(chatId);
}
msg &#x3D; await window.WWebJS.sendMessage(chat, message, options, sendSeen);
}
return msg.serialize();
}, chatId, content, internalOptions, sendSeen);
return new Message(this, newMessage);
}
/**
* Get all current chat instances
* @returns {Promise&amp;lt;Array&amp;lt;Chat&gt;&gt;}
*/
async getChats() {
let chats &#x3D; await this.pupPage.evaluate(() &#x3D;&gt; {
return window.WWebJS.getChats();
});
return chats.map(chat &#x3D;&gt; ChatFactory.create(this, chat));
}
/**
* Get chat instance by ID
* @param {string} chatId
* @returns {Promise&amp;lt;Chat&gt;}
*/
async getChatById(chatId) {
let chat &#x3D; await this.pupPage.evaluate(chatId &#x3D;&gt; {
return window.WWebJS.getChat(chatId);
}, chatId);
return ChatFactory.create(this, chat);
}
/**
* Get all current contact instances
* @returns {Promise&amp;lt;Array&amp;lt;Contact&gt;&gt;}
*/
async getContacts() {
let contacts &#x3D; await this.pupPage.evaluate(() &#x3D;&gt; {
return window.WWebJS.getContacts();
});
return contacts.map(contact &#x3D;&gt; ContactFactory.create(this, contact));
}
/**
* Get contact instance by ID
* @param {string} contactId
* @returns {Promise&amp;lt;Contact&gt;}
*/
async getContactById(contactId) {
let contact &#x3D; await this.pupPage.evaluate(contactId &#x3D;&gt; {
return window.WWebJS.getContact(contactId);
}, contactId);
return ContactFactory.create(this, contact);
}
/**
* Accepts an invitation to join a group
* @param {string} inviteCode Invitation code
*/
async acceptInvite(inviteCode) {
const chatId &#x3D; await this.pupPage.evaluate(async inviteCode &#x3D;&gt; {
return await window.Store.Invite.sendJoinGroupViaInvite(inviteCode);
}, inviteCode);
return chatId._serialized;
}
/**
* Sets the current user&#x27;s status message
* @param {string} status New status message
*/
async setStatus(status) {
await this.pupPage.evaluate(async status &#x3D;&gt; {
return await window.Store.Wap.sendSetStatus(status);
}, status);
}
/**
* Gets the current connection state for the client
* @returns {WAState}
*/
async getState() {
return await this.pupPage.evaluate(() &#x3D;&gt; {
return window.Store.AppState.state;
});
}
/**
* Enables and returns the archive state of the Chat
* @returns {boolean}
*/
async archiveChat(chatId) {
return await this.pupPage.evaluate(async chatId &#x3D;&gt; {
let chat &#x3D; await window.Store.Chat.get(chatId);
await window.Store.Cmd.archiveChat(chat, true);
return chat.archive;
}, chatId);
}
/**
* Changes and returns the archive state of the Chat
* @returns {boolean}
*/
async unarchiveChat(chatId) {
return await this.pupPage.evaluate(async chatId &#x3D;&gt; {
let chat &#x3D; await window.Store.Chat.get(chatId);
await window.Store.Cmd.archiveChat(chat, false);
return chat.archive;
}, chatId);
}
/**
* Force reset of connection state for the client
*/
async resetState(){
await this.pupPage.evaluate(() &#x3D;&gt; {
window.Store.AppState.phoneWatchdog.shiftTimer.forceRunNow();
});
}
}
module.exports &#x3D; Client;
</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.3 on March 13, 2020.
</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>

202
docs/ClientInfo.html Normal file
View File

@@ -0,0 +1,202 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">ClientInfo</span></h1>
<p class="source-link">Source: <a href="structures_ClientInfo.js.html#source-line-10">structures/<wbr>ClientInfo.<wbr>js:10</a></p>
<div class="symbol-classdesc">
<p>Current connection information</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="ClientInfo.html#me">me</a></dt>
<dd>
</dd>
<dt><a href="ClientInfo.html#phone">phone</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="ClientInfo.html#platform">platform</a></dt>
<dd>
</dd>
<dt><a href="ClientInfo.html#pushname">pushname</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
</div>
</div>
</div>
</section>
<section>
<h2 id="ClientInfo">new&nbsp;<span class="symbol-name">ClientInfo</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Base.html">Base</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="me"><span class="symbol-name">me</span><small class="property-type">
&nbsp;object</small></h3>
<p>Current user ID</p>
<dl class="dl-compact">
</dl>
<h3 id="phone"><span class="symbol-name">phone</span><small class="property-type">
&nbsp;object</small></h3>
<p>Information about the phone this client is connected to</p>
<section>
<h4>Properties</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>wa_version</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>WhatsApp Version running on the phone</p>
</td>
</tr>
<tr>
<td>
<p>os_version</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>OS Version running on the phone (iOS or Android version)</p>
</td>
</tr>
<tr>
<td>
<p>device_manufacturer</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Device manufacturer</p>
</td>
</tr>
<tr>
<td>
<p>device_model</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Device model</p>
</td>
</tr>
<tr>
<td>
<p>os_build_number</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>OS build number</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<h3 id="platform"><span class="symbol-name">platform</span><small class="property-type">
&nbsp;string</small></h3>
<p>Platform the phone is running on</p>
<dl class="dl-compact">
</dl>
<h3 id="pushname"><span class="symbol-name">pushname</span><small class="property-type">
&nbsp;string</small></h3>
<p>Name configured to be shown in push notifications</p>
<dl class="dl-compact">
</dl>
</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.3 on March 13, 2020.
</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>

211
docs/Contact.html Normal file
View File

@@ -0,0 +1,211 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">Contact</span></h1>
<p class="source-link">Source: <a href="structures_Contact.js.html#source-line-10">structures/<wbr>Contact.<wbr>js:10</a></p>
<div class="symbol-classdesc">
<p>Represents a Contact on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Contact.html#id">id</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#isBusiness">isBusiness</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#isEnterprise">isEnterprise</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#isGroup">isGroup</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Contact.html#isMe">isMe</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#isMyContact">isMyContact</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#isUser">isUser</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#isWAContact">isWAContact</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Contact.html#name">name</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#number">number</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#pushname">pushname</a></dt>
<dd>
</dd>
<dt><a href="Contact.html#shortName">shortName</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Method</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Contact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
</div>
<div class="summary-column">
</div>
</div>
</div>
</section>
<section>
<h2 id="Contact">new&nbsp;<span class="symbol-name">Contact</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Base.html">Base</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;object</small></h3>
<p>ID that represents the contact</p>
<dl class="dl-compact">
</dl>
<h3 id="isBusiness"><span class="symbol-name">isBusiness</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the contact is a business contact</p>
<dl class="dl-compact">
</dl>
<h3 id="isEnterprise"><span class="symbol-name">isEnterprise</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the contact is an enterprise contact</p>
<dl class="dl-compact">
</dl>
<h3 id="isGroup"><span class="symbol-name">isGroup</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the contact is a group contact</p>
<dl class="dl-compact">
</dl>
<h3 id="isMe"><span class="symbol-name">isMe</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the contact is the current user's contact</p>
<dl class="dl-compact">
</dl>
<h3 id="isMyContact"><span class="symbol-name">isMyContact</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the number is saved in the current phone's contacts</p>
<dl class="dl-compact">
</dl>
<h3 id="isUser"><span class="symbol-name">isUser</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the contact is a user contact</p>
<dl class="dl-compact">
</dl>
<h3 id="isWAContact"><span class="symbol-name">isWAContact</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the number is registered on WhatsApp</p>
<dl class="dl-compact">
</dl>
<h3 id="name"><span class="symbol-name">name</span><small class="property-type">
&nbsp;nullable string</small></h3>
<p>The contact's name, as saved by the current user</p>
<dl class="dl-compact">
</dl>
<h3 id="number"><span class="symbol-name">number</span><small class="property-type">
&nbsp;string</small></h3>
<p>Contact's phone number</p>
<dl class="dl-compact">
</dl>
<h3 id="pushname"><span class="symbol-name">pushname</span><small class="property-type">
&nbsp;string</small></h3>
<p>The name that the contact has configured to be shown publically</p>
<dl class="dl-compact">
</dl>
<h3 id="shortName"><span class="symbol-name">shortName</span><small class="property-type">
&nbsp;nullable string</small></h3>
<p>A shortened version of name</p>
<dl class="dl-compact">
</dl>
</section>
<h2>Method</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getProfilePicUrl"><span class="symbol-name">getProfilePicUrl</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 profile picture URL, if privacy settings allow it</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing string</code> </p>
</dd>
</dl>
</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.3 on March 13, 2020.
</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>

741
docs/GroupChat.html Normal file
View File

@@ -0,0 +1,741 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">GroupChat</span></h1>
<p class="source-link">Source: <a href="structures_GroupChat.js.html#source-line-9">structures/<wbr>GroupChat.<wbr>js:9</a></p>
<div class="symbol-classdesc">
<p>Represents a Group Chat on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupChat.html#archived">archived</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#createdAt">createdAt</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#description">description</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#id">id</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupChat.html#isGroup">isGroup</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#isReadOnly">isReadOnly</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#name">name</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#owner">owner</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupChat.html#participants">participants</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#timestamp">timestamp</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#unreadCount">unreadCount</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Methods</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupChat.html#.getInviteInfo">getInviteInfo(inviteCode)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#.join">join(inviteCode)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#addParticipants">addParticipants(participantIds)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#archive">archive()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#clearMessages">clearMessages()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#clearState">clearState()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#delete">delete()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupChat.html#demoteParticipants">demoteParticipants(participantIds)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#fetchMessages">fetchMessages(searchOptions)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#getInviteCode">getInviteCode()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#leave">leave()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#promoteParticipants">promoteParticipants(participantIds)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#removeParticipants">removeParticipants(participantIds)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#revokeInvite">revokeInvite()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupChat.html#sendMessage">sendMessage(content, options)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#sendSeen">sendSeen()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#sendStateRecording">sendStateRecording()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#sendStateTyping">sendStateTyping()</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#setDescription">setDescription(description)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#setSubject">setSubject(subject)</a></dt>
<dd>
</dd>
<dt><a href="GroupChat.html#unarchive">unarchive()</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
</section>
<section>
<h2 id="GroupChat">new&nbsp;<span class="symbol-name">GroupChat</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Chat.html">Chat</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="archived"><span class="symbol-name">archived</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the Chat is archived</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#archived">Chat#archived</a></dd>
</dl>
<h3 id="createdAt"><span class="symbol-name">createdAt</span><small class="property-type">
&nbsp;date</small></h3>
<p>Gets the date at which the group was created</p>
<dl class="dl-compact">
</dl>
<h3 id="description"><span class="symbol-name">description</span><small class="property-type">
&nbsp;string</small></h3>
<p>Gets the group description</p>
<dl class="dl-compact">
</dl>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>ID that represents the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#id">Chat#id</a></dd>
</dl>
<h3 id="isGroup"><span class="symbol-name">isGroup</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the Chat is a Group Chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#isGroup">Chat#isGroup</a></dd>
</dl>
<h3 id="isReadOnly"><span class="symbol-name">isReadOnly</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the Chat is readonly</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#isReadOnly">Chat#isReadOnly</a></dd>
</dl>
<h3 id="name"><span class="symbol-name">name</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Title of the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#name">Chat#name</a></dd>
</dl>
<h3 id="owner"><span class="symbol-name">owner</span></h3>
<p>Gets the group owner</p>
<dl class="dl-compact">
</dl>
<h3 id="participants"><span class="symbol-name">participants</span><small class="property-type">
&nbsp;array</small></h3>
<p>Gets the group participants</p>
<dl class="dl-compact">
</dl>
<h3 id="timestamp"><span class="symbol-name">timestamp</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Unix timestamp for when the chat was created</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#timestamp">Chat#timestamp</a></dd>
</dl>
<h3 id="unreadCount"><span class="symbol-name">unreadCount</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Amount of messages unread</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#unreadCount">Chat#unreadCount</a></dd>
</dl>
</section>
<h2>Methods</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span>&nbsp;<span class="label label-static">static</span></div>
<h3 id=".getInviteInfo"><span class="symbol-name">getInviteInfo</span><span class="signature"><span class="signature-params">(inviteCode)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing object</span></span></h3>
<p>Returns an object with information about the invite code's 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>inviteCode</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing object</code> <p>Invite information</p>
</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span>&nbsp;<span class="label label-static">static</span></div>
<h3 id=".join"><span class="symbol-name">join</span><span class="signature"><span class="signature-params">(inviteCode)</span></span></h3>
<p>Joins a group with an invite code</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>inviteCode</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="addParticipants"><span class="symbol-name">addParticipants</span><span class="signature"><span class="signature-params">(participantIds)</span></span></h3>
<p>Adds a list of participants by ID to the 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>participantIds</p>
</td>
<td>
<p>Array of string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="archive"><span class="symbol-name">archive</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Archives this chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#archive">Chat#archive</a></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="clearMessages"><span class="symbol-name">clearMessages</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Clears all messages from the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#clearMessages">Chat#clearMessages</a></dd>
<dt>Returns</dt>
<dd>
<p>result</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="clearState"><span class="symbol-name">clearState</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Stops typing or recording in chat immediately.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#clearState">Chat#clearState</a></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="delete"><span class="symbol-name">delete</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Deletes the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#delete">Chat#delete</a></dd>
<dt>Returns</dt>
<dd>
<p>result</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="demoteParticipants"><span class="symbol-name">demoteParticipants</span><span class="signature"><span class="signature-params">(participantIds)</span></span></h3>
<p>Demotes participants by IDs to regular users</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>participantIds</p>
</td>
<td>
<p>Array of string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="fetchMessages"><span class="symbol-name">fetchMessages</span><span class="signature"><span class="signature-params">(searchOptions)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of <a href="Message.html">Message</a></span></span></h3>
<p>Loads chat messages, sorted from earliest to latest.</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>searchOptions</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Options for searching messages. Right now only limit is supported.</p>
<p>Values in <code>searchOptions</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>limit</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Yes</p>
</td>
<td>
<p>The amount of messages to return. Note that the actual number of returned messages may be smaller if there aren't enough messages in the conversation. Set this to Infinity to load all messages.</p>
<p>Defaults to <code>50</code>.</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#fetchMessages">Chat#fetchMessages</a></dd>
<dt>Returns</dt>
<dd></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getInviteCode"><span class="symbol-name">getInviteCode</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Gets the invite code for a specific group</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="leave"><span class="symbol-name">leave</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Makes the bot leave the group</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="promoteParticipants"><span class="symbol-name">promoteParticipants</span><span class="signature"><span class="signature-params">(participantIds)</span></span></h3>
<p>Promotes participants by IDs to admins</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>participantIds</p>
</td>
<td>
<p>Array of string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="removeParticipants"><span class="symbol-name">removeParticipants</span><span class="signature"><span class="signature-params">(participantIds)</span></span></h3>
<p>Removes a list of participants by ID to the 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>participantIds</p>
</td>
<td>
<p>Array of string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<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></span></h3>
<p>Invalidates the current group invite code and generates a new one</p>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendMessage"><span class="symbol-name">sendMessage</span><span class="signature"><span class="signature-params">(content, options)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3>
<p>Send a message to this chat</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>content</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendMessage">Chat#sendMessage</a></dd>
<dt>Returns</dt>
<dd>
<p>Message that was just sent</p>
</dd>
</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">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Set the message as seen</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendSeen">Chat#sendSeen</a></dd>
<dt>Returns</dt>
<dd>
<p>result</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendStateRecording"><span class="symbol-name">sendStateRecording</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Simulate recording audio in chat. This will last for 25 seconds.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendStateRecording">Chat#sendStateRecording</a></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendStateTyping"><span class="symbol-name">sendStateTyping</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Simulate typing in chat. This will last for 25 seconds.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendStateTyping">Chat#sendStateTyping</a></dd>
</dl>
<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></span></h3>
<p>Updates the group description</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>description</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<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></span></h3>
<p>Updates the group subject</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>subject</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="unarchive"><span class="symbol-name">unarchive</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>un-archives this chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#unarchive">Chat#unarchive</a></dd>
</dl>
</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.3 on March 13, 2020.
</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>

248
docs/GroupNotification.html Normal file
View File

@@ -0,0 +1,248 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">GroupNotification</span></h1>
<p class="source-link">Source: <a href="structures_GroupNotification.js.html#source-line-10">structures/<wbr>GroupNotification.<wbr>js:10</a></p>
<div class="symbol-classdesc">
<p>Represents a GroupNotification on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupNotification.html#author">author</a></dt>
<dd>
</dd>
<dt><a href="GroupNotification.html#body">body</a></dt>
<dd>
</dd>
<dt><a href="GroupNotification.html#chatId">chatId</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupNotification.html#id">id</a></dt>
<dd>
</dd>
<dt><a href="GroupNotification.html#recipientIds">recipientIds</a></dt>
<dd>
</dd>
<dt><a href="GroupNotification.html#timestamp">timestamp</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupNotification.html#type">type</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Methods</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupNotification.html#getChat">getChat()</a></dt>
<dd>
</dd>
<dt><a href="GroupNotification.html#getContact">getContact()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="GroupNotification.html#getRecipients">getRecipients()</a></dt>
<dd>
</dd>
<dt><a href="GroupNotification.html#reply">reply(content, options)</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
</div>
</div>
</div>
</section>
<section>
<h2 id="GroupNotification">new&nbsp;<span class="symbol-name">GroupNotification</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Base.html">Base</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="author"><span class="symbol-name">author</span><small class="property-type">
&nbsp;string</small></h3>
<p>ContactId for the user that produced the GroupNotification.</p>
<dl class="dl-compact">
</dl>
<h3 id="body"><span class="symbol-name">body</span><small class="property-type">
&nbsp;string</small></h3>
<p>Extra content</p>
<dl class="dl-compact">
</dl>
<h3 id="chatId"><span class="symbol-name">chatId</span><small class="property-type">
&nbsp;string</small></h3>
<p>ID for the Chat that this groupNotification was sent for.</p>
<dl class="dl-compact">
</dl>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;object</small></h3>
<p>ID that represents the groupNotification</p>
<dl class="dl-compact">
</dl>
<h3 id="recipientIds"><span class="symbol-name">recipientIds</span><small class="property-type">
&nbsp;Array of string</small></h3>
<p>Contact IDs for the users that were affected by this GroupNotification.</p>
<dl class="dl-compact">
</dl>
<h3 id="timestamp"><span class="symbol-name">timestamp</span><small class="property-type">
&nbsp;number</small></h3>
<p>Unix timestamp for when the groupNotification was created</p>
<dl class="dl-compact">
</dl>
<h3 id="type"><span class="symbol-name">type</span><small class="property-type">
&nbsp;<a href="global.html#GroupNotificationTypes">GroupNotificationTypes</a></small></h3>
<p>GroupNotification type</p>
<dl class="dl-compact">
</dl>
</section>
<h2>Methods</h2>
<section>
<h3 id="getChat"><span class="symbol-name">getChat</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Chat.html">Chat</a></span></span></h3>
<p>Returns the Chat this groupNotification was sent in</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Chat.html">Chat</a></code> </p>
</dd>
</dl>
<h3 id="getContact"><span class="symbol-name">getContact</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Contact.html">Contact</a></span></span></h3>
<p>Returns the Contact this GroupNotification was produced by</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Contact.html">Contact</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getRecipients"><span class="symbol-name">getRecipients</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of <a href="Contact.html">Contact</a></span></span></h3>
<p>Returns the Contacts affected by this GroupNotification.</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Array of <a href="Contact.html">Contact</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, options)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3>
<p>Sends a message to the same chat this GroupNotification was produced in.</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>content</p>
</td>
<td>
<p>(string, <a href="MessageMedia.html">MessageMedia</a>, or <a href="Location.html">Location</a>)</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>object</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Message.html">Message</a></code> </p>
</dd>
</dl>
</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.3 on March 13, 2020.
</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>

164
docs/Location.html Normal file
View File

@@ -0,0 +1,164 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">Location</span></h1>
<p class="source-link">Source: <a href="structures_Location.js.html#source-line-12">structures/<wbr>Location.<wbr>js:12</a></p>
<div class="symbol-classdesc">
<p>Location information</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Location.html#description">description</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Location.html#latitude">latitude</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Location.html#longitude">longitude</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
</section>
<section>
<h2 id="Location">new&nbsp;<span class="symbol-name">Location</span><span class="signature"><span class="signature-params">(latitude, longitude, description)</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>latitude</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>longitude</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>description</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Value can be null.</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="description"><span class="symbol-name">description</span><small class="property-type">
&nbsp;nullable string</small></h3>
<p>Name for the location</p>
<dl class="dl-compact">
</dl>
<h3 id="latitude"><span class="symbol-name">latitude</span><small class="property-type">
&nbsp;number</small></h3>
<p>Location latitude</p>
<dl class="dl-compact">
</dl>
<h3 id="longitude"><span class="symbol-name">longitude</span><small class="property-type">
&nbsp;number</small></h3>
<p>Location longitude</p>
<dl class="dl-compact">
</dl>
</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.3 on March 13, 2020.
</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>

386
docs/Message.html Normal file
View File

@@ -0,0 +1,386 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">Message</span></h1>
<p class="source-link">Source: <a href="structures_Message.js.html#source-line-13">structures/<wbr>Message.<wbr>js:13</a></p>
<div class="symbol-classdesc">
<p>Represents a Message on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Message.html#author">author</a></dt>
<dd>
</dd>
<dt><a href="Message.html#body">body</a></dt>
<dd>
</dd>
<dt><a href="Message.html#broadcast">broadcast</a></dt>
<dd>
</dd>
<dt><a href="Message.html#from">from</a></dt>
<dd>
</dd>
<dt><a href="Message.html#fromMe">fromMe</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Message.html#hasMedia">hasMedia</a></dt>
<dd>
</dd>
<dt><a href="Message.html#hasQuotedMsg">hasQuotedMsg</a></dt>
<dd>
</dd>
<dt><a href="Message.html#id">id</a></dt>
<dd>
</dd>
<dt><a href="Message.html#isForwarded">isForwarded</a></dt>
<dd>
</dd>
<dt><a href="Message.html#location">location</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Message.html#mentionedIds">mentionedIds</a></dt>
<dd>
</dd>
<dt><a href="Message.html#timestamp">timestamp</a></dt>
<dd>
</dd>
<dt><a href="Message.html#to">to</a></dt>
<dd>
</dd>
<dt><a href="Message.html#type">type</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Methods</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Message.html#delete">delete(everyone)</a></dt>
<dd>
</dd>
<dt><a href="Message.html#downloadMedia">downloadMedia()</a></dt>
<dd>
</dd>
<dt><a href="Message.html#getChat">getChat()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Message.html#getContact">getContact()</a></dt>
<dd>
</dd>
<dt><a href="Message.html#getMentions">getMentions()</a></dt>
<dd>
</dd>
<dt><a href="Message.html#getQuotedMessage">getQuotedMessage()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="Message.html#reply">reply(content, chatId, options)</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
</section>
<section>
<h2 id="Message">new&nbsp;<span class="symbol-name">Message</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Base.html">Base</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="author"><span class="symbol-name">author</span><small class="property-type">
&nbsp;string</small></h3>
<p>If the message was sent to a group, this field will contain the user that sent the message.</p>
<dl class="dl-compact">
</dl>
<h3 id="body"><span class="symbol-name">body</span><small class="property-type">
&nbsp;string</small></h3>
<p>Message content</p>
<dl class="dl-compact">
</dl>
<h3 id="broadcast"><span class="symbol-name">broadcast</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the message was a broadcast</p>
<dl class="dl-compact">
</dl>
<h3 id="from"><span class="symbol-name">from</span><small class="property-type">
&nbsp;string</small></h3>
<p>ID for the Chat that this message was sent to, except if the message was sent by the current user.</p>
<dl class="dl-compact">
</dl>
<h3 id="fromMe"><span class="symbol-name">fromMe</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the message was sent by the current user</p>
<dl class="dl-compact">
</dl>
<h3 id="hasMedia"><span class="symbol-name">hasMedia</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the message has media available for download</p>
<dl class="dl-compact">
</dl>
<h3 id="hasQuotedMsg"><span class="symbol-name">hasQuotedMsg</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the message was sent as a reply to another message.</p>
<dl class="dl-compact">
</dl>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;object</small></h3>
<p>ID that represents the message</p>
<dl class="dl-compact">
</dl>
<h3 id="isForwarded"><span class="symbol-name">isForwarded</span><small class="property-type">
&nbsp;boolean</small></h3>
<p>Indicates if the message was forwarded</p>
<dl class="dl-compact">
</dl>
<h3 id="location"><span class="symbol-name">location</span><small class="property-type">
&nbsp;<a href="Location.html">Location</a></small></h3>
<p>Location information contained in the message, if the message is type &quot;location&quot;</p>
<dl class="dl-compact">
</dl>
<h3 id="mentionedIds"><span class="symbol-name">mentionedIds</span><small class="property-type">
&nbsp;Array of string</small></h3>
<p>Indicates the mentions in the message body.</p>
<dl class="dl-compact">
</dl>
<h3 id="timestamp"><span class="symbol-name">timestamp</span><small class="property-type">
&nbsp;number</small></h3>
<p>Unix timestamp for when the message was created</p>
<dl class="dl-compact">
</dl>
<h3 id="to"><span class="symbol-name">to</span><small class="property-type">
&nbsp;string</small></h3>
<p>ID for who this message is for.</p>
<p>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.</p>
<dl class="dl-compact">
</dl>
<h3 id="type"><span class="symbol-name">type</span><small class="property-type">
&nbsp;<a href="global.html#MessageTypes">MessageTypes</a></small></h3>
<p>Message type</p>
<dl class="dl-compact">
</dl>
</section>
<h2>Methods</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="delete"><span class="symbol-name">delete</span><span class="signature"><span class="signature-params">(everyone)</span></span></h3>
<p>Deletes a message from the chat</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>everyone</p>
</td>
<td>
<p>boolean</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>If true and the message is sent by the current user, will delete it for everyone in the chat.</p>
<p>Value can be null.</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="downloadMedia"><span class="symbol-name">downloadMedia</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="MessageMedia.html">MessageMedia</a></span></span></h3>
<p>Downloads and returns the attatched message media</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="MessageMedia.html">MessageMedia</a></code> </p>
</dd>
</dl>
<h3 id="getChat"><span class="symbol-name">getChat</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Chat.html">Chat</a></span></span></h3>
<p>Returns the Chat this message was sent in</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Chat.html">Chat</a></code> </p>
</dd>
</dl>
<h3 id="getContact"><span class="symbol-name">getContact</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Contact.html">Contact</a></span></span></h3>
<p>Returns the Contact this message was sent from</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Contact.html">Contact</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getMentions"><span class="symbol-name">getMentions</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of <a href="Contact.html">Contact</a></span></span></h3>
<p>Returns the Contacts mentioned in this message</p>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing Array of <a href="Contact.html">Contact</a></code> </p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getQuotedMessage"><span class="symbol-name">getQuotedMessage</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>Returns the quoted message, if any</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>
<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
in the same Chat as the original message was sent.</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>content</p>
</td>
<td>
<p>(string, <a href="MessageMedia.html">MessageMedia</a>, or <a href="Location.html">Location</a>)</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>chatId</p>
</td>
<td>
<p>string</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Value can be null.</p>
</td>
</tr>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>object</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Returns</dt>
<dd>
<p><code>Promise containing <a href="Message.html">Message</a></code> </p>
</dd>
</dl>
</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.3 on March 13, 2020.
</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>

167
docs/MessageMedia.html Normal file
View File

@@ -0,0 +1,167 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">MessageMedia</span></h1>
<p class="source-link">Source: <a href="structures_MessageMedia.js.html#source-line-10">structures/<wbr>MessageMedia.<wbr>js:10</a></p>
<div class="symbol-classdesc">
<p>Media attached to a message</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="MessageMedia.html#data">data</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="MessageMedia.html#filename">filename</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="MessageMedia.html#mimetype">mimetype</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
</section>
<section>
<h2 id="MessageMedia">new&nbsp;<span class="symbol-name">MessageMedia</span><span class="signature"><span class="signature-params">(mimetype, data, filename)</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>mimetype</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>MIME type of the attachment</p>
</td>
</tr>
<tr>
<td>
<p>data</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Base64-encoded data of the file</p>
</td>
</tr>
<tr>
<td>
<p>filename</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Document file name</p>
<p>Value can be null.</p>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="data"><span class="symbol-name">data</span><small class="property-type">
&nbsp;string</small></h3>
<p>Base64 encoded data that represents the file</p>
<dl class="dl-compact">
</dl>
<h3 id="filename"><span class="symbol-name">filename</span><small class="property-type">
&nbsp;nullable string</small></h3>
<p>Name of the file (for documents)</p>
<dl class="dl-compact">
</dl>
<h3 id="mimetype"><span class="symbol-name">mimetype</span><small class="property-type">
&nbsp;string</small></h3>
<p>MIME type of the attachment</p>
<dl class="dl-compact">
</dl>
</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.3 on March 13, 2020.
</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>

393
docs/PrivateChat.html Normal file
View File

@@ -0,0 +1,393 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">PrivateChat</span></h1>
<p class="source-link">Source: <a href="structures_PrivateChat.js.html#source-line-9">structures/<wbr>PrivateChat.<wbr>js:9</a></p>
<div class="symbol-classdesc">
<p>Represents a Private Chat on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateChat.html#archived">archived</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#id">id</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#isGroup">isGroup</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateChat.html#isReadOnly">isReadOnly</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#name">name</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#timestamp">timestamp</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateChat.html#unreadCount">unreadCount</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Methods</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateChat.html#archive">archive()</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#clearMessages">clearMessages()</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#clearState">clearState()</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#delete">delete()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateChat.html#fetchMessages">fetchMessages(searchOptions)</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#sendMessage">sendMessage(content, options)</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#sendSeen">sendSeen()</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#sendStateRecording">sendStateRecording()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateChat.html#sendStateTyping">sendStateTyping()</a></dt>
<dd>
</dd>
<dt><a href="PrivateChat.html#unarchive">unarchive()</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
</section>
<section>
<h2 id="PrivateChat">new&nbsp;<span class="symbol-name">PrivateChat</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Chat.html">Chat</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="archived"><span class="symbol-name">archived</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the Chat is archived</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#archived">Chat#archived</a></dd>
</dl>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>ID that represents the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#id">Chat#id</a></dd>
</dl>
<h3 id="isGroup"><span class="symbol-name">isGroup</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the Chat is a Group Chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#isGroup">Chat#isGroup</a></dd>
</dl>
<h3 id="isReadOnly"><span class="symbol-name">isReadOnly</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the Chat is readonly</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#isReadOnly">Chat#isReadOnly</a></dd>
</dl>
<h3 id="name"><span class="symbol-name">name</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Title of the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#name">Chat#name</a></dd>
</dl>
<h3 id="timestamp"><span class="symbol-name">timestamp</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Unix timestamp for when the chat was created</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#timestamp">Chat#timestamp</a></dd>
</dl>
<h3 id="unreadCount"><span class="symbol-name">unreadCount</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Amount of messages unread</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#unreadCount">Chat#unreadCount</a></dd>
</dl>
</section>
<h2>Methods</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="archive"><span class="symbol-name">archive</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Archives this chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#archive">Chat#archive</a></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="clearMessages"><span class="symbol-name">clearMessages</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Clears all messages from the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#clearMessages">Chat#clearMessages</a></dd>
<dt>Returns</dt>
<dd>
<p>result</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="clearState"><span class="symbol-name">clearState</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Stops typing or recording in chat immediately.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#clearState">Chat#clearState</a></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="delete"><span class="symbol-name">delete</span><span class="signature"><span class="signature-params">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Deletes the chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#delete">Chat#delete</a></dd>
<dt>Returns</dt>
<dd>
<p>result</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="fetchMessages"><span class="symbol-name">fetchMessages</span><span class="signature"><span class="signature-params">(searchOptions)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Array of <a href="Message.html">Message</a></span></span></h3>
<p>Loads chat messages, sorted from earliest to latest.</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>searchOptions</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Options for searching messages. Right now only limit is supported.</p>
<p>Values in <code>searchOptions</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>limit</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>Yes</p>
</td>
<td>
<p>The amount of messages to return. Note that the actual number of returned messages may be smaller if there aren't enough messages in the conversation. Set this to Infinity to load all messages.</p>
<p>Defaults to <code>50</code>.</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#fetchMessages">Chat#fetchMessages</a></dd>
<dt>Returns</dt>
<dd></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendMessage"><span class="symbol-name">sendMessage</span><span class="signature"><span class="signature-params">(content, options)</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing <a href="Message.html">Message</a></span></span></h3>
<p>Send a message to this chat</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>content</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>options</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
<p>&nbsp;</p>
</td>
<td>
</td>
</tr>
</tbody>
</table>
</section>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendMessage">Chat#sendMessage</a></dd>
<dt>Returns</dt>
<dd>
<p>Message that was just sent</p>
</dd>
</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">()</span>&nbsp;&rarr; <span class="signature-returns"> Promise containing Boolean</span></span></h3>
<p>Set the message as seen</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendSeen">Chat#sendSeen</a></dd>
<dt>Returns</dt>
<dd>
<p>result</p>
</dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendStateRecording"><span class="symbol-name">sendStateRecording</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Simulate recording audio in chat. This will last for 25 seconds.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendStateRecording">Chat#sendStateRecording</a></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="sendStateTyping"><span class="symbol-name">sendStateTyping</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>Simulate typing in chat. This will last for 25 seconds.</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#sendStateTyping">Chat#sendStateTyping</a></dd>
</dl>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="unarchive"><span class="symbol-name">unarchive</span><span class="signature"><span class="signature-params">()</span></span></h3>
<p>un-archives this chat</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Chat.html#unarchive">Chat#unarchive</a></dd>
</dl>
</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.3 on March 13, 2020.
</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>

235
docs/PrivateContact.html Normal file
View File

@@ -0,0 +1,235 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">PrivateContact</span></h1>
<p class="source-link">Source: <a href="structures_PrivateContact.js.html#source-line-9">structures/<wbr>PrivateContact.<wbr>js:9</a></p>
<div class="symbol-classdesc">
<p>Represents a Private Contact on WhatsApp</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
<div class="summary-callout">
<h2 class="summary-callout-heading">Properties</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateContact.html#id">id</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#isBusiness">isBusiness</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#isEnterprise">isEnterprise</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#isGroup">isGroup</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateContact.html#isMe">isMe</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#isMyContact">isMyContact</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#isUser">isUser</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#isWAContact">isWAContact</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateContact.html#name">name</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#number">number</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#pushname">pushname</a></dt>
<dd>
</dd>
<dt><a href="PrivateContact.html#shortName">shortName</a></dt>
<dd>
</dd>
</dl>
</div>
</div>
</div>
<div class="summary-callout">
<h2 class="summary-callout-heading">Method</h2>
<div class="summary-content">
<div class="summary-column">
<dl class="dl-summary-callout">
<dt><a href="PrivateContact.html#getProfilePicUrl">getProfilePicUrl()</a></dt>
<dd>
</dd>
</dl>
</div>
<div class="summary-column">
</div>
<div class="summary-column">
</div>
</div>
</div>
</section>
<section>
<h2 id="PrivateContact">new&nbsp;<span class="symbol-name">PrivateContact</span><span class="signature"><span class="signature-params">()</span></span></h2>
<dl class="dl-compact">
<dt>Extends</dt>
<dd><a href="Contact.html">Contact</a></dd>
</dl>
</section>
<section>
<h2>Properties</h2>
<section>
<h3 id="id"><span class="symbol-name">id</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>ID that represents the contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#id">Contact#id</a></dd>
</dl>
<h3 id="isBusiness"><span class="symbol-name">isBusiness</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is a business contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isBusiness">Contact#isBusiness</a></dd>
</dl>
<h3 id="isEnterprise"><span class="symbol-name">isEnterprise</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is an enterprise contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isEnterprise">Contact#isEnterprise</a></dd>
</dl>
<h3 id="isGroup"><span class="symbol-name">isGroup</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is a group contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isGroup">Contact#isGroup</a></dd>
</dl>
<h3 id="isMe"><span class="symbol-name">isMe</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is the current user's contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isMe">Contact#isMe</a></dd>
</dl>
<h3 id="isMyContact"><span class="symbol-name">isMyContact</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the number is saved in the current phone's contacts</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isMyContact">Contact#isMyContact</a></dd>
</dl>
<h3 id="isUser"><span class="symbol-name">isUser</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the contact is a user contact</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isUser">Contact#isUser</a></dd>
</dl>
<h3 id="isWAContact"><span class="symbol-name">isWAContact</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Indicates if the number is registered on WhatsApp</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#isWAContact">Contact#isWAContact</a></dd>
</dl>
<h3 id="name"><span class="symbol-name">name</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>The contact's name, as saved by the current user</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#name">Contact#name</a></dd>
</dl>
<h3 id="number"><span class="symbol-name">number</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>Contact's phone number</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#number">Contact#number</a></dd>
</dl>
<h3 id="pushname"><span class="symbol-name">pushname</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>The name that the contact has configured to be shown publically</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#pushname">Contact#pushname</a></dd>
</dl>
<h3 id="shortName"><span class="symbol-name">shortName</span><small class="property-type">
&nbsp;unknown</small></h3>
<p>A shortened version of name</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#shortName">Contact#shortName</a></dd>
</dl>
</section>
<h2>Method</h2>
<section>
<div class="symbol-detail-labels"><span class="label label-async">async</span></div>
<h3 id="getProfilePicUrl"><span class="symbol-name">getProfilePicUrl</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 profile picture URL, if privacy settings allow it</p>
<dl class="dl-compact">
<dt>Inherited from</dt>
<dd><a href="Contact.html#getProfilePicUrl">Contact#getProfilePicUrl</a></dd>
<dt>Returns</dt>
<dd></dd>
</dl>
</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.3 on March 13, 2020.
</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>

65
docs/Util.html Normal file
View File

@@ -0,0 +1,65 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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">Util</span></h1>
<p class="source-link">Source: <a href="util_Util.js.html#source-line-10">util/<wbr>Util.<wbr>js:10</a></p>
<div class="symbol-classdesc">
<p>Utility methods</p>
</div>
<dl class="dl-compact">
</dl>
</header>
<section id="summary">
</section>
<section>
<h2 id="Util">new&nbsp;<span class="symbol-name">Util</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.3 on March 13, 2020.
</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>

4
docs/css/baseline.css Normal file

File diff suppressed because one or more lines are too long

1006
docs/global.html Normal file

File diff suppressed because it is too large Load Diff

1830
docs/index.html Normal file

File diff suppressed because it is too large Load Diff

2
docs/scripts/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

17
docs/scripts/jsdoc-toc.js Normal file
View File

@@ -0,0 +1,17 @@
(function($) {
// TODO: make the node ID configurable
var treeNode = $('#jsdoc-toc-nav');
// initialize the tree
treeNode.tree({
autoEscape: false,
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=\"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=\"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=\"PrivateChat.html\">PrivateChat</a>","id":"PrivateChat","children":[]},{"label":"<a href=\"PrivateContact.html\">PrivateContact</a>","id":"PrivateContact","children":[]},{"label":"<a href=\"Util.html\">Util</a>","id":"Util","children":[]}],
openedIcon: ' &#x21e3;',
saveState: false,
useContextMenu: false
});
// add event handlers
// TODO
})(jQuery);

1
docs/scripts/lang-css.js Normal file
View File

@@ -0,0 +1 @@
PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']+)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}\b/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]),PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]),PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]);

View File

@@ -0,0 +1 @@
!function(){var n,e=0,t=document.getElementsByClassName("prettyprint");t&&t[0]&&(n=(n=(t=t[0].getElementsByTagName("code")[0]).innerHTML.split("\n")).map(function(n){return'<span id="source-line-'+ ++e+'" class="line"></span>'+n}),t.innerHTML=n.join("\n"))}();

1
docs/scripts/prettify.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
!function(){function o(n){var o,t,e=document.getElementById(n.replace(/^#/,""));e&&(t=e.getBoundingClientRect(),o=t.top+window.pageYOffset,setTimeout(function(){window.scrollTo(0,o-50)},5))}window.addEventListener("load",function(){var n=window.location.hash;n&&"#"!==n&&o(n),window.addEventListener("hashchange",function(){o(window.location.hash)})})}();

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,75 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/Base.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
/**
* Represents a WhatsApp data structure
*/
class Base {
constructor(client) {
/**
* The client that instantiated this
* @readonly
*/
Object.defineProperty(this, &#x27;client&#x27;, { value: client });
}
_clone() {
return Object.assign(Object.create(this), this);
}
_patch(data) { return data; }
}
module.exports &#x3D; Base;</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.3 on March 13, 2020.
</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,74 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/BusinessContact.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Contact &#x3D; require(&#x27;./Contact&#x27;);
/**
* Represents a Business Contact on WhatsApp
* @extends {Contact}
*/
class BusinessContact extends Contact {
_patch(data) {
/**
* The contact&#x27;s business profile
*/
this.businessProfile &#x3D; data.businessProfile;
return super._patch(data);
}
}
module.exports &#x3D; BusinessContact;</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.3 on March 13, 2020.
</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,230 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/Chat.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Base &#x3D; require(&#x27;./Base&#x27;);
const Message &#x3D; require(&#x27;./Message&#x27;);
/**
* Represents a Chat on WhatsApp
* @extends {Base}
*/
class Chat extends Base {
constructor(client, data) {
super(client);
if (data) this._patch(data);
}
_patch(data) {
/**
* ID that represents the chat
* @type {object}
*/
this.id &#x3D; data.id;
/**
* Title of the chat
* @type {string}
*/
this.name &#x3D; data.formattedTitle;
/**
* Indicates if the Chat is a Group Chat
* @type {boolean}
*/
this.isGroup &#x3D; data.isGroup;
/**
* Indicates if the Chat is readonly
* @type {boolean}
*/
this.isReadOnly &#x3D; data.isReadOnly;
/**
* Amount of messages unread
* @type {number}
*/
this.unreadCount &#x3D; data.unreadCount;
/**
* Unix timestamp for when the chat was created
* @type {number}
*/
this.timestamp &#x3D; data.t;
/**
* Indicates if the Chat is archived
* @type {boolean}
*/
this.archived &#x3D; data.archive;
return super._patch(data);
}
/**
* Send a message to this chat
* @param {string|MessageMedia|Location} content
* @param {object} options
* @returns {Promise&amp;lt;Message&gt;} Message that was just sent
*/
async sendMessage(content, options) {
return this.client.sendMessage(this.id._serialized, content, options);
}
/**
* Set the message as seen
* @returns {Promise&amp;lt;Boolean&gt;} result
*/
async sendSeen() {
return this.client.sendSeen(this.id._serialized);
}
/**
* Clears all messages from the chat
* @returns {Promise&amp;lt;Boolean&gt;} result
*/
async clearMessages() {
return this.client.pupPage.evaluate(chatId &#x3D;&gt; {
return window.WWebJS.sendClearChat(chatId);
}, this.id._serialized);
}
/**
* Deletes the chat
* @returns {Promise&amp;lt;Boolean&gt;} result
*/
async delete() {
return this.client.pupPage.evaluate(chatId &#x3D;&gt; {
return window.WWebJS.sendDeleteChat(chatId);
}, this.id._serialized);
}
/**
* Archives this chat
*/
async archive() {
return this.client.archiveChat(this.id._serialized);
}
/**
* un-archives this chat
*/
async unarchive() {
return this.client.unarchiveChat(this.id._serialized);
}
/**
* Loads chat messages, sorted from earliest to latest.
* @param {Object} searchOptions Options for searching messages. Right now only limit is supported.
* @param {Number} [searchOptions.limit&#x3D;50] The amount of messages to return. Note that the actual number of returned messages may be smaller if there aren&#x27;t enough messages in the conversation. Set this to Infinity to load all messages.
* @returns {Promise&amp;lt;Array&amp;lt;Message&gt;&gt;}
*/
async fetchMessages(searchOptions) {
if(!searchOptions || !searchOptions.limit) {
searchOptions &#x3D; {limit: 50};
}
let messages &#x3D; await this.client.pupPage.evaluate(async (chatId, limit) &#x3D;&gt; {
const msgFilter &#x3D; m &#x3D;&gt; !m.isNotification; // dont include notification messages
const chat &#x3D; window.Store.Chat.get(chatId);
let msgs &#x3D; chat.msgs.models.filter(msgFilter);
while(msgs.length &amp;lt; limit) {
const loadedMessages &#x3D; await chat.loadEarlierMsgs();
if(!loadedMessages) break;
msgs &#x3D; [...loadedMessages.filter(msgFilter), ...msgs];
}
msgs.sort((a, b) &#x3D;&gt; (a.t &gt; b.t) ? 1 : -1);
return msgs.splice(msgs.length - limit).map(m &#x3D;&gt; m.serialize());
}, this.id._serialized, searchOptions.limit);
return messages.map(m &#x3D;&gt; new Message(this.client, m));
}
/**
* Simulate typing in chat. This will last for 25 seconds.
*/
async sendStateTyping() {
return this.client.pupPage.evaluate(chatId &#x3D;&gt; {
window.WWebJS.sendChatstate(&#x27;typing&#x27;, chatId);
return true;
}, this.id._serialized);
}
/**
* Simulate recording audio in chat. This will last for 25 seconds.
*/
async sendStateRecording() {
return this.client.pupPage.evaluate(chatId &#x3D;&gt; {
window.WWebJS.sendChatstate(&#x27;recording&#x27;, chatId);
return true;
}, this.id._serialized);
}
/**
* Stops typing or recording in chat immediately.
*/
async clearState() {
return this.client.pupPage.evaluate(chatId &#x3D;&gt; {
window.WWebJS.sendChatstate(&#x27;stop&#x27;, chatId);
return true;
}, this.id._serialized);
}
}
module.exports &#x3D; Chat;
</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.3 on March 13, 2020.
</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,104 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/ClientInfo.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Base &#x3D; require(&#x27;./Base&#x27;);
/**
* Current connection information
* @extends {Base}
*/
class ClientInfo extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
/**
* Name configured to be shown in push notifications
* @type {string}
*/
this.pushname &#x3D; data.pushname;
/**
* Current user ID
* @type {object}
*/
this.me &#x3D; data.me;
/**
* Information about the phone this client is connected to
* @type {object}
* @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} device_manufacturer Device manufacturer
* @property {string} device_model Device model
* @property {string} os_build_number OS build number
*/
this.phone &#x3D; data.phone;
/**
* Platform the phone is running on
* @type {string}
*/
this.platform &#x3D; data.platform;
return super._patch(data);
}
}
module.exports &#x3D; ClientInfo;</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.3 on March 13, 2020.
</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,168 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/Contact.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Base &#x3D; require(&#x27;./Base&#x27;);
/**
* Represents a Contact on WhatsApp
* @extends {Base}
*/
class Contact extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
/**
* ID that represents the contact
* @type {object}
*/
this.id &#x3D; data.id;
/**
* Contact&#x27;s phone number
* @type {string}
*/
this.number &#x3D; data.userid;
/**
* Indicates if the contact is a business contact
* @type {boolean}
*/
this.isBusiness &#x3D; data.isBusiness;
/**
* Indicates if the contact is an enterprise contact
* @type {boolean}
*/
this.isEnterprise &#x3D; data.isEnterprise;
this.labels &#x3D; data.labels;
/**
* The contact&#x27;s name, as saved by the current user
* @type {?string}
*/
this.name &#x3D; data.name;
/**
* The name that the contact has configured to be shown publically
* @type {string}
*/
this.pushname &#x3D; data.pushname;
this.sectionHeader &#x3D; data.sectionHeader;
/**
* A shortened version of name
* @type {?string}
*/
this.shortName &#x3D; data.shortName;
this.statusMute &#x3D; data.statusMute;
this.type &#x3D; data.type;
this.verifiedLevel &#x3D; data.verifiedLevel;
this.verifiedName &#x3D; data.verifiedName;
/**
* Indicates if the contact is the current user&#x27;s contact
* @type {boolean}
*/
this.isMe &#x3D; data.isMe;
/**
* Indicates if the contact is a user contact
* @type {boolean}
*/
this.isUser &#x3D; data.isUser;
/**
* Indicates if the contact is a group contact
* @type {boolean}
*/
this.isGroup &#x3D; data.isGroup;
/**
* Indicates if the number is registered on WhatsApp
* @type {boolean}
*/
this.isWAContact &#x3D; data.isWAContact;
/**
* Indicates if the number is saved in the current phone&#x27;s contacts
* @type {boolean}
*/
this.isMyContact &#x3D; data.isMyContact;
return super._patch(data);
}
/**
* Returns the contact&#x27;s profile picture URL, if privacy settings allow it
* @returns {Promise&amp;lt;string&gt;}
*/
async getProfilePicUrl() {
const profilePic &#x3D; await this.client.pupPage.evaluate((contactId) &#x3D;&gt; {
return window.Store.Wap.profilePicFind(contactId);
}, this.id._serialized);
return profilePic ? profilePic.eurl : undefined;
}
}
module.exports &#x3D; Contact;</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.3 on March 13, 2020.
</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,224 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/GroupChat.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Chat &#x3D; require(&#x27;./Chat&#x27;);
/**
* Represents a Group Chat on WhatsApp
* @extends {Chat}
*/
class GroupChat extends Chat {
_patch(data) {
this.groupMetadata &#x3D; data.groupMetadata;
return super._patch(data);
}
/**
* Gets the group owner
*/
get owner() {
return this.groupMetadata.owner;
}
/**
* Gets the date at which the group was created
* @type {date}
*/
get createdAt() {
return new Date(this.groupMetadata.creation * 1000);
}
/**
* Gets the group description
* @type {string}
*/
get description() {
return this.groupMetadata.desc;
}
/**
* Gets the group participants
* @type {array}
*/
get participants() {
return this.groupMetadata.participants;
}
/**
* Adds a list of participants by ID to the group
* @param {Array&amp;lt;string&gt;} participantIds
*/
async addParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.addParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Removes a list of participants by ID to the group
* @param {Array&amp;lt;string&gt;} participantIds
*/
async removeParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.removeParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Promotes participants by IDs to admins
* @param {Array&amp;lt;string&gt;} participantIds
*/
async promoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.promoteParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Demotes participants by IDs to regular users
* @param {Array&amp;lt;string&gt;} participantIds
*/
async demoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) &#x3D;&gt; {
return window.Store.Wap.demoteParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Updates the group subject
* @param {string} subject
*/
async setSubject(subject) {
let res &#x3D; await this.client.pupPage.evaluate((chatId, subject) &#x3D;&gt; {
return window.Store.Wap.changeSubject(chatId, subject);
}, this.id._serialized, subject);
if(res.status &#x3D;&#x3D; 200) {
this.name &#x3D; subject;
}
}
/**
* Updates the group description
* @param {string} description
*/
async setDescription(description) {
let res &#x3D; await this.client.pupPage.evaluate((chatId, description) &#x3D;&gt; {
let descId &#x3D; window.Store.GroupMetadata.get(chatId).descId;
return window.Store.Wap.setGroupDescription(chatId, description, window.Store.genId(), descId);
}, this.id._serialized, description);
if (res.status &#x3D;&#x3D; 200) {
this.groupMetadata.desc &#x3D; description;
}
}
/**
* Gets the invite code for a specific group
*/
async getInviteCode() {
let res &#x3D; await this.client.pupPage.evaluate(chatId &#x3D;&gt; {
return window.Store.Wap.groupInviteCode(chatId);
}, this.id._serialized);
if (res.status &#x3D;&#x3D; 200) {
return res.code;
}
throw new Error(&#x27;Not authorized&#x27;);
}
/**
* Invalidates the current group invite code and generates a new one
*/
async revokeInvite() {
return await this.client.pupPage.evaluate(chatId &#x3D;&gt; {
return window.Store.Wap.revokeGroupInvite(chatId);
}, this.id._serialized);
}
/**
* Returns an object with information about the invite code&#x27;s group
* @param {string} inviteCode
* @returns {Promise&amp;lt;object&gt;} Invite information
*/
static async getInviteInfo(inviteCode) {
return await this.client.pupPage.evaluate(inviteCode &#x3D;&gt; {
return window.Store.Wap.groupInviteInfo(inviteCode);
}, inviteCode);
}
/**
* Joins a group with an invite code
* @param {string} inviteCode
*/
static async join(inviteCode) {
return await this.client.pupPage.evaluate(inviteCode &#x3D;&gt; {
return window.Store.Wap.acceptGroupInvite(inviteCode);
}, inviteCode);
}
/**
* Makes the bot leave the group
*/
async leave() {
return await this.client.pupPage.evaluate(chatId &#x3D;&gt; {
return window.Store.Wap.leaveGroup(chatId);
}, this.id._serialized);
}
}
module.exports &#x3D; GroupChat;</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.3 on March 13, 2020.
</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,158 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/GroupNotification.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Base &#x3D; require(&#x27;./Base&#x27;);
/**
* Represents a GroupNotification on WhatsApp
* @extends {Base}
*/
class GroupNotification extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
/**
* ID that represents the groupNotification
* @type {object}
*/
this.id &#x3D; data.id;
/**
* Extra content
* @type {string}
*/
this.body &#x3D; data.body || &#x27;&#x27;;
/**
* GroupNotification type
* @type {GroupNotificationTypes}
*/
this.type &#x3D; data.subtype;
/**
* Unix timestamp for when the groupNotification was created
* @type {number}
*/
this.timestamp &#x3D; data.t;
/**
* ID for the Chat that this groupNotification was sent for.
*
* @type {string}
*/
this.chatId &#x3D; typeof (data.to) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; ? data.to._serialized : data.to;
/**
* ContactId for the user that produced the GroupNotification.
* @type {string}
*/
this.author &#x3D; typeof (data.author) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; ? data.author._serialized : data.author;
/**
* Contact IDs for the users that were affected by this GroupNotification.
* @type {Array&amp;lt;string&gt;}
*/
this.recipientIds &#x3D; [];
if (data.recipients) {
this.recipientIds &#x3D; data.recipients;
}
return super._patch(data);
}
/**
* Returns the Chat this groupNotification was sent in
* @returns {Promise&amp;lt;Chat&gt;}
*/
getChat() {
return this.client.getChatById(this.chatId);
}
/**
* Returns the Contact this GroupNotification was produced by
* @returns {Promise&amp;lt;Contact&gt;}
*/
getContact() {
return this.client.getContactById(this.author);
}
/**
* Returns the Contacts affected by this GroupNotification.
* @returns {Promise&amp;lt;Array&amp;lt;Contact&gt;&gt;}
*/
async getRecipients() {
return await Promise.all(this.recipientIds.map(async m &#x3D;&gt; await this.client.getContactById(m)));
}
/**
* Sends a message to the same chat this GroupNotification was produced in.
*
* @param {string|MessageMedia|Location} content
* @param {object} options
* @returns {Promise&amp;lt;Message&gt;}
*/
async reply(content, options&#x3D;{}) {
return this.client.sendMessage(this.chatId, content, options);
}
}
module.exports &#x3D; GroupNotification;
</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.3 on March 13, 2020.
</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,86 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/Location.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
/**
* Location information
*/
class Location {
/**
* @param {number} latitude
* @param {number} longitude
* @param {?string} description
*/
constructor(latitude, longitude, description) {
/**
* Location latitude
* @type {number}
*/
this.latitude &#x3D; latitude;
/**
* Location longitude
* @type {number}
*/
this.longitude &#x3D; longitude;
/**
* Name for the location
* @type {?string}
*/
this.description &#x3D; description;
}
}
module.exports &#x3D; Location;</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.3 on March 13, 2020.
</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,277 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/Message.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Base &#x3D; require(&#x27;./Base&#x27;);
const MessageMedia &#x3D; require(&#x27;./MessageMedia&#x27;);
const Location &#x3D; require(&#x27;./Location&#x27;);
const { MessageTypes } &#x3D; require(&#x27;../util/Constants&#x27;);
/**
* Represents a Message on WhatsApp
* @extends {Base}
*/
class Message extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
/**
* ID that represents the message
* @type {object}
*/
this.id &#x3D; data.id;
/**
* Indicates if the message has media available for download
* @type {boolean}
*/
this.hasMedia &#x3D; data.clientUrl ? true : false;
/**
* Message content
* @type {string}
*/
this.body &#x3D; this.hasMedia ? data.caption || &#x27;&#x27; : data.body || &#x27;&#x27;;
/**
* Message type
* @type {MessageTypes}
*/
this.type &#x3D; data.type;
/**
* Unix timestamp for when the message was created
* @type {number}
*/
this.timestamp &#x3D; data.t;
/**
* ID for the Chat that this message was sent to, except if the message was sent by the current user.
* @type {string}
*/
this.from &#x3D; typeof (data.from) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; ? data.from._serialized : data.from;
/**
* 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 another user, it will be the ID for the current user.
* @type {string}
*/
this.to &#x3D; typeof (data.to) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; ? data.to._serialized : data.to;
/**
* If the message was sent to a group, this field will contain the user that sent the message.
* @type {string}
*/
this.author &#x3D; typeof (data.author) &#x3D;&#x3D;&#x3D; &#x27;object&#x27; ? data.author._serialized : data.author;
/**
* Indicates if the message was forwarded
* @type {boolean}
*/
this.isForwarded &#x3D; data.isForwarded;
/**
* Indicates if the message was a broadcast
* @type {boolean}
*/
this.broadcast &#x3D; data.broadcast;
/**
* Indicates if the message was sent by the current user
* @type {boolean}
*/
this.fromMe &#x3D; data.id.fromMe;
/**
* Indicates if the message was sent as a reply to another message.
* @type {boolean}
*/
this.hasQuotedMsg &#x3D; data.quotedMsg ? true : false;
/**
* Location information contained in the message, if the message is type &quot;location&quot;
* @type {Location}
*/
this.location &#x3D; data.type &#x3D;&#x3D;&#x3D; MessageTypes.LOCATION ? new Location(data.lat, data.lng, data.loc) : undefined;
/**
* Indicates the mentions in the message body.
* @type {Array&amp;lt;string&gt;}
*/
this.mentionedIds &#x3D; [];
if (data.mentionedJidList) {
this.mentionedIds &#x3D; data.mentionedJidList;
}
return super._patch(data);
}
_getChatId() {
return this.fromMe ? this.to : this.from;
}
/**
* Returns the Chat this message was sent in
* @returns {Promise&amp;lt;Chat&gt;}
*/
getChat() {
return this.client.getChatById(this._getChatId());
}
/**
* Returns the Contact this message was sent from
* @returns {Promise&amp;lt;Contact&gt;}
*/
getContact() {
return this.client.getContactById(this.author || this.from);
}
/**
* Returns the Contacts mentioned in this message
* @returns {Promise&amp;lt;Array&amp;lt;Contact&gt;&gt;}
*/
async getMentions() {
return await Promise.all(this.mentionedIds.map(async m &#x3D;&gt; await this.client.getContactById(m)));
}
/**
* Returns the quoted message, if any
* @returns {Promise&amp;lt;Message&gt;}
*/
async getQuotedMessage() {
if (!this.hasQuotedMsg) return undefined;
const quotedMsg &#x3D; await this.client.pupPage.evaluate((msgId) &#x3D;&gt; {
let msg &#x3D; window.Store.Msg.get(msgId);
return msg.quotedMsgObj().serialize();
}, this.id._serialized);
return new Message(this.client, quotedMsg);
}
/**
* 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
* in the same Chat as the original message was sent.
*
* @param {string|MessageMedia|Location} content
* @param {?string} chatId
* @param {object} options
* @returns {Promise&amp;lt;Message&gt;}
*/
async reply(content, chatId, options&#x3D;{}) {
if (!chatId) {
chatId &#x3D; this._getChatId();
}
options &#x3D; {
...options,
quotedMessageId: this.id._serialized
};
return this.client.sendMessage(chatId, content, options);
}
/**
* Downloads and returns the attatched message media
* @returns {Promise&amp;lt;MessageMedia&gt;}
*/
async downloadMedia() {
if (!this.hasMedia) {
return undefined;
}
const {data, mimetype, filename} &#x3D; await this.client.pupPage.evaluate(async (msgId) &#x3D;&gt; {
const msg &#x3D; window.Store.Msg.get(msgId);
const buffer &#x3D; await window.WWebJS.downloadBuffer(msg.clientUrl);
const decrypted &#x3D; await window.Store.CryptoLib.decryptE2EMedia(msg.type, buffer, msg.mediaKey, msg.mimetype);
const data &#x3D; await window.WWebJS.readBlobAsync(decrypted._blob);
return {
data: data.split(&#x27;,&#x27;)[1],
mimetype: msg.mimetype,
filename: msg.filename
};
}, this.id._serialized);
return new MessageMedia(mimetype, data, filename);
}
/**
* Deletes a message from the chat
* @param {?boolean} everyone If true and the message is sent by the current user, will delete it for everyone in the chat.
*/
async delete(everyone) {
await this.client.pupPage.evaluate((msgId, everyone) &#x3D;&gt; {
let msg &#x3D; window.Store.Msg.get(msgId);
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.sendDeleteMsgs(msg.chat, [msg], true);
}, this.id._serialized, everyone);
}
}
module.exports &#x3D; Message;
</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.3 on March 13, 2020.
</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,84 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/MessageMedia.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
/**
* Media attached to a message
* @param {string} mimetype MIME type of the attachment
* @param {string} data Base64-encoded data of the file
* @param {?string} filename Document file name
*/
class MessageMedia {
constructor(mimetype, data, filename) {
/**
* MIME type of the attachment
* @type {string}
*/
this.mimetype &#x3D; mimetype;
/**
* Base64 encoded data that represents the file
* @type {string}
*/
this.data &#x3D; data;
/**
* Name of the file (for documents)
* @type {?string}
*/
this.filename &#x3D; filename;
}
}
module.exports &#x3D; MessageMedia;</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.3 on March 13, 2020.
</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,66 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/PrivateChat.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Chat &#x3D; require(&#x27;./Chat&#x27;);
/**
* Represents a Private Chat on WhatsApp
* @extends {Chat}
*/
class PrivateChat extends Chat {
}
module.exports &#x3D; PrivateChat;</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.3 on March 13, 2020.
</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,66 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: structures/PrivateContact.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const Contact &#x3D; require(&#x27;./Contact&#x27;);
/**
* Represents a Private Contact on WhatsApp
* @extends {Contact}
*/
class PrivateContact extends Contact {
}
module.exports &#x3D; PrivateContact;</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.3 on March 13, 2020.
</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>

181
docs/util_Constants.js.html Normal file
View File

@@ -0,0 +1,181 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: util/Constants.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
exports.WhatsWebURL &#x3D; &#x27;https://web.whatsapp.com/&#x27;;
exports.UserAgent &#x3D; &#x27;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36&#x27;;
exports.DefaultOptions &#x3D; {
puppeteer: {
headless: true
},
session: false
};
/**
* Client status
* @readonly
* @enum {number}
*/
exports.Status &#x3D; {
INITIALIZING: 0,
AUTHENTICATING: 1,
READY: 3
};
/**
* Events that can be emitted by the client
* @readonly
* @enum {string}
*/
exports.Events &#x3D; {
AUTHENTICATED: &#x27;authenticated&#x27;,
AUTHENTICATION_FAILURE: &#x27;auth_failure&#x27;,
READY: &#x27;ready&#x27;,
MESSAGE_RECEIVED: &#x27;message&#x27;,
MESSAGE_CREATE: &#x27;message_create&#x27;,
MESSAGE_REVOKED_EVERYONE: &#x27;message_revoke_everyone&#x27;,
MESSAGE_REVOKED_ME: &#x27;message_revoke_me&#x27;,
MESSAGE_ACK: &#x27;message_ack&#x27;,
GROUP_JOIN: &#x27;group_join&#x27;,
GROUP_LEAVE: &#x27;group_leave&#x27;,
GROUP_UPDATE: &#x27;group_update&#x27;,
QR_RECEIVED: &#x27;qr&#x27;,
DISCONNECTED: &#x27;disconnected&#x27;,
STATE_CHANGED: &#x27;change_state&#x27;,
};
/**
* Message types
* @readonly
* @enum {string}
*/
exports.MessageTypes &#x3D; {
TEXT: &#x27;chat&#x27;,
AUDIO: &#x27;audio&#x27;,
VOICE: &#x27;ptt&#x27;,
IMAGE: &#x27;image&#x27;,
VIDEO: &#x27;video&#x27;,
DOCUMENT: &#x27;document&#x27;,
STICKER: &#x27;sticker&#x27;,
LOCATION: &#x27;location&#x27;,
CONTACT_CARD: &#x27;vcard&#x27;,
CONTACT_CARD_MULTI: &#x27;multi_vcard&#x27;,
REVOKED: &#x27;revoked&#x27;,
UNKNOWN: &#x27;unknown&#x27;
};
/**
* Group notification types
* @readonly
* @enum {string}
*/
exports.GroupNotificationTypes &#x3D; {
ADD: &#x27;add&#x27;,
INVITE: &#x27;invite&#x27;,
REMOVE: &#x27;remove&#x27;,
LEAVE: &#x27;leave&#x27;,
SUBJECT: &#x27;subject&#x27;,
DESCRIPTION: &#x27;description&#x27;,
PICTURE: &#x27;picture&#x27;,
ANNOUNCE: &#x27;announce&#x27;,
RESTRICT: &#x27;restrict&#x27;,
};
/**
* Chat types
* @readonly
* @enum {string}
*/
exports.ChatTypes &#x3D; {
SOLO: &#x27;solo&#x27;,
GROUP: &#x27;group&#x27;,
UNKNOWN: &#x27;unknown&#x27;
};
/**
* WhatsApp state
* @readonly
* @enum {string}
*/
exports.WAState &#x3D; {
CONFLICT: &#x27;CONFLICT&#x27;,
CONNECTED: &#x27;CONNECTED&#x27;,
DEPRECATED_VERSION: &#x27;DEPRECATED_VERSION&#x27;,
OPENING: &#x27;OPENING&#x27;,
PAIRING: &#x27;PAIRING&#x27;,
PROXYBLOCK: &#x27;PROXYBLOCK&#x27;,
SMB_TOS_BLOCK: &#x27;SMB_TOS_BLOCK&#x27;,
TIMEOUT: &#x27;TIMEOUT&#x27;,
TOS_BLOCK: &#x27;TOS_BLOCK&#x27;,
UNLAUNCHED: &#x27;UNLAUNCHED&#x27;,
UNPAIRED: &#x27;UNPAIRED&#x27;,
UNPAIRED_IDLE: &#x27;UNPAIRED_IDLE&#x27;
};
/**
* Message ACK
* @readonly
* @enum {number}
*/
exports.MessageAck &#x3D; {
ACK_ERROR: -1,
ACK_PENDING: 0,
ACK_SERVER: 1,
ACK_DEVICE: 2,
ACK_READ: 3,
ACK_PLAYED: 4,
};
</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.3 on March 13, 2020.
</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>

88
docs/util_Util.js.html Normal file
View File

@@ -0,0 +1,88 @@
<!doctype html>
<html>
<head>
<meta name="generator" content="JSDoc 3.6.3">
<meta charset="utf-8">
<title>whatsapp-web.js 1.2.3 &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/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>2.<wbr>3</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: util/Util.js</h1>
</header>
<article>
<pre class="prettyprint linenums"><code>&#x27;use strict&#x27;;
const has &#x3D; (o, k) &#x3D;&gt; Object.prototype.hasOwnProperty.call(o, k);
/**
* Utility methods
*/
class Util {
constructor() {
throw new Error(&#x60;The ${this.constructor.name} class may not be instantiated.&#x60;);
}
/**
* Sets default properties on an object that aren&#x27;t already specified.
* @param {Object} def Default properties
* @param {Object} given Object to assign defaults to
* @returns {Object}
* @private
*/
static mergeDefault(def, given) {
if (!given) return def;
for (const key in def) {
if (!has(given, key) || given[key] &#x3D;&#x3D;&#x3D; undefined) {
given[key] &#x3D; def[key];
} else if (given[key] &#x3D;&#x3D;&#x3D; Object(given[key])) {
given[key] &#x3D; Util.mergeDefault(def[key], given[key]);
}
}
return given;
}
}
module.exports &#x3D; Util;</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.3 on March 13, 2020.
</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

@@ -1,6 +1,13 @@
const { Client } = require('./index')
const fs = require('fs');
const { Client, Location } = require('./index');
const client = new Client({puppeteer: {headless: false}});
const SESSION_FILE_PATH = './session.json';
let sessionCfg;
if (fs.existsSync(SESSION_FILE_PATH)) {
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.
@@ -13,12 +20,18 @@ client.on('qr', (qr) => {
client.on('authenticated', (session) => {
console.log('AUTHENTICATED', session);
sessionCfg=session;
fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), function (err) {
if (err) {
console.error(err);
}
});
});
client.on('auth_failure', msg => {
// Fired if session restore was unsuccessfull
console.error('AUTHENTICATION FAILURE', msg);
})
});
client.on('ready', () => {
console.log('READY');
@@ -35,10 +48,20 @@ client.on('message', async msg => {
// Send a new message to the same chat
client.sendMessage(msg.from, 'pong');
} else if (msg.body.startsWith('!sendto ')) {
// Direct send a new message to specific id
let number = msg.body.split(' ')[1];
let messageIndex = msg.body.indexOf(number) + number.length;
let message = msg.body.slice(messageIndex, msg.body.length);
number = number.includes('@c.us') ? number : `${number}@c.us`;
let chat = await msg.getChat();
chat.sendSeen();
client.sendMessage(number, message);
} else if (msg.body.startsWith('!subject ')) {
// Change the group subject
let chat = await msg.getChat();
if(chat.isGroup) {
if (chat.isGroup) {
let newSubject = msg.body.slice(9);
chat.setSubject(newSubject);
} else {
@@ -50,7 +73,7 @@ client.on('message', async msg => {
} else if (msg.body.startsWith('!desc ')) {
// Change the group description
let chat = await msg.getChat();
if(chat.isGroup) {
if (chat.isGroup) {
let newDescription = msg.body.slice(6);
chat.setDescription(newDescription);
} else {
@@ -59,14 +82,22 @@ client.on('message', async msg => {
} else if (msg.body == '!leave') {
// Leave the group
let chat = await msg.getChat();
if(chat.isGroup) {
if (chat.isGroup) {
chat.leave();
} else {
msg.reply('This command can only be used in a group!');
}
} else if(msg.body == '!groupinfo') {
} else if (msg.body.startsWith('!join ')) {
const inviteCode = msg.body.split(' ')[1];
try {
await client.acceptInvite(inviteCode);
msg.reply('Joined the group!');
} catch (e) {
msg.reply('That invite code seems to be invalid.');
}
} else if (msg.body == '!groupinfo') {
let chat = await msg.getChat();
if(chat.isGroup) {
if (chat.isGroup) {
msg.reply(`
*Group Details*
Name: ${chat.name}
@@ -78,10 +109,19 @@ client.on('message', async msg => {
} else {
msg.reply('This command can only be used in a group!');
}
} else if(msg.body == '!chats') {
} else if (msg.body == '!chats') {
const chats = await client.getChats();
client.sendMessage(msg.from, `The bot has ${chats.length} chats open.`);
} else if(msg.body == '!mediainfo' && msg.hasMedia) {
} else if (msg.body == '!info') {
let info = client.info;
client.sendMessage(msg.from, `
*Connection info*
User name: ${info.pushname}
My number: ${info.me.user}
Platform: ${info.platform}
WhatsApp version: ${info.phone.wa_version}
`);
} else if (msg.body == '!mediainfo' && msg.hasMedia) {
const attachmentData = await msg.downloadMedia();
msg.reply(`
*Media info*
@@ -89,17 +129,115 @@ client.on('message', async msg => {
Filename: ${attachmentData.filename}
Data (length): ${attachmentData.data.length}
`);
} else if (msg.body == '!quoteinfo' && msg.hasQuotedMsg) {
const quotedMsg = await msg.getQuotedMessage();
quotedMsg.reply(`
ID: ${quotedMsg.id._serialized}
Type: ${quotedMsg.type}
Author: ${quotedMsg.author || quotedMsg.from}
Timestamp: ${quotedMsg.timestamp}
Has Media? ${quotedMsg.hasMedia}
`);
} else if (msg.body == '!resendmedia' && msg.hasQuotedMsg) {
const quotedMsg = await msg.getQuotedMessage();
if (quotedMsg.hasMedia) {
const attachmentData = await quotedMsg.downloadMedia();
client.sendMessage(msg.from, attachmentData, { caption: 'Here\'s your requested media.' });
}
} else if (msg.body == '!location') {
msg.reply(new Location(37.422, -122.084, 'Googleplex\nGoogle Headquarters'));
} else if (msg.location) {
msg.reply(msg.location);
} else if (msg.body.startsWith('!status ')) {
const newStatus = msg.body.split(' ')[1];
await client.setStatus(newStatus);
msg.reply(`Status was updated to *${newStatus}*`);
} else if (msg.body == '!mention') {
const contact = await msg.getContact();
const chat = await msg.getChat();
chat.sendMessage(`Hi @${contact.number}!`, {
mentions: [contact]
});
} else if (msg.body == '!delete' && msg.hasQuotedMsg) {
const quotedMsg = await msg.getQuotedMessage();
if (quotedMsg.fromMe) {
quotedMsg.delete(true);
} else {
msg.reply('I can only delete my own messages');
}
} else if (msg.body === '!archive') {
const chat = await msg.getChat();
chat.archive();
} else if (msg.body === '!typing') {
const chat = await msg.getChat();
// simulates typing in the chat
chat.sendStateTyping();
} else if (msg.body === '!recording') {
const chat = await msg.getChat();
// simulates recording audio in the chat
chat.sendStateRecording();
} else if (msg.body === '!clearstate') {
const chat = await msg.getChat();
// stops typing or recording in the chat
chat.clearState();
}
});
client.on('message_create', (msg) => {
// Fired on all message creations, including your own
if(msg.fromMe) {
if (msg.fromMe) {
// do stuff here
}
})
});
client.on('disconnected', () => {
console.log('Client was logged out');
})
client.on('message_revoke_everyone', async (after, before) => {
// Fired whenever a message is deleted by anyone (including you)
console.log(after); // message after it was deleted.
if (before) {
console.log(before); // message before it was deleted.
}
});
client.on('message_revoke_me', async (msg) => {
// Fired whenever a message is only deleted in your own view.
console.log(msg.body); // message before it was deleted.
});
client.on('message_ack', (msg, ack) => {
/*
== ACK VALUES ==
ACK_ERROR: -1
ACK_PENDING: 0
ACK_SERVER: 1
ACK_DEVICE: 2
ACK_READ: 3
ACK_PLAYED: 4
*/
if(ack == 3) {
// The message was read
}
});
client.on('group_join', (notification) => {
// User has joined or been added to the group.
console.log('join', notification);
notification.reply('User joined.');
});
client.on('group_leave', (notification) => {
// User has left or been kicked from the group.
console.log('leave', notification);
notification.reply('User left.');
});
client.on('group_update', (notification) => {
// Group picture, subject or description has been updated.
console.log('update', notification);
});
client.on('disconnected', (reason) => {
console.log('Client was logged out', reason);
});

View File

@@ -9,5 +9,11 @@ module.exports = {
Chat: require('./src/structures/Chat'),
PrivateChat: require('./src/structures/PrivateChat'),
GroupChat: require('./src/structures/GroupChat'),
Message: require('./src/structures/Message')
Message: require('./src/structures/Message'),
MessageMedia: require('./src/structures/MessageMedia'),
Contact: require('./src/structures/Contact'),
PrivateContact: require('./src/structures/PrivateContact'),
BusinessContact: require('./src/structures/BusinessContact'),
ClientInfo: require('./src/structures/ClientInfo'),
Location: require('./src/structures/Location')
};

1378
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,11 @@
{
"name": "whatsapp-web.js",
"version": "0.3.0",
"version": "1.2.3",
"description": "Library for interacting with the WhatsApp Web API ",
"main": "./index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose"
},
"repository": {
"type": "git",
@@ -25,7 +26,13 @@
},
"homepage": "https://github.com/pedroslopez/whatsapp-web.js#readme",
"dependencies": {
"jsqr": "^1.2.0",
"moduleraid": "git+https://github.com/pixeldesu/moduleRaid.git",
"puppeteer": "^1.20.0"
"puppeteer": "^2.1.1"
},
"devDependencies": {
"eslint": "^6.8.0",
"jsdoc": "^3.6.3",
"jsdoc-baseline": "^0.1.5"
}
}

View File

@@ -3,17 +3,31 @@
const EventEmitter = require('events');
const puppeteer = require('puppeteer');
const moduleRaid = require('moduleraid/moduleraid');
const jsQR = require('jsqr');
const Util = require('./util/Util');
const { WhatsWebURL, UserAgent, DefaultOptions, Events, WAState } = require('./util/Constants');
const { ExposeStore, LoadUtils } = require('./util/Injected');
const ChatFactory = require('./factories/ChatFactory');
const Chat = require('./structures/Chat');
const Message = require('./structures/Message');
const ContactFactory = require('./factories/ContactFactory');
const { ClientInfo, Message, MessageMedia, Location, GroupNotification } = require('./structures');
/**
* Starting point for interacting with the WhatsApp Web API
* @extends {EventEmitter}
* @fires Client#qr
* @fires Client#authenticated
* @fires Client#auth_failure
* @fires Client#ready
* @fires Client#message
* @fires Client#message_ack
* @fires Client#message_create
* @fires Client#message_revoke_me
* @fires Client#message_revoke_everyone
* @fires Client#group_join
* @fires Client#group_leave
* @fires Client#group_update
* @fires Client#disconnected
* @fires Client#change_state
*/
class Client extends EventEmitter {
constructor(options = {}) {
@@ -30,30 +44,35 @@ class Client extends EventEmitter {
*/
async initialize() {
const browser = await puppeteer.launch(this.options.puppeteer);
const page = await browser.newPage();
const page = (await browser.pages())[0];
page.setUserAgent(UserAgent);
if (this.options.session) {
await page.evaluateOnNewDocument(
session => {
localStorage.clear();
localStorage.setItem("WABrowserId", session.WABrowserId);
localStorage.setItem("WASecretBundle", session.WASecretBundle);
localStorage.setItem("WAToken1", session.WAToken1);
localStorage.setItem("WAToken2", session.WAToken2);
localStorage.setItem('WABrowserId', session.WABrowserId);
localStorage.setItem('WASecretBundle', session.WASecretBundle);
localStorage.setItem('WAToken1', session.WAToken1);
localStorage.setItem('WAToken2', session.WAToken2);
}, this.options.session);
}
await page.goto(WhatsWebURL);
const KEEP_PHONE_CONNECTED_IMG_SELECTOR = '._1wSzK';
const KEEP_PHONE_CONNECTED_IMG_SELECTOR = '[data-asset-intro-image="true"]';
if (this.options.session) {
// Check if session restore was successfull
try {
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: 5000 });
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: 15000 });
} catch (err) {
if (err.name === 'TimeoutError') {
/**
* 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, 'Unable to log in. Are the session details valid?');
browser.close();
@@ -64,17 +83,34 @@ class Client extends EventEmitter {
}
} else {
// Wait for QR Code
const QR_CONTAINER_SELECTOR = '._2d3Jz';
const QR_VALUE_SELECTOR = '._1pw2F';
const getQrCode = async () => {
// Check if retry button is present
var QR_RETRY_SELECTOR = 'div[data-ref] > span > div';
var qrRetry = await page.$(QR_RETRY_SELECTOR);
if (qrRetry) {
await qrRetry.click();
}
await page.waitForSelector(QR_CONTAINER_SELECTOR);
// Wait for QR Code
const qr = await page.$eval(QR_VALUE_SELECTOR, node => node.getAttribute('data-ref'));
this.emit(Events.QR_RECEIVED, qr);
const QR_CANVAS_SELECTOR = 'canvas';
await page.waitForSelector(QR_CANVAS_SELECTOR);
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
* @event Client#qr
* @param {string} qr QR Code
*/
this.emit(Events.QR_RECEIVED, qr);
};
getQrCode();
let retryInterval = setInterval(getQrCode, 20000); // check for qr code every 20 seconds
// Wait for code scan
await page.waitForSelector(KEEP_PHONE_CONNECTED_IMG_SELECTOR, { timeout: 0 });
clearInterval(retryInterval);
}
await page.evaluate(ExposeStore, moduleRaid.toString());
@@ -89,67 +125,262 @@ class Client extends EventEmitter {
WASecretBundle: localStorage.WASecretBundle,
WAToken1: localStorage.WAToken1,
WAToken2: localStorage.WAToken2
}
};
/**
* Emitted when authentication is successful
* @event Client#authenticated
* @param {object} session Object containing session information. Can be used to restore the session.
*/
this.emit(Events.AUTHENTICATED, session);
// Check Store Injection
// Check window.Store Injection
await page.waitForFunction('window.Store != undefined');
//Load util functions (serializers, helper functions)
await page.evaluate(LoadUtils);
// Expose client info
this.info = new ClientInfo(this, await page.evaluate(() => {
return window.Store.Conn.serialize();
}));
// Register events
await page.exposeFunction('onAddMessageEvent', msg => {
if (!msg.isNewMsg) return;
if (msg.type === 'gp2') {
const notification = new GroupNotification(this, msg);
if (msg.subtype === 'add' || msg.subtype === 'invite') {
/**
* Emitted when a user joins the chat via invite link or is added by an admin.
* @event Client#group_join
* @param {GroupNotification} notification GroupNotification with more information about the action
*/
this.emit(Events.GROUP_JOIN, notification);
} else if (msg.subtype === 'remove' || msg.subtype === 'leave') {
/**
* Emitted when a user leaves the chat or is removed by an admin.
* @event Client#group_leave
* @param {GroupNotification} notification GroupNotification with more information about the action
*/
this.emit(Events.GROUP_LEAVE, notification);
} else {
/**
* Emitted when group settings are updated, such as subject, description or picture.
* @event Client#group_update
* @param {GroupNotification} notification GroupNotification with more information about the action
*/
this.emit(Events.GROUP_UPDATE, notification);
}
return;
}
const message = new Message(this, msg);
/**
* Emitted when a new message is created, which may include the current user's own messages.
* @event Client#message_create
* @param {Message} message The message that was created
*/
this.emit(Events.MESSAGE_CREATE, message);
if (msg.id.fromMe) return;
/**
* Emitted when a new message is received.
* @event Client#message
* @param {Message} message The message that was received
*/
this.emit(Events.MESSAGE_RECEIVED, message);
});
await page.exposeFunction('onAppStateChangedEvent', (AppState, state) => {
const ACCEPTED_STATES = [WAState.CONNECTED, WAState.OPENING, WAState.PAIRING];
let last_message;
await page.exposeFunction('onChangeMessageTypeEvent', (msg) => {
if (msg.type === 'revoked') {
const message = new Message(this, msg);
let revoked_msg;
if (last_message && msg.id.id === last_message.id.id) {
revoked_msg = new Message(this, last_message);
}
/**
* Emitted when a message is deleted for everyone in the chat.
* @event Client#message_revoke_everyone
* @param {Message} message The message that was revoked, in its current state. It will not contain the original message's data.
* @param {?Message} revoked_msg The message that was revoked, before it was revoked. It will contain the message's original data.
* Note that due to the way this data is captured, it may be possible that this param will be undefined.
*/
this.emit(Events.MESSAGE_REVOKED_EVERYONE, message, revoked_msg);
}
});
await page.exposeFunction('onChangeMessageEvent', (msg) => {
if (msg.type !== 'revoked') {
last_message = msg;
}
});
await page.exposeFunction('onRemoveMessageEvent', (msg) => {
if (!msg.isNewMsg) return;
const message = new Message(this, msg);
/**
* Emitted when a message is deleted by the current user.
* @event Client#message_revoke_me
* @param {Message} message The message that was revoked
*/
this.emit(Events.MESSAGE_REVOKED_ME, message);
});
await page.exposeFunction('onMessageAckEvent', (msg, ack) => {
const message = new Message(this, msg);
/**
* Emitted when an ack event occurrs on message type.
* @event Client#message_ack
* @param {Message} message The message that was affected
* @param {MessageAck} ack The new ACK value
*/
this.emit(Events.MESSAGE_ACK, message, ack);
});
await page.exposeFunction('onAppStateChangedEvent', (state) => {
/**
* Emitted when the connection state changes
* @event Client#change_state
* @param {WAState} state the new connection state
*/
this.emit(Events.STATE_CHANGED, state);
const ACCEPTED_STATES = [WAState.CONNECTED, WAState.OPENING, WAState.PAIRING, WAState.TIMEOUT];
if (!ACCEPTED_STATES.includes(state)) {
this.emit(Events.DISCONNECTED);
/**
* Emitted when the client has been disconnected
* @event Client#disconnected
* @param {WAState} reason state that caused the disconnect
*/
this.emit(Events.DISCONNECTED, state);
this.destroy();
}
})
});
await page.evaluate(() => {
Store.Msg.on('add', onAddMessageEvent);
Store.AppState.on('change:state', onAppStateChangedEvent);
}).catch(err => console.log(err.message));
window.Store.Msg.on('add', (msg) => { if(msg.isNewMsg) window.onAddMessageEvent(msg); });
window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(msg); });
window.Store.Msg.on('change:type', (msg) => { window.onChangeMessageTypeEvent(msg); });
window.Store.Msg.on('change:ack', (msg, ack) => { window.onMessageAckEvent(msg, ack); });
window.Store.Msg.on('remove', (msg) => { if(msg.isNewMsg) window.onRemoveMessageEvent(msg); });
window.Store.AppState.on('change:state', (_AppState, state) => { window.onAppStateChangedEvent(state); });
});
this.pupBrowser = browser;
this.pupPage = page;
/**
* Emitted when the client has initialized and is ready to receive messages.
* @event Client#ready
*/
this.emit(Events.READY);
}
/**
* Closes the client
*/
async destroy() {
await this.pupBrowser.close();
}
/**
* Mark as seen for the Chat
* @param {string} chatId
* @returns {Promise<boolean>} result
*
*/
async sendSeen(chatId) {
const result = await this.pupPage.evaluate(async (chatId) => {
return window.WWebJS.sendSeen(chatId);
}, chatId);
return result;
}
/**
* Send a message to a specific chatId
* @param {string} chatId
* @param {string} message
* @param {string|MessageMedia|Location} content
* @param {object} options
* @returns {Promise<Message>} Message that was just sent
*/
async sendMessage(chatId, message) {
await this.pupPage.evaluate((chatId, message) => {
Store.SendMessage(Store.Chat.get(chatId), message);
}, chatId, message)
async sendMessage(chatId, content, options = {}) {
let internalOptions = {
caption: options.caption,
quotedMessageId: options.quotedMessageId,
mentionedJidList: Array.isArray(options.mentions) ? options.mentions.map(contact => contact.id._serialized) : []
};
const sendSeen = typeof options.sendSeen === 'undefined' ? true : options.sendSeen;
if (content instanceof MessageMedia) {
internalOptions.attachment = content;
content = '';
} else if (options.media instanceof MessageMedia) {
internalOptions.attachment = options.media;
internalOptions.caption = content;
} else if (content instanceof Location) {
internalOptions.location = content;
content = '';
}
const newMessage = await this.pupPage.evaluate(async (chatId, message, options, sendSeen) => {
let chat = window.Store.Chat.get(chatId);
let msg;
if (!chat) { // The chat is not available in the previously chatted list
let newChatId = await window.WWebJS.getNumberId(chatId);
if (newChatId) {
//get the topmost chat object and assign the new chatId to it .
//This is just a workaround.May cause problem if there are no chats at all. Need to dig in and emulate how whatsapp web does
let chat = window.Store.Chat.models[0];
if (!chat)
throw 'Chat List empty! Need at least one open conversation with any of your contact';
let originalChatObjId = chat.id;
chat.id = newChatId;
msg = await window.WWebJS.sendMessage(chat, message, options);
chat.id = originalChatObjId; //replace the chat with its original id
}
}
else {
if(sendSeen) {
window.WWebJS.sendSeen(chatId);
}
msg = await window.WWebJS.sendMessage(chat, message, options, sendSeen);
}
return msg.serialize();
}, chatId, content, internalOptions, sendSeen);
return new Message(this, newMessage);
}
/**
* Get all current chat instances
* @returns {Promise<Array<Chat>>}
*/
async getChats() {
let chats = await this.pupPage.evaluate(() => {
return WWebJS.getChats();
return window.WWebJS.getChats();
});
return chats.map(chat => ChatFactory.create(this, chat));
@@ -158,15 +389,106 @@ class Client extends EventEmitter {
/**
* Get chat instance by ID
* @param {string} chatId
* @returns {Promise<Chat>}
*/
async getChatById(chatId) {
let chat = await this.pupPage.evaluate(chatId => {
return WWebJS.getChat(chatId);
return window.WWebJS.getChat(chatId);
}, chatId);
return ChatFactory.create(this, chat);
}
/**
* Get all current contact instances
* @returns {Promise<Array<Contact>>}
*/
async getContacts() {
let contacts = await this.pupPage.evaluate(() => {
return window.WWebJS.getContacts();
});
return contacts.map(contact => ContactFactory.create(this, contact));
}
/**
* Get contact instance by ID
* @param {string} contactId
* @returns {Promise<Contact>}
*/
async getContactById(contactId) {
let contact = await this.pupPage.evaluate(contactId => {
return window.WWebJS.getContact(contactId);
}, contactId);
return ContactFactory.create(this, contact);
}
/**
* Accepts an invitation to join a group
* @param {string} inviteCode Invitation code
*/
async acceptInvite(inviteCode) {
const chatId = await this.pupPage.evaluate(async inviteCode => {
return await window.Store.Invite.sendJoinGroupViaInvite(inviteCode);
}, inviteCode);
return chatId._serialized;
}
/**
* Sets the current user's status message
* @param {string} status New status message
*/
async setStatus(status) {
await this.pupPage.evaluate(async status => {
return await window.Store.Wap.sendSetStatus(status);
}, status);
}
/**
* Gets the current connection state for the client
* @returns {WAState}
*/
async getState() {
return await this.pupPage.evaluate(() => {
return window.Store.AppState.state;
});
}
/**
* Enables and returns the archive state of the Chat
* @returns {boolean}
*/
async archiveChat(chatId) {
return await this.pupPage.evaluate(async chatId => {
let chat = await window.Store.Chat.get(chatId);
await window.Store.Cmd.archiveChat(chat, true);
return chat.archive;
}, chatId);
}
/**
* Changes and returns the archive state of the Chat
* @returns {boolean}
*/
async unarchiveChat(chatId) {
return await this.pupPage.evaluate(async chatId => {
let chat = await window.Store.Chat.get(chatId);
await window.Store.Cmd.archiveChat(chat, false);
return chat.archive;
}, chatId);
}
/**
* Force reset of connection state for the client
*/
async resetState(){
await this.pupPage.evaluate(() => {
window.Store.AppState.phoneWatchdog.shiftTimer.forceRunNow();
});
}
}
module.exports = Client;

View File

@@ -0,0 +1,16 @@
'use strict';
const PrivateContact = require('../structures/PrivateContact');
const BusinessContact = require('../structures/BusinessContact');
class ContactFactory {
static create(client, data) {
if(data.isBusiness) {
return new BusinessContact(client, data);
}
return new PrivateContact(client, data);
}
}
module.exports = ContactFactory;

View File

@@ -14,7 +14,7 @@ class Base {
_clone() {
return Object.assign(Object.create(this), this);
}
}
_patch(data) { return data; }
}

View File

@@ -0,0 +1,21 @@
'use strict';
const Contact = require('./Contact');
/**
* Represents a Business Contact on WhatsApp
* @extends {Contact}
*/
class BusinessContact extends Contact {
_patch(data) {
/**
* The contact's business profile
*/
this.businessProfile = data.businessProfile;
return super._patch(data);
}
}
module.exports = BusinessContact;

View File

@@ -1,6 +1,7 @@
'use strict';
const Base = require('./Base');
const Message = require('./Message');
/**
* Represents a Chat on WhatsApp
@@ -10,24 +11,166 @@ class Chat extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
if (data) this._patch(data);
}
_patch(data) {
/**
* ID that represents the chat
* @type {object}
*/
this.id = data.id;
/**
* Title of the chat
* @type {string}
*/
this.name = data.formattedTitle;
/**
* Indicates if the Chat is a Group Chat
* @type {boolean}
*/
this.isGroup = data.isGroup;
/**
* Indicates if the Chat is readonly
* @type {boolean}
*/
this.isReadOnly = data.isReadOnly;
/**
* Amount of messages unread
* @type {number}
*/
this.unreadCount = data.unreadCount;
/**
* Unix timestamp for when the chat was created
* @type {number}
*/
this.timestamp = data.t;
/**
* Indicates if the Chat is archived
* @type {boolean}
*/
this.archived = data.archive;
return super._patch(data);
}
sendMessage(message) {
return this.client.sendMessage(this.id._serialized, message);
/**
* Send a message to this chat
* @param {string|MessageMedia|Location} content
* @param {object} options
* @returns {Promise<Message>} Message that was just sent
*/
async sendMessage(content, options) {
return this.client.sendMessage(this.id._serialized, content, options);
}
/**
* Set the message as seen
* @returns {Promise<Boolean>} result
*/
async sendSeen() {
return this.client.sendSeen(this.id._serialized);
}
/**
* Clears all messages from the chat
* @returns {Promise<Boolean>} result
*/
async clearMessages() {
return this.client.pupPage.evaluate(chatId => {
return window.WWebJS.sendClearChat(chatId);
}, this.id._serialized);
}
/**
* Deletes the chat
* @returns {Promise<Boolean>} result
*/
async delete() {
return this.client.pupPage.evaluate(chatId => {
return window.WWebJS.sendDeleteChat(chatId);
}, this.id._serialized);
}
/**
* Archives this chat
*/
async archive() {
return this.client.archiveChat(this.id._serialized);
}
/**
* un-archives this chat
*/
async unarchive() {
return this.client.unarchiveChat(this.id._serialized);
}
/**
* Loads chat messages, sorted from earliest to latest.
* @param {Object} searchOptions Options for searching messages. Right now only limit is supported.
* @param {Number} [searchOptions.limit=50] The amount of messages to return. Note that the actual number of returned messages may be smaller if there aren't enough messages in the conversation. Set this to Infinity to load all messages.
* @returns {Promise<Array<Message>>}
*/
async fetchMessages(searchOptions) {
if(!searchOptions || !searchOptions.limit) {
searchOptions = {limit: 50};
}
let messages = await this.client.pupPage.evaluate(async (chatId, limit) => {
const msgFilter = m => !m.isNotification; // dont include notification messages
const chat = window.Store.Chat.get(chatId);
let msgs = chat.msgs.models.filter(msgFilter);
while(msgs.length < limit) {
const loadedMessages = await chat.loadEarlierMsgs();
if(!loadedMessages) break;
msgs = [...loadedMessages.filter(msgFilter), ...msgs];
}
msgs.sort((a, b) => (a.t > b.t) ? 1 : -1);
return msgs.splice(msgs.length - limit).map(m => m.serialize());
}, this.id._serialized, searchOptions.limit);
return messages.map(m => new Message(this.client, m));
}
/**
* Simulate typing in chat. This will last for 25 seconds.
*/
async sendStateTyping() {
return this.client.pupPage.evaluate(chatId => {
window.WWebJS.sendChatstate('typing', chatId);
return true;
}, this.id._serialized);
}
/**
* Simulate recording audio in chat. This will last for 25 seconds.
*/
async sendStateRecording() {
return this.client.pupPage.evaluate(chatId => {
window.WWebJS.sendChatstate('recording', chatId);
return true;
}, this.id._serialized);
}
/**
* Stops typing or recording in chat immediately.
*/
async clearState() {
return this.client.pupPage.evaluate(chatId => {
window.WWebJS.sendChatstate('stop', chatId);
return true;
}, this.id._serialized);
}
}
module.exports = Chat;
module.exports = Chat;

View File

@@ -0,0 +1,51 @@
'use strict';
const Base = require('./Base');
/**
* Current connection information
* @extends {Base}
*/
class ClientInfo extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
/**
* Name configured to be shown in push notifications
* @type {string}
*/
this.pushname = data.pushname;
/**
* Current user ID
* @type {object}
*/
this.me = data.me;
/**
* Information about the phone this client is connected to
* @type {object}
* @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} device_manufacturer Device manufacturer
* @property {string} device_model Device model
* @property {string} os_build_number OS build number
*/
this.phone = data.phone;
/**
* Platform the phone is running on
* @type {string}
*/
this.platform = data.platform;
return super._patch(data);
}
}
module.exports = ClientInfo;

115
src/structures/Contact.js Normal file
View File

@@ -0,0 +1,115 @@
'use strict';
const Base = require('./Base');
/**
* Represents a Contact on WhatsApp
* @extends {Base}
*/
class Contact extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
/**
* ID that represents the contact
* @type {object}
*/
this.id = data.id;
/**
* Contact's phone number
* @type {string}
*/
this.number = data.userid;
/**
* Indicates if the contact is a business contact
* @type {boolean}
*/
this.isBusiness = data.isBusiness;
/**
* Indicates if the contact is an enterprise contact
* @type {boolean}
*/
this.isEnterprise = data.isEnterprise;
this.labels = data.labels;
/**
* The contact's name, as saved by the current user
* @type {?string}
*/
this.name = data.name;
/**
* The name that the contact has configured to be shown publically
* @type {string}
*/
this.pushname = data.pushname;
this.sectionHeader = data.sectionHeader;
/**
* A shortened version of name
* @type {?string}
*/
this.shortName = data.shortName;
this.statusMute = data.statusMute;
this.type = data.type;
this.verifiedLevel = data.verifiedLevel;
this.verifiedName = data.verifiedName;
/**
* Indicates if the contact is the current user's contact
* @type {boolean}
*/
this.isMe = data.isMe;
/**
* Indicates if the contact is a user contact
* @type {boolean}
*/
this.isUser = data.isUser;
/**
* Indicates if the contact is a group contact
* @type {boolean}
*/
this.isGroup = data.isGroup;
/**
* Indicates if the number is registered on WhatsApp
* @type {boolean}
*/
this.isWAContact = data.isWAContact;
/**
* Indicates if the number is saved in the current phone's contacts
* @type {boolean}
*/
this.isMyContact = data.isMyContact;
return super._patch(data);
}
/**
* Returns the contact's profile picture URL, if privacy settings allow it
* @returns {Promise<string>}
*/
async getProfilePicUrl() {
const profilePic = await this.client.pupPage.evaluate((contactId) => {
return window.Store.Wap.profilePicFind(contactId);
}, this.id._serialized);
return profilePic ? profilePic.eurl : undefined;
}
}
module.exports = Contact;

View File

@@ -22,6 +22,7 @@ class GroupChat extends Chat {
/**
* Gets the date at which the group was created
* @type {date}
*/
get createdAt() {
return new Date(this.groupMetadata.creation * 1000);
@@ -29,12 +30,14 @@ class GroupChat extends Chat {
/**
* Gets the group description
* @type {string}
*/
get description() {
return this.groupMetadata.desc;
}
/**
* Gets the group participants
* @type {array}
*/
get participants() {
return this.groupMetadata.participants;
@@ -42,41 +45,41 @@ class GroupChat extends Chat {
/**
* Adds a list of participants by ID to the group
* @param {Array[string]} participantIds
* @param {Array<string>} participantIds
*/
async addParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.addParticipants(chatId, participantIds);
return window.Store.Wap.addParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Removes a list of participants by ID to the group
* @param {Array[string]} participantIds
* @param {Array<string>} participantIds
*/
async removeParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.removeParticipants(chatId, participantIds);
return window.Store.Wap.removeParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Promotes participants by IDs to admins
* @param {Array[string]} participantIds
* @param {Array<string>} participantIds
*/
async promoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.promoteParticipants(chatId, participantIds);
return window.Store.Wap.promoteParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
/**
* Demotes participants by IDs to regular users
* @param {Array[string]} participantIds
* @param {Array<string>} participantIds
*/
async demoteParticipants(participantIds) {
return await this.client.pupPage.evaluate((chatId, participantIds) => {
return Store.Wap.demoteParticipants(chatId, participantIds);
return window.Store.Wap.demoteParticipants(chatId, participantIds);
}, this.id._serialized, participantIds);
}
@@ -86,7 +89,7 @@ class GroupChat extends Chat {
*/
async setSubject(subject) {
let res = await this.client.pupPage.evaluate((chatId, subject) => {
return Store.Wap.changeSubject(chatId, subject);
return window.Store.Wap.changeSubject(chatId, subject);
}, this.id._serialized, subject);
if(res.status == 200) {
@@ -100,8 +103,8 @@ class GroupChat extends Chat {
*/
async setDescription(description) {
let res = await this.client.pupPage.evaluate((chatId, description) => {
let descId = Store.GroupMetadata.get(chatId).descId;
return Store.Wap.setGroupDescription(chatId, description, Store.genId(), descId);
let descId = window.Store.GroupMetadata.get(chatId).descId;
return window.Store.Wap.setGroupDescription(chatId, description, window.Store.genId(), descId);
}, this.id._serialized, description);
if (res.status == 200) {
@@ -114,14 +117,14 @@ class GroupChat extends Chat {
*/
async getInviteCode() {
let res = await this.client.pupPage.evaluate(chatId => {
return Store.Wap.groupInviteCode(chatId);
return window.Store.Wap.groupInviteCode(chatId);
}, this.id._serialized);
if (res.status == 200) {
return res.code;
}
throw new Error('Not authorized')
throw new Error('Not authorized');
}
/**
@@ -129,17 +132,18 @@ class GroupChat extends Chat {
*/
async revokeInvite() {
return await this.client.pupPage.evaluate(chatId => {
return Store.Wap.revokeGroupInvite(chatId);
}, chatId);
return window.Store.Wap.revokeGroupInvite(chatId);
}, this.id._serialized);
}
/**
* Returns an object with information about the invite code's group
* @param {string} inviteCode
* @returns {Promise<object>} Invite information
*/
static async getInviteInfo(inviteCode) {
return await this.client.pupPage.evaluate(inviteCode => {
return Store.Wap.groupInviteInfo(inviteCode);
return window.Store.Wap.groupInviteInfo(inviteCode);
}, inviteCode);
}
@@ -149,7 +153,7 @@ class GroupChat extends Chat {
*/
static async join(inviteCode) {
return await this.client.pupPage.evaluate(inviteCode => {
return Store.Wap.acceptGroupInvite(inviteCode);
return window.Store.Wap.acceptGroupInvite(inviteCode);
}, inviteCode);
}
@@ -158,7 +162,7 @@ class GroupChat extends Chat {
*/
async leave() {
return await this.client.pupPage.evaluate(chatId => {
return Store.Wap.leaveGroup(chatId);
return window.Store.Wap.leaveGroup(chatId);
}, this.id._serialized);
}

View File

@@ -0,0 +1,104 @@
'use strict';
const Base = require('./Base');
/**
* Represents a GroupNotification on WhatsApp
* @extends {Base}
*/
class GroupNotification extends Base {
constructor(client, data) {
super(client);
if(data) this._patch(data);
}
_patch(data) {
/**
* ID that represents the groupNotification
* @type {object}
*/
this.id = data.id;
/**
* Extra content
* @type {string}
*/
this.body = data.body || '';
/**
* GroupNotification type
* @type {GroupNotificationTypes}
*/
this.type = data.subtype;
/**
* Unix timestamp for when the groupNotification was created
* @type {number}
*/
this.timestamp = data.t;
/**
* ID for the Chat that this groupNotification was sent for.
*
* @type {string}
*/
this.chatId = typeof (data.to) === 'object' ? data.to._serialized : data.to;
/**
* ContactId for the user that produced the GroupNotification.
* @type {string}
*/
this.author = typeof (data.author) === 'object' ? data.author._serialized : data.author;
/**
* Contact IDs for the users that were affected by this GroupNotification.
* @type {Array<string>}
*/
this.recipientIds = [];
if (data.recipients) {
this.recipientIds = data.recipients;
}
return super._patch(data);
}
/**
* Returns the Chat this groupNotification was sent in
* @returns {Promise<Chat>}
*/
getChat() {
return this.client.getChatById(this.chatId);
}
/**
* Returns the Contact this GroupNotification was produced by
* @returns {Promise<Contact>}
*/
getContact() {
return this.client.getContactById(this.author);
}
/**
* Returns the Contacts affected by this GroupNotification.
* @returns {Promise<Array<Contact>>}
*/
async getRecipients() {
return await Promise.all(this.recipientIds.map(async m => await this.client.getContactById(m)));
}
/**
* Sends a message to the same chat this GroupNotification was produced in.
*
* @param {string|MessageMedia|Location} content
* @param {object} options
* @returns {Promise<Message>}
*/
async reply(content, options={}) {
return this.client.sendMessage(this.chatId, content, options);
}
}
module.exports = GroupNotification;

View File

@@ -0,0 +1,33 @@
'use strict';
/**
* Location information
*/
class Location {
/**
* @param {number} latitude
* @param {number} longitude
* @param {?string} description
*/
constructor(latitude, longitude, description) {
/**
* Location latitude
* @type {number}
*/
this.latitude = latitude;
/**
* Location longitude
* @type {number}
*/
this.longitude = longitude;
/**
* Name for the location
* @type {?string}
*/
this.description = description;
}
}
module.exports = Location;

View File

@@ -1,6 +1,9 @@
'use strict';
const Base = require('./Base');
const MessageMedia = require('./MessageMedia');
const Location = require('./Location');
const { MessageTypes } = require('../util/Constants');
/**
* Represents a Message on WhatsApp
@@ -14,73 +17,207 @@ class Message extends Base {
}
_patch(data) {
/**
* ID that represents the message
* @type {object}
*/
this.id = data.id;
/**
* Indicates if the message has media available for download
* @type {boolean}
*/
this.hasMedia = data.clientUrl ? true : false;
/**
* Message content
* @type {string}
*/
this.body = this.hasMedia ? data.caption || '' : data.body || '';
/**
* Message type
* @type {MessageTypes}
*/
this.type = data.type;
/**
* Unix timestamp for when the message was created
* @type {number}
*/
this.timestamp = data.t;
this.from = data.from;
this.to = data.to;
this.author = data.author;
/**
* ID for the Chat that this message was sent to, except if the message was sent by the current user.
* @type {string}
*/
this.from = typeof (data.from) === 'object' ? data.from._serialized : data.from;
/**
* 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 another user, it will be the ID for the current user.
* @type {string}
*/
this.to = typeof (data.to) === 'object' ? data.to._serialized : data.to;
/**
* If the message was sent to a group, this field will contain the user that sent the message.
* @type {string}
*/
this.author = typeof (data.author) === 'object' ? data.author._serialized : data.author;
/**
* Indicates if the message was forwarded
* @type {boolean}
*/
this.isForwarded = data.isForwarded;
/**
* Indicates if the message was a broadcast
* @type {boolean}
*/
this.broadcast = data.broadcast;
/**
* Indicates if the message was sent by the current user
* @type {boolean}
*/
this.fromMe = data.id.fromMe;
/**
* Indicates if the message was sent as a reply to another message.
* @type {boolean}
*/
this.hasQuotedMsg = data.quotedMsg ? true : false;
/**
* Location information contained in the message, if the message is type "location"
* @type {Location}
*/
this.location = data.type === MessageTypes.LOCATION ? new Location(data.lat, data.lng, data.loc) : undefined;
/**
* Indicates the mentions in the message body.
* @type {Array<string>}
*/
this.mentionedIds = [];
if (data.mentionedJidList) {
this.mentionedIds = data.mentionedJidList;
}
return super._patch(data);
}
_getChatId() {
return this.fromMe ? this.to : this.from;
}
/**
* Returns the Chat this message was sent in
* @returns {Promise<Chat>}
*/
getChat() {
return this.client.getChatById(this.from);
return this.client.getChatById(this._getChatId());
}
/**
* Sends a message as a reply. If chatId is specified, it will be sent
* through the specified Chat. If not, it will send the message
* in the same Chat as the original message was sent.
* @param {string} message
* @param {?string} chatId
* Returns the Contact this message was sent from
* @returns {Promise<Contact>}
*/
async reply(message, chatId) {
if (!chatId) {
chatId = this.from;
}
return await this.client.pupPage.evaluate((chatId, quotedMessageId, message) => {
let quotedMessage = Store.Msg.get(quotedMessageId);
if(quotedMessage.canReply()) {
const chat = Store.Chat.get(chatId);
chat.composeQuotedMsg = quotedMessage;
window.Store.SendMessage(chat, message, {quotedMsg: quotedMessage});
chat.composeQuotedMsg = null;
} else {
throw new Error('This message cannot be replied to.');
}
}, chatId, this.id._serialized, message);
getContact() {
return this.client.getContactById(this.author || this.from);
}
/**
* Returns the Contacts mentioned in this message
* @returns {Promise<Array<Contact>>}
*/
async getMentions() {
return await Promise.all(this.mentionedIds.map(async m => await this.client.getContactById(m)));
}
/**
* Returns the quoted message, if any
* @returns {Promise<Message>}
*/
async getQuotedMessage() {
if (!this.hasQuotedMsg) return undefined;
const quotedMsg = await this.client.pupPage.evaluate((msgId) => {
let msg = window.Store.Msg.get(msgId);
return msg.quotedMsgObj().serialize();
}, this.id._serialized);
return new Message(this.client, quotedMsg);
}
/**
* 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
* in the same Chat as the original message was sent.
*
* @param {string|MessageMedia|Location} content
* @param {?string} chatId
* @param {object} options
* @returns {Promise<Message>}
*/
async reply(content, chatId, options={}) {
if (!chatId) {
chatId = this._getChatId();
}
options = {
...options,
quotedMessageId: this.id._serialized
};
return this.client.sendMessage(chatId, content, options);
}
/**
* Downloads and returns the attatched message media
* @returns {Promise<MessageMedia>}
*/
async downloadMedia() {
if (!this.hasMedia) {
return undefined;
}
return await this.client.pupPage.evaluate(async (msgId) => {
const msg = Store.Msg.get(msgId);
const buffer = await WWebJS.downloadBuffer(msg.clientUrl);
const decrypted = await Store.CryptoLib.decryptE2EMedia(msg.type, buffer, msg.mediaKey, msg.mimetype);
const data = await WWebJS.readBlobAsync(decrypted._blob);
const {data, mimetype, filename} = await this.client.pupPage.evaluate(async (msgId) => {
const msg = window.Store.Msg.get(msgId);
const buffer = await window.WWebJS.downloadBuffer(msg.clientUrl);
const decrypted = await window.Store.CryptoLib.decryptE2EMedia(msg.type, buffer, msg.mediaKey, msg.mimetype);
const data = await window.WWebJS.readBlobAsync(decrypted._blob);
return {
data,
data: data.split(',')[1],
mimetype: msg.mimetype,
filename: msg.filename
}
};
}, this.id._serialized);
return new MessageMedia(mimetype, data, filename);
}
/**
* Deletes a message from the chat
* @param {?boolean} everyone If true and the message is sent by the current user, will delete it for everyone in the chat.
*/
async delete(everyone) {
await this.client.pupPage.evaluate((msgId, everyone) => {
let msg = window.Store.Msg.get(msgId);
if(everyone && msg.id.fromMe && msg.canRevoke()) {
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], true);
}
return window.Store.Cmd.sendDeleteMsgs(msg.chat, [msg], true);
}, this.id._serialized, everyone);
}
}
module.exports = Message;
module.exports = Message;

View File

@@ -0,0 +1,31 @@
'use strict';
/**
* Media attached to a message
* @param {string} mimetype MIME type of the attachment
* @param {string} data Base64-encoded data of the file
* @param {?string} filename Document file name
*/
class MessageMedia {
constructor(mimetype, data, filename) {
/**
* MIME type of the attachment
* @type {string}
*/
this.mimetype = mimetype;
/**
* Base64 encoded data that represents the file
* @type {string}
*/
this.data = data;
/**
* Name of the file (for documents)
* @type {?string}
*/
this.filename = filename;
}
}
module.exports = MessageMedia;

View File

@@ -0,0 +1,13 @@
'use strict';
const Contact = require('./Contact');
/**
* Represents a Private Contact on WhatsApp
* @extends {Contact}
*/
class PrivateContact extends Contact {
}
module.exports = PrivateContact;

13
src/structures/index.js Normal file
View File

@@ -0,0 +1,13 @@
module.exports = {
Base: require('./Base'),
BusinessContact: require('./BusinessContact'),
Chat: require('./Chat'),
ClientInfo: require('./ClientInfo'),
Contact: require('./Contact'),
GroupChat: require('./GroupChat'),
Location: require('./Location'),
Message: require('./Message'),
MessageMedia: require('./MessageMedia'),
PrivateChat: require('./PrivateChat'),
PrivateContact: require('./PrivateContact'),
};

View File

@@ -1,6 +1,6 @@
'use strict';
exports.WhatsWebURL = 'https://web.whatsapp.com/'
exports.WhatsWebURL = 'https://web.whatsapp.com/';
exports.UserAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36';
@@ -9,24 +9,46 @@ exports.DefaultOptions = {
headless: true
},
session: false
}
};
/**
* Client status
* @readonly
* @enum {number}
*/
exports.Status = {
INITIALIZING: 0,
AUTHENTICATING: 1,
READY: 3
}
};
/**
* Events that can be emitted by the client
* @readonly
* @enum {string}
*/
exports.Events = {
AUTHENTICATED: 'authenticated',
AUTHENTICATION_FAILURE: 'auth_failure',
READY: 'ready',
MESSAGE_RECEIVED: 'message',
MESSAGE_CREATE: 'message_create',
MESSAGE_REVOKED_EVERYONE: 'message_revoke_everyone',
MESSAGE_REVOKED_ME: 'message_revoke_me',
MESSAGE_ACK: 'message_ack',
GROUP_JOIN: 'group_join',
GROUP_LEAVE: 'group_leave',
GROUP_UPDATE: 'group_update',
QR_RECEIVED: 'qr',
DISCONNECTED: 'disconnected'
}
DISCONNECTED: 'disconnected',
STATE_CHANGED: 'change_state',
};
/**
* Message types
* @readonly
* @enum {string}
*/
exports.MessageTypes = {
TEXT: 'chat',
AUDIO: 'audio',
@@ -34,26 +56,72 @@ exports.MessageTypes = {
IMAGE: 'image',
VIDEO: 'video',
DOCUMENT: 'document',
STICKER: 'sticker'
}
STICKER: 'sticker',
LOCATION: 'location',
CONTACT_CARD: 'vcard',
CONTACT_CARD_MULTI: 'multi_vcard',
REVOKED: 'revoked',
UNKNOWN: 'unknown'
};
/**
* Group notification types
* @readonly
* @enum {string}
*/
exports.GroupNotificationTypes = {
ADD: 'add',
INVITE: 'invite',
REMOVE: 'remove',
LEAVE: 'leave',
SUBJECT: 'subject',
DESCRIPTION: 'description',
PICTURE: 'picture',
ANNOUNCE: 'announce',
RESTRICT: 'restrict',
};
/**
* Chat types
* @readonly
* @enum {string}
*/
exports.ChatTypes = {
SOLO: 'solo',
GROUP: 'group',
UNKNOWN: 'unknown'
}
};
/**
* WhatsApp state
* @readonly
* @enum {string}
*/
exports.WAState = {
CONFLICT: "CONFLICT",
CONNECTED: "CONNECTED",
DEPRECATED_VERSION: "DEPRECATED_VERSION",
OPENING: "OPENING",
PAIRING: "PAIRING",
PROXYBLOCK: "PROXYBLOCK",
SMB_TOS_BLOCK: "SMB_TOS_BLOCK",
TIMEOUT: "TIMEOUT",
TOS_BLOCK: "TOS_BLOCK",
UNLAUNCHED: "UNLAUNCHED",
UNPAIRED: "UNPAIRED",
UNPAIRED_IDLE: "UNPAIRED_IDLE"
}
CONFLICT: 'CONFLICT',
CONNECTED: 'CONNECTED',
DEPRECATED_VERSION: 'DEPRECATED_VERSION',
OPENING: 'OPENING',
PAIRING: 'PAIRING',
PROXYBLOCK: 'PROXYBLOCK',
SMB_TOS_BLOCK: 'SMB_TOS_BLOCK',
TIMEOUT: 'TIMEOUT',
TOS_BLOCK: 'TOS_BLOCK',
UNLAUNCHED: 'UNLAUNCHED',
UNPAIRED: 'UNPAIRED',
UNPAIRED_IDLE: 'UNPAIRED_IDLE'
};
/**
* Message ACK
* @readonly
* @enum {number}
*/
exports.MessageAck = {
ACK_ERROR: -1,
ACK_PENDING: 0,
ACK_SERVER: 1,
ACK_DEVICE: 2,
ACK_READ: 3,
ACK_PLAYED: 4,
};

View File

@@ -1,20 +1,147 @@
'use strict';
/**
* Exposes the internal Store to the WhatsApp Web client
*/
// Exposes the internal Store to the WhatsApp Web client
exports.ExposeStore = (moduleRaidStr) => {
eval("var moduleRaid = " + moduleRaidStr);
eval('var moduleRaid = ' + moduleRaidStr);
// eslint-disable-next-line no-undef
window.mR = moduleRaid();
window.Store = window.mR.findModule("Chat")[1].default;
window.Store.AppState = window.mR.findModule("STREAM")[0].default;
window.Store.CryptoLib = window.mR.findModule("decryptE2EMedia")[0];
window.Store = window.mR.findModule('Chat')[1].default;
window.Store.AppState = window.mR.findModule('STREAM')[0].default;
window.Store.Conn = window.mR.findModule('Conn')[0].default;
window.Store.CryptoLib = window.mR.findModule('decryptE2EMedia')[0];
window.Store.Wap = window.mR.findModule('Wap')[0].default;
window.Store.SendSeen = window.mR.findModule('sendSeen')[0];
window.Store.SendClear = window.mR.findModule('sendClear')[0];
window.Store.SendDelete = window.mR.findModule('sendDelete')[0];
window.Store.genId = window.mR.findModule((module) => module.default && typeof module.default === 'function' && module.default.toString().match(/crypto/))[0].default;
window.Store.SendMessage = window.mR.findModule("sendTextMsgToChat")[0].sendTextMsgToChat;
}
window.Store.SendMessage = window.mR.findModule('addAndSendMsgToChat')[0];
window.Store.MsgKey = window.mR.findModule((module) => module.default && module.default.fromString)[0].default;
window.Store.Invite = window.mR.findModule('sendJoinGroupViaInvite')[0];
window.Store.OpaqueData = window.mR.findModule('getOrCreateOpaqueDataForPath')[0];
window.Store.MediaPrep = window.mR.findModule('MediaPrep')[0];
window.Store.MediaObject = window.mR.findModule('getOrCreateMediaObject')[0];
window.Store.MediaUpload = window.mR.findModule('uploadMedia')[0];
window.Store.Cmd = window.mR.findModule('Cmd')[0].default;
window.Store.MediaTypes = window.mR.findModule('msgToMediaType')[0];
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;
};
exports.LoadUtils = () => {
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) => {
let chat = window.Store.Chat.get(chatId);
if (chat !== undefined) {
await window.Store.SendSeen.sendSeen(chat, false);
return true;
}
return false;
};
window.WWebJS.sendMessage = async (chat, content, options = {}) => {
let attOptions = {};
if (options.attachment) {
attOptions = await window.WWebJS.processMediaData(options.attachment);
delete options.attachment;
}
let quotedMsgOptions = {};
if (options.quotedMessageId) {
let quotedMessage = window.Store.Msg.get(options.quotedMessageId);
if (quotedMessage.canReply()) {
quotedMsgOptions = quotedMessage.msgContextInfo(chat);
}
delete options.quotedMessageId;
}
if (options.mentionedJidList) {
options.mentionedJidList = options.mentionedJidList.map(cId => window.Store.Contact.get(cId).id);
}
let locationOptions = {};
if (options.location) {
locationOptions = {
type: 'location',
loc: options.location.description,
lat: options.location.latitude,
lng: options.location.longitude
};
delete options.location;
}
const newMsgId = new window.Store.MsgKey({
from: window.Store.Conn.me,
to: chat.id,
id: window.Store.genId(),
});
const message = {
...options,
id: newMsgId,
ack: 0,
body: content,
from: window.Store.Conn.me,
to: chat.id,
local: true,
self: 'out',
t: parseInt(new Date().getTime() / 1000),
isNewMsg: true,
type: 'chat',
...locationOptions,
...attOptions,
...quotedMsgOptions
};
await window.Store.SendMessage.addAndSendMsgToChat(chat, message);
return window.Store.Msg.get(newMsgId._serialized);
};
window.WWebJS.processMediaData = async (mediaInfo) => {
const file = window.WWebJS.mediaInfoToFile(mediaInfo);
const mData = await window.Store.OpaqueData.default.createFromData(file, file.type);
const mediaPrep = window.Store.MediaPrep.prepRawMedia(mData, {});
const mediaData = await mediaPrep.waitForPrep();
const mediaObject = window.Store.MediaObject.getOrCreateMediaObject(mediaData.filehash);
const mediaType = window.Store.MediaTypes.msgToMediaType({
type: mediaData.type,
isGif: mediaData.isGif
});
if (!(mediaData.mediaBlob instanceof window.Store.OpaqueData.default)) {
mediaData.mediaBlob = await window.Store.OpaqueData.default.createFromData(mediaData.mediaBlob, mediaData.mediaBlob.type);
}
mediaData.renderableUrl = mediaData.mediaBlob.url();
mediaObject.consolidate(mediaData.toJSON());
mediaData.mediaBlob.autorelease();
const uploadedMedia = await window.Store.MediaUpload.uploadMedia(mediaData.mimetype, mediaObject, mediaType);
if (!uploadedMedia) {
throw new Error('upload failed: media entry was not created');
}
mediaData.set({
clientUrl: uploadedMedia.mmsUrl,
directPath: uploadedMedia.directPath,
mediaKey: uploadedMedia.mediaKey,
mediaKeyTimestamp: uploadedMedia.mediaKeyTimestamp,
filehash: mediaObject.filehash,
uploadhash: uploadedMedia.uploadHash,
size: mediaObject.size,
streamingSidecar: uploadedMedia.sidecar,
firstFrameSidecar: uploadedMedia.firstFrameSidecar
});
return mediaData;
};
window.WWebJS.getChatModel = chat => {
let res = chat.serialize();
@@ -26,22 +153,66 @@ exports.LoadUtils = () => {
}
return res;
}
};
window.WWebJS.getChat = chatId => {
const chat = Store.Chat.get(chatId);
return WWebJS.getChatModel(chat);
}
const chat = window.Store.Chat.get(chatId);
return window.WWebJS.getChatModel(chat);
};
window.WWebJS.getChats = () => {
const chats = Store.Chat.models;
return chats.map(chat => WWebJS.getChatModel(chat));
}
const chats = window.Store.Chat.models;
return chats.map(chat => window.WWebJS.getChatModel(chat));
};
window.WWebJS.getContactModel = contact => {
let res = contact.serialize();
res.isBusiness = contact.isBusiness;
if (contact.businessProfile) {
res.businessProfile = contact.businessProfile.serialize();
}
res.isMe = contact.isMe;
res.isUser = contact.isUser;
res.isGroup = contact.isGroup;
res.isWAContact = contact.isWAContact;
res.isMyContact = contact.isMyContact;
res.userid = contact.userid;
return res;
};
window.WWebJS.getContact = contactId => {
const contact = window.Store.Contact.get(contactId);
return window.WWebJS.getContactModel(contact);
};
window.WWebJS.getContacts = () => {
const contacts = window.Store.Contact.models;
return contacts.map(contact => window.WWebJS.getContactModel(contact));
};
window.WWebJS.mediaInfoToFile = ({ data, mimetype, filename }) => {
const binaryData = atob(data);
const buffer = new ArrayBuffer(binaryData.length);
const view = new Uint8Array(buffer);
for (let i = 0; i < binaryData.length; i++) {
view[i] = binaryData.charCodeAt(i);
}
const blob = new Blob([buffer], { type: mimetype });
return new File([blob], filename, {
type: mimetype,
lastModified: Date.now()
});
};
window.WWebJS.downloadBuffer = (url) => {
return new Promise(function(resolve, reject) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
if (xhr.status == 200) {
@@ -61,27 +232,64 @@ exports.LoadUtils = () => {
};
xhr.send(null);
});
}
};
window.WWebJS.readBlobAsync = (blob) => {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(blob);
})
}
}
let reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(blob);
});
};
window.WWebJS.sendClearChat = async (chatId) => {
let chat = window.Store.Chat.get(chatId);
if (chat !== undefined) {
await window.Store.SendClear.sendClear(chat, false);
return true;
}
return false;
};
window.WWebJS.sendDeleteChat = async (chatId) => {
let chat = window.Store.Chat.get(chatId);
if (chat !== undefined) {
await window.Store.SendDelete.sendDelete(chat);
return true;
}
return false;
};
window.WWebJS.sendChatstate = async (state, chatId) => {
switch(state) {
case 'typing':
await window.Store.Wap.sendChatstateComposing(chatId);
break;
case 'recording':
await window.Store.Wap.sendChatstateRecording(chatId);
break;
case 'stop':
await window.Store.Wap.sendChatstatePaused(chatId);
break;
default:
throw 'Invalid chatstate';
}
return true;
};
};
exports.MarkAllRead = () => {
let Chats = Store.Chat.models;
let Chats = window.Store.Chat.models;
for (chatIndex in Chats) {
for (let chatIndex in Chats) {
if (isNaN(chatIndex)) {
continue;
}
@@ -90,7 +298,7 @@ exports.MarkAllRead = () => {
if (chat.unreadCount > 0) {
chat.markSeen();
Store.Wap.sendConversationSeen(chat.id, chat.getLastMsgKeyForAction(), chat.unreadCount - chat.pendingSeenCount);
window.Store.Wap.sendConversationSeen(chat.id, chat.getLastMsgKeyForAction(), chat.unreadCount - chat.pendingSeenCount);
}
}
}
};

View File

@@ -7,29 +7,29 @@ const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
*/
class Util {
constructor() {
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
}
/**
* Sets default properties on an object that aren't already specified.
* @param {Object} def Default properties
* @param {Object} given Object to assign defaults to
* @returns {Object}
* @private
*/
static mergeDefault(def, given) {
if (!given) return def;
for (const key in def) {
if (!has(given, key) || given[key] === undefined) {
given[key] = def[key];
} else if (given[key] === Object(given[key])) {
given[key] = Util.mergeDefault(def[key], given[key]);
}
constructor() {
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
}
return given;
}
/**
* Sets default properties on an object that aren't already specified.
* @param {Object} def Default properties
* @param {Object} given Object to assign defaults to
* @returns {Object}
* @private
*/
static mergeDefault(def, given) {
if (!given) return def;
for (const key in def) {
if (!has(given, key) || given[key] === undefined) {
given[key] = def[key];
} else if (given[key] === Object(given[key])) {
given[key] = Util.mergeDefault(def[key], given[key]);
}
}
return given;
}
}
module.exports = Util;