whatsapp-web.js 1.23.1-alpha.4 → 1.23.1-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,24 +1,70 @@
1
- [![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js) [![Depfu](https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg)](https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765) ![WhatsApp_Web 2.2346.52](https://img.shields.io/badge/WhatsApp_Web-2.2346.52-brightgreen.svg) [![Discord Chat](https://img.shields.io/discord/698610475432411196.svg?logo=discord)](https://discord.gg/H7DqQs4)
1
+ <div align="center">
2
+ <br />
3
+ <p>
4
+ <a href="https://wwebjs.dev"><img src="https://github.com/wwebjs/logos/blob/main/4_Full%20Logo%20Lockup_Small/small_banner_blue.png?raw=true" title="whatsapp-web.js" alt="WWebJS Website" width="500" /></a>
5
+ </p>
6
+ <br />
7
+ <p>
8
+ <a href="https://www.npmjs.com/package/whatsapp-web.js"><img src="https://img.shields.io/npm/v/whatsapp-web.js.svg" alt="npm" /></a>
9
+ <a href="https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765"><img src="https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg" alt="Depfu" /></a>
10
+ <img src="https://img.shields.io/badge/WhatsApp_Web-2.2346.52-brightgreen.svg" alt="WhatsApp_Web 2.2346.52" />
11
+ <a href="https://discord.gg/H7DqQs4"><img src="https://img.shields.io/discord/698610475432411196.svg?logo=discord" alt="Discord server" /></a>
12
+ </p>
13
+ <br />
14
+ </div>
15
+
16
+ ## About
17
+ **A WhatsApp API client that connects through the WhatsApp Web browser app**
18
+
19
+ The library works by launching the WhatsApp Web browser application and managing it using Puppeteer to create an instance of WhatsApp Web, thereby mitigating the risk of being blocked. The WhatsApp API client connects through the WhatsApp Web browser app, accessing its internal functions. This grants you access to nearly all the features available on WhatsApp Web, enabling dynamic handling similar to any other Node.js application.
20
+
21
+ > [!IMPORTANT]
22
+ > **It is not guaranteed you will not be blocked by using this method. WhatsApp does not allow bots or unofficial clients on their platform, so this shouldn't be considered totally safe.**
23
+
24
+ ## Links
25
+
26
+ * [Website][website]
27
+ * [Guide][guide] ([source][guide-source]) _(work in progress)_
28
+ * [Documentation][documentation] ([source][documentation-source])
29
+ * [WWebJS Discord][discord]
30
+ * [GitHub][gitHub]
31
+ * [npm][npm]
2
32
 
3
- # whatsapp-web.js
4
- A WhatsApp API client that connects through the WhatsApp Web browser app
33
+ ## Installation
5
34
 
6
- It uses Puppeteer to run a real instance of Whatsapp Web to avoid getting blocked.
35
+ The module is now available on npm! `npm i whatsapp-web.js`
7
36
 
8
- **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.
37
+ > [!NOTE]
38
+ > **Node ``v18+`` is required.**
9
39
 
10
- ## Quick Links
40
+ ## QUICK STEPS TO UPGRADE NODE
11
41
 
12
- * [Guide / Getting Started](https://wwebjs.dev/guide) _(work in progress)_
13
- * [Reference documentation](https://docs.wwebjs.dev/)
14
- * [GitHub](https://github.com/pedroslopez/whatsapp-web.js)
15
- * [npm](https://npmjs.org/package/whatsapp-web.js)
42
+ ### Windows
16
43
 
17
- ## Installation
44
+ #### Manual
45
+ Just get the latest LTS from the [official node website][nodejs].
18
46
 
19
- The module is now available on npm! `npm i whatsapp-web.js`
47
+ #### npm
48
+ ```powershell
49
+ sudo npm install -g n
50
+ sudo n stable
51
+ ```
52
+
53
+ #### Choco
54
+ ```powershell
55
+ choco install nodejs-lts
56
+ ```
20
57
 
21
- Please note that Node v12+ is required.
58
+ #### Winget
59
+ ```powershell
60
+ winget install OpenJS.NodeJS.LTS
61
+ ```
62
+
63
+ ### Ubuntu / Debian
64
+ ```bash
65
+ curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - &&\
66
+ sudo apt-get install -y nodejs
67
+ ```
22
68
 
23
69
  ## Example usage
24
70
 
@@ -45,9 +91,8 @@ client.on('message', msg => {
45
91
  client.initialize();
46
92
  ```
47
93
 
48
- Take a look at [example.js](https://github.com/pedroslopez/whatsapp-web.js/blob/master/example.js) for another example with more use cases.
49
-
50
- For more information on saving and restoring sessions, check out the available [Authentication Strategies](https://wwebjs.dev/guide/authentication.html).
94
+ Take a look at [example.js][examples] for another examples with additional use cases.
95
+ For further details on saving and restoring sessions, explore the provided [Authentication Strategies][auth-strategies].
51
96
 
52
97
 
53
98
  ## Supported features
@@ -58,13 +103,13 @@ For more information on saving and restoring sessions, check out the available [
58
103
  | Send messages | ✅ |
59
104
  | Receive messages | ✅ |
60
105
  | Send media (images/audio/documents) | ✅ |
61
- | Send media (video) | ✅ [(requires google chrome)](https://wwebjs.dev/guide/handling-attachments.html#caveat-for-sending-videos-and-gifs) |
106
+ | Send media (video) | ✅ [(requires Google Chrome)][google-chrome] |
62
107
  | Send stickers | ✅ |
63
108
  | Receive media (images/audio/video/documents) | ✅ |
64
109
  | Send contact cards | ✅ |
65
110
  | Send location | ✅ |
66
- | Send buttons | ❌ |
67
- | Send lists | ❌ [(DEPRECATED)](https://www.youtube.com/watch?v=hv1R1rLeVVE) |
111
+ | Send buttons | ❌ [(DEPRECATED)][deprecated-video] |
112
+ | Send lists | ❌ [(DEPRECATED)][deprecated-video] |
68
113
  | Receive location | ✅ |
69
114
  | Message replies | ✅ |
70
115
  | Join groups by invite | ✅ |
@@ -75,43 +120,66 @@ For more information on saving and restoring sessions, check out the available [
75
120
  | Kick group participants | ✅ |
76
121
  | Promote/demote group participants | ✅ |
77
122
  | Mention users | ✅ |
123
+ | Mention groups | ✅ |
78
124
  | Mute/unmute chats | ✅ |
79
125
  | Block/unblock contacts | ✅ |
80
126
  | Get contact info | ✅ |
81
127
  | Get profile pictures | ✅ |
82
128
  | Set user status message | ✅ |
83
129
  | React to messages | ✅ |
84
- | Vote in polls | 🔜 |
85
130
  | Create polls | ✅ |
131
+ | Vote in polls | 🔜 |
132
+ | Communities | 🔜 |
133
+ | Channels | 🔜 |
86
134
 
87
135
  Something missing? Make an issue and let us know!
88
136
 
89
137
  ## Contributing
90
138
 
91
- Pull requests are welcome! If you see something you'd like to add, please do. For drastic changes, please open an issue first.
139
+ Feel free to open pull requests; we welcome contributions! However, for significant changes, it's best to open an issue beforehand. Make sure to review our [contribution guidelines][contributing] before creating a pull request. Before creating your own issue or pull request, always check to see if one already exists!
92
140
 
93
141
  ## Supporting the project
94
142
 
95
143
  You can support the maintainer of this project through the links below
96
144
 
97
- - [Support via GitHub Sponsors](https://github.com/sponsors/pedroslopez)
98
- - [Support via PayPal](https://www.paypal.me/psla/)
99
- - [Sign up for DigitalOcean](https://m.do.co/c/73f906a36ed4) and get $200 in credit when you sign up (Referral)
145
+ - [Support via GitHub Sponsors][gitHub-sponsors]
146
+ - [Support via PayPal][support-payPal]
147
+ - [Sign up for DigitalOcean][digitalocean] and get $200 in credit when you sign up (Referral)
100
148
 
101
149
  ## Disclaimer
102
150
 
103
- This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or its affiliates. The official WhatsApp website can be found at https://whatsapp.com. "WhatsApp" as well as related names, marks, emblems and images are registered trademarks of their respective owners.
151
+ This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or its affiliates. The official WhatsApp website can be found at [whatsapp.com][whatsapp]. "WhatsApp" as well as related names, marks, emblems and images are registered trademarks of their respective owners. Also it is not guaranteed you will not be blocked by using this method. WhatsApp does not allow bots or unofficial clients on their platform, so this shouldn't be considered totally safe.
104
152
 
105
153
  ## License
106
154
 
107
- Copyright 2019 Pedro S Lopez
108
-
109
- Licensed under the Apache License, Version 2.0 (the "License");
110
- you may not use this project except in compliance with the License.
111
- You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
112
-
113
- Unless required by applicable law or agreed to in writing, software
114
- distributed under the License is distributed on an "AS IS" BASIS,
115
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
116
- See the License for the specific language governing permissions and
117
- limitations under the License.
155
+ Copyright 2019 Pedro S Lopez
156
+
157
+ Licensed under the Apache License, Version 2.0 (the "License");
158
+ you may not use this project except in compliance with the License.
159
+ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
160
+
161
+ Unless required by applicable law or agreed to in writing, software
162
+ distributed under the License is distributed on an "AS IS" BASIS,
163
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
164
+ See the License for the specific language governing permissions and
165
+ limitations under the License.
166
+
167
+
168
+ [website]: https://wwebjs.dev
169
+ [guide]: https://guide.wwebjs.dev/guide
170
+ [guide-source]: https://github.com/wwebjs/wwebjs.dev/tree/main
171
+ [documentation]: https://docs.wwebjs.dev/
172
+ [documentation-source]: https://github.com/pedroslopez/whatsapp-web.js/tree/main/docs
173
+ [discord]: https://discord.gg/H7DqQs4
174
+ [gitHub]: https://github.com/pedroslopez/whatsapp-web.js
175
+ [npm]: https://npmjs.org/package/whatsapp-web.js
176
+ [nodejs]: https://nodejs.org/en/download/
177
+ [examples]: https://github.com/pedroslopez/whatsapp-web.js/blob/master/example.js
178
+ [auth-strategies]: https://wwebjs.dev/guide/creating-your-bot/authentication.html
179
+ [google-chrome]: https://wwebjs.dev/guide/creating-your-bot/handling-attachments.html#caveat-for-sending-videos-and-gifs
180
+ [deprecated-video]: https://www.youtube.com/watch?v=hv1R1rLeVVE
181
+ [gitHub-sponsors]: https://github.com/sponsors/pedroslopez
182
+ [support-payPal]: https://www.paypal.me/psla/
183
+ [digitalocean]: https://m.do.co/c/73f906a36ed4
184
+ [contributing]: https://github.com/pedroslopez/whatsapp-web.js/blob/main/CODE_OF_CONDUCT.md
185
+ [whatsapp]: https://whatsapp.com
package/example.js CHANGED
@@ -593,4 +593,9 @@ client.on('group_membership_request', async (notification) => {
593
593
  /** You can approve or reject the newly appeared membership request: */
594
594
  await client.approveGroupMembershipRequestss(notification.chatId, notification.author);
595
595
  await client.rejectGroupMembershipRequests(notification.chatId, notification.author);
596
- });
596
+ });
597
+
598
+ client.on('vote_update', (vote) => {
599
+ /** The vote that was affected: */
600
+ console.log(vote);
601
+ });
package/index.d.ts CHANGED
@@ -371,6 +371,14 @@ declare namespace WAWebJS {
371
371
 
372
372
  /** Emitted when the RemoteAuth session is saved successfully on the external Database */
373
373
  on(event: 'remote_session_saved', listener: () => void): this
374
+
375
+ /**
376
+ * Emitted when some poll option is selected or deselected,
377
+ * shows a user's current selected option(s) on the poll
378
+ */
379
+ on(event: 'vote_update', listener: (
380
+ vote: PollVote
381
+ ) => void): this
374
382
  }
375
383
 
376
384
  /** Current connection information */
@@ -1018,6 +1026,34 @@ declare namespace WAWebJS {
1018
1026
  constructor(pollName: string, pollOptions: Array<string>, options?: PollSendOptions)
1019
1027
  }
1020
1028
 
1029
+ /** Represents a Poll Vote on WhatsApp */
1030
+ export interface PollVote {
1031
+ /** The person who voted */
1032
+ voter: string;
1033
+
1034
+ /**
1035
+ * The selected poll option(s)
1036
+ * If it's an empty array, the user hasn't selected any options on the poll,
1037
+ * may occur when they deselected all poll options
1038
+ */
1039
+ selectedOptions: SelectedPollOption[];
1040
+
1041
+ /** Timestamp the option was selected or deselected at */
1042
+ interractedAtTs: number;
1043
+
1044
+ /** The poll creation message associated with the poll vote */
1045
+ parentMessage: Message;
1046
+ }
1047
+
1048
+ /** Selected poll option structure */
1049
+ export interface SelectedPollOption {
1050
+ /** The local selected option ID */
1051
+ id: number;
1052
+
1053
+ /** The option name */
1054
+ name: string;
1055
+ }
1056
+
1021
1057
  export interface Label {
1022
1058
  /** Label name */
1023
1059
  name: string,
@@ -1444,7 +1480,7 @@ declare namespace WAWebJS {
1444
1480
  message: string;
1445
1481
  isInviteV4Sent: boolean,
1446
1482
  }
1447
- };
1483
+ }
1448
1484
 
1449
1485
  /** An object that handles options for adding participants */
1450
1486
  export interface AddParticipantsOptions {
@@ -1468,7 +1504,7 @@ declare namespace WAWebJS {
1468
1504
  * @default ''
1469
1505
  */
1470
1506
  comment?: string
1471
- };
1507
+ }
1472
1508
 
1473
1509
  /** An object that handles the information about the group membership request */
1474
1510
  export interface GroupMembershipRequest {
@@ -1523,6 +1559,12 @@ declare namespace WAWebJS {
1523
1559
  setSubject: (subject: string) => Promise<boolean>;
1524
1560
  /** Updates the group description */
1525
1561
  setDescription: (description: string) => Promise<boolean>;
1562
+ /**
1563
+ * Updates the group setting to allow only admins to add members to the group.
1564
+ * @param {boolean} [adminsOnly=true] Enable or disable this option
1565
+ * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
1566
+ */
1567
+ setAddMembersAdminsOnly: (adminsOnly?: boolean) => Promise<boolean>;
1526
1568
  /** Updates the group settings to only allow admins to send messages
1527
1569
  * @param {boolean} [adminsOnly=true] Enable or disable this option
1528
1570
  * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whatsapp-web.js",
3
- "version": "1.23.1-alpha.4",
3
+ "version": "1.23.1-alpha.6",
4
4
  "description": "Library for interacting with the WhatsApp Web API ",
5
5
  "main": "./index.js",
6
6
  "typings": "./index.d.ts",
@@ -32,9 +32,9 @@
32
32
  "@pedroslopez/moduleraid": "^5.0.2",
33
33
  "fluent-ffmpeg": "2.1.2",
34
34
  "mime": "^3.0.0",
35
- "node-fetch": "^2.6.5",
36
- "node-webpmux": "3.1.0",
37
- "puppeteer": "^13.0.0"
35
+ "node-fetch": "^2.6.9",
36
+ "node-webpmux": "3.1.7",
37
+ "puppeteer": "^18.2.1"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node-fetch": "^2.5.12",
@@ -49,7 +49,7 @@
49
49
  "sinon": "^13.0.1"
50
50
  },
51
51
  "engines": {
52
- "node": ">=12.0.0"
52
+ "node": ">=18.0.0"
53
53
  },
54
54
  "optionalDependencies": {
55
55
  "archiver": "^5.3.1",
package/src/Client.js CHANGED
@@ -11,7 +11,7 @@ const { ExposeStore, LoadUtils } = require('./util/Injected');
11
11
  const ChatFactory = require('./factories/ChatFactory');
12
12
  const ContactFactory = require('./factories/ContactFactory');
13
13
  const WebCacheFactory = require('./webCache/WebCacheFactory');
14
- const { ClientInfo, Message, MessageMedia, Contact, Location, Poll, GroupNotification, Label, Call, Buttons, List, Reaction } = require('./structures');
14
+ const { ClientInfo, Message, MessageMedia, Contact, Location, Poll, PollVote, GroupNotification, Label, Call, Buttons, List, Reaction } = require('./structures');
15
15
  const LegacySessionAuth = require('./authStrategies/LegacySessionAuth');
16
16
  const NoAuth = require('./authStrategies/NoAuth');
17
17
 
@@ -54,6 +54,7 @@ const NoAuth = require('./authStrategies/NoAuth');
54
54
  * @fires Client#contact_changed
55
55
  * @fires Client#group_admin_changed
56
56
  * @fires Client#group_membership_request
57
+ * @fires Client#vote_update
57
58
  */
58
59
  class Client extends EventEmitter {
59
60
  constructor(options = {}) {
@@ -105,6 +106,8 @@ class Client extends EventEmitter {
105
106
  if(!browserArgs.find(arg => arg.includes('--user-agent'))) {
106
107
  browserArgs.push(`--user-agent=${this.options.userAgent}`);
107
108
  }
109
+ // navigator.webdriver fix
110
+ browserArgs.push('--disable-blink-features=AutomationControlled');
108
111
 
109
112
  browser = await puppeteer.launch({...puppeteerOpts, args: browserArgs});
110
113
  page = (await browser.pages())[0];
@@ -123,6 +126,18 @@ class Client extends EventEmitter {
123
126
  await this.authStrategy.afterBrowserInitialized();
124
127
  await this.initWebVersionCache();
125
128
 
129
+ // ocVesion (isOfficialClient patch)
130
+ await page.evaluateOnNewDocument(() => {
131
+ const originalError = Error;
132
+ //eslint-disable-next-line no-global-assign
133
+ Error = function (message) {
134
+ const error = new originalError(message);
135
+ const originalStack = error.stack;
136
+ if (error.stack.includes('moduleRaid')) error.stack = originalStack + '\n at https://web.whatsapp.com/vendors~lazy_loaded_low_priority_components.05e98054dbd60f980427.js:2:44';
137
+ return error;
138
+ };
139
+ });
140
+
126
141
  await page.goto(WhatsWebURL, {
127
142
  waitUntil: 'load',
128
143
  timeout: 0,
@@ -382,7 +397,7 @@ class Client extends EventEmitter {
382
397
  * @param {GroupNotification} notification GroupNotification with more information about the action
383
398
  */
384
399
  this.emit(Events.GROUP_ADMIN_CHANGED, notification);
385
- } else if (msg.subtype === 'created_membership_requests') {
400
+ } else if (msg.subtype === 'membership_approval_request') {
386
401
  /**
387
402
  * Emitted when some user requested to join the group
388
403
  * that has the membership approval mode turned on
@@ -671,6 +686,16 @@ class Client extends EventEmitter {
671
686
  this.emit(Events.MESSAGE_CIPHERTEXT, new Message(this, msg));
672
687
  });
673
688
 
689
+ await page.exposeFunction('onPollVoteEvent', (vote) => {
690
+ const _vote = new PollVote(this, vote);
691
+ /**
692
+ * Emitted when some poll option is selected or deselected,
693
+ * shows a user's current selected option(s) on the poll
694
+ * @event Client#vote_update
695
+ */
696
+ this.emit(Events.VOTE_UPDATE, _vote);
697
+ });
698
+
674
699
  await page.evaluate(() => {
675
700
  window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); });
676
701
  window.Store.Msg.on('change:type', (msg) => { window.onChangeMessageTypeEvent(window.WWebJS.getMessageModel(msg)); });
@@ -695,6 +720,10 @@ class Client extends EventEmitter {
695
720
  }
696
721
  });
697
722
  window.Store.Chat.on('change:unreadCount', (chat) => {window.onChatUnreadCountEvent(chat);});
723
+ window.Store.PollVote.on('add', (vote) => {
724
+ const pollVoteModel = window.WWebJS.getPollVoteModel(vote);
725
+ pollVoteModel && window.onPollVoteEvent(pollVoteModel);
726
+ });
698
727
 
699
728
  {
700
729
  const module = window.Store.createOrUpdateReactionsModule;
@@ -281,6 +281,27 @@ class GroupChat extends Chat {
281
281
  return true;
282
282
  }
283
283
 
284
+ /**
285
+ * Updates the group setting to allow only admins to add members to the group.
286
+ * @param {boolean} [adminsOnly=true] Enable or disable this option
287
+ * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
288
+ */
289
+ async setAddMembersAdminsOnly(adminsOnly=true) {
290
+ const success = await this.client.pupPage.evaluate(async (groupId, adminsOnly) => {
291
+ const chatWid = window.Store.WidFactory.createWid(groupId);
292
+ try {
293
+ const response = await window.Store.GroupUtils.setGroupMemberAddMode(chatWid, 'member_add_mode', adminsOnly ? 0 : 1);
294
+ return response.name === 'SetMemberAddModeResponseSuccess';
295
+ } catch (err) {
296
+ if(err.name === 'SmaxParsingFailure') return false;
297
+ throw err;
298
+ }
299
+ }, this.id._serialized, adminsOnly);
300
+
301
+ success && (this.groupMetadata.memberAddMode = adminsOnly ? 'admin_add' : 'all_member_add');
302
+ return success;
303
+ }
304
+
284
305
  /**
285
306
  * Updates the group settings to only allow admins to send messages.
286
307
  * @param {boolean} [adminsOnly=true] Enable or disable this option
@@ -295,12 +295,7 @@ class Message extends Base {
295
295
  this.allowMultipleAnswers = Boolean(!data.pollSelectableOptionsCount);
296
296
  this.pollInvalidated = data.pollInvalidated;
297
297
  this.isSentCagPollCreation = data.isSentCagPollCreation;
298
-
299
- delete this._data.pollName;
300
- delete this._data.pollOptions;
301
- delete this._data.pollSelectableOptionsCount;
302
- delete this._data.pollInvalidated;
303
- delete this._data.isSentCagPollCreation;
298
+ this.messageSecret = Object.keys(data.messageSecret).map((key) => data.messageSecret[key]);
304
299
  }
305
300
 
306
301
  return super._patch(data);
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ const Message = require('./Message');
4
+ const Base = require('./Base');
5
+
6
+ /**
7
+ * Selected poll option structure
8
+ * @typedef {Object} SelectedPollOption
9
+ * @property {number} id The local selected or deselected option ID
10
+ * @property {string} name The option name
11
+ */
12
+
13
+ /**
14
+ * Represents a Poll Vote on WhatsApp
15
+ * @extends {Base}
16
+ */
17
+ class PollVote extends Base {
18
+ constructor(client, data) {
19
+ super(client);
20
+
21
+ if (data) this._patch(data);
22
+ }
23
+
24
+ _patch(data) {
25
+ /**
26
+ * The person who voted
27
+ * @type {string}
28
+ */
29
+ this.voter = data.sender;
30
+
31
+ /**
32
+ * The selected poll option(s)
33
+ * If it's an empty array, the user hasn't selected any options on the poll,
34
+ * may occur when they deselected all poll options
35
+ * @type {SelectedPollOption[]}
36
+ */
37
+ this.selectedOptions =
38
+ data.selectedOptionLocalIds.length > 0
39
+ ? data.selectedOptionLocalIds.map((e) => ({
40
+ name: data.parentMessage.pollOptions.find((x) => x.localId === e).name,
41
+ localId: e
42
+ }))
43
+ : [];
44
+
45
+ /**
46
+ * Timestamp the option was selected or deselected at
47
+ * @type {number}
48
+ */
49
+ this.interractedAtTs = data.senderTimestampMs;
50
+
51
+ /**
52
+ * The poll creation message associated with the poll vote
53
+ * @type {Message}
54
+ */
55
+ this.parentMessage = new Message(this.client, data.parentMessage);
56
+
57
+ return super._patch(data);
58
+ }
59
+ }
60
+
61
+ module.exports = PollVote;
@@ -20,4 +20,5 @@ module.exports = {
20
20
  Payment: require('./Payment'),
21
21
  Reaction: require('./Reaction'),
22
22
  Poll: require('./Poll'),
23
+ PollVote: require('./PollVote')
23
24
  };
@@ -65,7 +65,8 @@ exports.Events = {
65
65
  STATE_CHANGED: 'change_state',
66
66
  BATTERY_CHANGED: 'change_battery',
67
67
  INCOMING_CALL: 'call',
68
- REMOTE_SESSION_SAVED: 'remote_session_saved'
68
+ REMOTE_SESSION_SAVED: 'remote_session_saved',
69
+ VOTE_UPDATE: 'vote_update'
69
70
  };
70
71
 
71
72
  /**
@@ -556,6 +556,15 @@ exports.LoadUtils = () => {
556
556
  return msg;
557
557
  };
558
558
 
559
+ window.WWebJS.getPollVoteModel = (vote) => {
560
+ const _vote = vote.serialize();
561
+ if (vote.parentMsgKey) {
562
+ const msg = window.Store.Msg.get(vote.parentMsgKey);
563
+ msg && (_vote.parentMessage = window.WWebJS.getMessageModel(msg));
564
+ return _vote;
565
+ }
566
+ return null;
567
+ };
559
568
 
560
569
  window.WWebJS.getChatModel = async chat => {
561
570