whatsapp-web-sj.js 1.26.0

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.
Files changed (52) hide show
  1. package/.env.example +3 -0
  2. package/CODE_OF_CONDUCT.md +133 -0
  3. package/LICENSE +201 -0
  4. package/README.md +185 -0
  5. package/example.js +634 -0
  6. package/index.d.ts +1842 -0
  7. package/index.js +32 -0
  8. package/package.json +55 -0
  9. package/shell.js +36 -0
  10. package/src/Client.js +1747 -0
  11. package/src/authStrategies/BaseAuthStrategy.js +27 -0
  12. package/src/authStrategies/LocalAuth.js +56 -0
  13. package/src/authStrategies/NoAuth.js +12 -0
  14. package/src/authStrategies/RemoteAuth.js +204 -0
  15. package/src/factories/ChatFactory.js +16 -0
  16. package/src/factories/ContactFactory.js +16 -0
  17. package/src/structures/Base.js +22 -0
  18. package/src/structures/BusinessContact.js +21 -0
  19. package/src/structures/Buttons.js +82 -0
  20. package/src/structures/Call.js +76 -0
  21. package/src/structures/Chat.js +275 -0
  22. package/src/structures/ClientInfo.js +71 -0
  23. package/src/structures/Contact.js +208 -0
  24. package/src/structures/GroupChat.js +475 -0
  25. package/src/structures/GroupNotification.js +104 -0
  26. package/src/structures/Label.js +50 -0
  27. package/src/structures/List.js +79 -0
  28. package/src/structures/Location.js +61 -0
  29. package/src/structures/Message.js +711 -0
  30. package/src/structures/MessageMedia.js +111 -0
  31. package/src/structures/Order.js +52 -0
  32. package/src/structures/Payment.js +79 -0
  33. package/src/structures/Poll.js +44 -0
  34. package/src/structures/PollVote.js +61 -0
  35. package/src/structures/PrivateChat.js +13 -0
  36. package/src/structures/PrivateContact.js +13 -0
  37. package/src/structures/Product.js +68 -0
  38. package/src/structures/ProductMetadata.js +25 -0
  39. package/src/structures/Reaction.js +69 -0
  40. package/src/structures/index.js +24 -0
  41. package/src/util/Constants.js +176 -0
  42. package/src/util/Injected/AuthStore/AuthStore.js +17 -0
  43. package/src/util/Injected/AuthStore/LegacyAuthStore.js +22 -0
  44. package/src/util/Injected/LegacyStore.js +146 -0
  45. package/src/util/Injected/Store.js +167 -0
  46. package/src/util/Injected/Utils.js +1017 -0
  47. package/src/util/InterfaceController.js +127 -0
  48. package/src/util/Util.js +186 -0
  49. package/src/webCache/LocalWebCache.js +40 -0
  50. package/src/webCache/RemoteWebCache.js +40 -0
  51. package/src/webCache/WebCache.js +14 -0
  52. package/src/webCache/WebCacheFactory.js +20 -0
@@ -0,0 +1,475 @@
1
+ 'use strict';
2
+
3
+ const Chat = require('./Chat');
4
+
5
+ /**
6
+ * Group participant information
7
+ * @typedef {Object} GroupParticipant
8
+ * @property {ContactId} id
9
+ * @property {boolean} isAdmin
10
+ * @property {boolean} isSuperAdmin
11
+ */
12
+
13
+ /**
14
+ * Represents a Group Chat on WhatsApp
15
+ * @extends {Chat}
16
+ */
17
+ class GroupChat extends Chat {
18
+ _patch(data) {
19
+ this.groupMetadata = data.groupMetadata;
20
+
21
+ return super._patch(data);
22
+ }
23
+
24
+ /**
25
+ * Gets the group owner
26
+ * @type {ContactId}
27
+ */
28
+ get owner() {
29
+ return this.groupMetadata.owner;
30
+ }
31
+
32
+ /**
33
+ * Gets the date at which the group was created
34
+ * @type {date}
35
+ */
36
+ get createdAt() {
37
+ return new Date(this.groupMetadata.creation * 1000);
38
+ }
39
+
40
+ /**
41
+ * Gets the group description
42
+ * @type {string}
43
+ */
44
+ get description() {
45
+ return this.groupMetadata.desc;
46
+ }
47
+
48
+ /**
49
+ * Gets the group participants
50
+ * @type {Array<GroupParticipant>}
51
+ */
52
+ get participants() {
53
+ return this.groupMetadata.participants;
54
+ }
55
+
56
+ /**
57
+ * An object that handles the result for {@link addParticipants} method
58
+ * @typedef {Object} AddParticipantsResult
59
+ * @property {number} code The code of the result
60
+ * @property {string} message The result message
61
+ * @property {boolean} isInviteV4Sent Indicates if the inviteV4 was sent to the partitipant
62
+ */
63
+
64
+ /**
65
+ * An object that handles options for adding participants
66
+ * @typedef {Object} AddParticipnatsOptions
67
+ * @property {Array<number>|number} [sleep = [250, 500]] The number of milliseconds to wait before adding the next participant. If it is an array, a random sleep time between the sleep[0] and sleep[1] values will be added (the difference must be >=100 ms, otherwise, a random sleep time between sleep[1] and sleep[1] + 100 will be added). If sleep is a number, a sleep time equal to its value will be added. By default, sleep is an array with a value of [250, 500]
68
+ * @property {boolean} [autoSendInviteV4 = true] If true, the inviteV4 will be sent to those participants who have restricted others from being automatically added to groups, otherwise the inviteV4 won't be sent (true by default)
69
+ * @property {string} [comment = ''] The comment to be added to an inviteV4 (empty string by default)
70
+ */
71
+
72
+ /**
73
+ * Adds a list of participants by ID to the group
74
+ * @param {string|Array<string>} participantIds
75
+ * @param {AddParticipnatsOptions} options An object thay handles options for adding participants
76
+ * @returns {Promise<Object.<string, AddParticipantsResult>|string>} Returns an object with the resulting data or an error message as a string
77
+ */
78
+ async addParticipants(participantIds, options = {}) {
79
+ return await this.client.pupPage.evaluate(async (groupId, participantIds, options) => {
80
+ const { sleep = [250, 500], autoSendInviteV4 = true, comment = '' } = options;
81
+ const participantData = {};
82
+
83
+ !Array.isArray(participantIds) && (participantIds = [participantIds]);
84
+ const groupWid = window.Store.WidFactory.createWid(groupId);
85
+ const group = await window.Store.Chat.find(groupWid);
86
+ const participantWids = participantIds.map((p) => window.Store.WidFactory.createWid(p));
87
+
88
+ const errorCodes = {
89
+ default: 'An unknown error occupied while adding a participant',
90
+ isGroupEmpty: 'AddParticipantsError: The participant can\'t be added to an empty group',
91
+ iAmNotAdmin: 'AddParticipantsError: You have no admin rights to add a participant to a group',
92
+ 200: 'The participant was added successfully',
93
+ 403: 'The participant can be added by sending private invitation only',
94
+ 404: 'The phone number is not registered on WhatsApp',
95
+ 408: 'You cannot add this participant because they recently left the group',
96
+ 409: 'The participant is already a group member',
97
+ 417: 'The participant can\'t be added to the community. You can invite them privately to join this group through its invite link',
98
+ 419: 'The participant can\'t be added because the group is full'
99
+ };
100
+
101
+ await window.Store.GroupQueryAndUpdate(groupWid);
102
+ const groupMetadata = group.groupMetadata;
103
+ const groupParticipants = groupMetadata?.participants;
104
+
105
+ if (!groupParticipants) {
106
+ return errorCodes.isGroupEmpty;
107
+ }
108
+
109
+ if (!group.iAmAdmin()) {
110
+ return errorCodes.iAmNotAdmin;
111
+ }
112
+
113
+ const _getSleepTime = (sleep) => {
114
+ if (!Array.isArray(sleep) || sleep.length === 2 && sleep[0] === sleep[1]) {
115
+ return sleep;
116
+ }
117
+ if (sleep.length === 1) {
118
+ return sleep[0];
119
+ }
120
+ (sleep[1] - sleep[0]) < 100 && (sleep[0] = sleep[1]) && (sleep[1] += 100);
121
+ return Math.floor(Math.random() * (sleep[1] - sleep[0] + 1)) + sleep[0];
122
+ };
123
+
124
+ for (const pWid of participantWids) {
125
+ const pId = pWid._serialized;
126
+
127
+ participantData[pId] = {
128
+ code: undefined,
129
+ message: undefined,
130
+ isInviteV4Sent: false
131
+ };
132
+
133
+ if (groupParticipants.some(p => p.id._serialized === pId)) {
134
+ participantData[pId].code = 409;
135
+ participantData[pId].message = errorCodes[409];
136
+ continue;
137
+ }
138
+
139
+ if (!(await window.Store.QueryExist(pWid))?.wid) {
140
+ participantData[pId].code = 404;
141
+ participantData[pId].message = errorCodes[404];
142
+ continue;
143
+ }
144
+
145
+ const rpcResult =
146
+ await window.WWebJS.getAddParticipantsRpcResult(groupMetadata, groupWid, pWid);
147
+ const { code: rpcResultCode } = rpcResult;
148
+
149
+ participantData[pId].code = rpcResultCode;
150
+ participantData[pId].message =
151
+ errorCodes[rpcResultCode] || errorCodes.default;
152
+
153
+ if (autoSendInviteV4 && rpcResultCode === 403) {
154
+ let userChat, isInviteV4Sent = false;
155
+ window.Store.Contact.gadd(pWid, { silent: true });
156
+
157
+ if (rpcResult.name === 'ParticipantRequestCodeCanBeSent' &&
158
+ (userChat = await window.Store.Chat.find(pWid))) {
159
+ const groupName = group.formattedTitle || group.name;
160
+ const res = await window.Store.GroupInviteV4.sendGroupInviteMessage(
161
+ userChat,
162
+ group.id._serialized,
163
+ groupName,
164
+ rpcResult.inviteV4Code,
165
+ rpcResult.inviteV4CodeExp,
166
+ comment,
167
+ await window.WWebJS.getProfilePicThumbToBase64(groupWid)
168
+ );
169
+ isInviteV4Sent = window.compareWwebVersions(window.Debug.VERSION, '<', '2.2335.6')
170
+ ? res === 'OK'
171
+ : res.messageSendResult === 'OK';
172
+ }
173
+
174
+ participantData[pId].isInviteV4Sent = isInviteV4Sent;
175
+ }
176
+
177
+ sleep &&
178
+ participantWids.length > 1 &&
179
+ participantWids.indexOf(pWid) !== participantWids.length - 1 &&
180
+ (await new Promise((resolve) => setTimeout(resolve, _getSleepTime(sleep))));
181
+ }
182
+
183
+ return participantData;
184
+ }, this.id._serialized, participantIds, options);
185
+ }
186
+
187
+ /**
188
+ * Removes a list of participants by ID to the group
189
+ * @param {Array<string>} participantIds
190
+ * @returns {Promise<{ status: number }>}
191
+ */
192
+ async removeParticipants(participantIds) {
193
+ return await this.client.pupPage.evaluate(async (chatId, participantIds) => {
194
+ const chatWid = window.Store.WidFactory.createWid(chatId);
195
+ const chat = await window.Store.Chat.find(chatWid);
196
+ const participants = participantIds.map(p => {
197
+ return chat.groupMetadata.participants.get(p);
198
+ }).filter(p => Boolean(p));
199
+ await window.Store.GroupParticipants.removeParticipants(chat, participants);
200
+ return { status: 200 };
201
+ }, this.id._serialized, participantIds);
202
+ }
203
+
204
+ /**
205
+ * Promotes participants by IDs to admins
206
+ * @param {Array<string>} participantIds
207
+ * @returns {Promise<{ status: number }>} Object with status code indicating if the operation was successful
208
+ */
209
+ async promoteParticipants(participantIds) {
210
+ return await this.client.pupPage.evaluate(async (chatId, participantIds) => {
211
+ const chatWid = window.Store.WidFactory.createWid(chatId);
212
+ const chat = await window.Store.Chat.find(chatWid);
213
+ const participants = participantIds.map(p => {
214
+ return chat.groupMetadata.participants.get(p);
215
+ }).filter(p => Boolean(p));
216
+ await window.Store.GroupParticipants.promoteParticipants(chat, participants);
217
+ return { status: 200 };
218
+ }, this.id._serialized, participantIds);
219
+ }
220
+
221
+ /**
222
+ * Demotes participants by IDs to regular users
223
+ * @param {Array<string>} participantIds
224
+ * @returns {Promise<{ status: number }>} Object with status code indicating if the operation was successful
225
+ */
226
+ async demoteParticipants(participantIds) {
227
+ return await this.client.pupPage.evaluate(async (chatId, participantIds) => {
228
+ const chatWid = window.Store.WidFactory.createWid(chatId);
229
+ const chat = await window.Store.Chat.find(chatWid);
230
+ const participants = participantIds.map(p => {
231
+ return chat.groupMetadata.participants.get(p);
232
+ }).filter(p => Boolean(p));
233
+ await window.Store.GroupParticipants.demoteParticipants(chat, participants);
234
+ return { status: 200 };
235
+ }, this.id._serialized, participantIds);
236
+ }
237
+
238
+ /**
239
+ * Updates the group subject
240
+ * @param {string} subject
241
+ * @returns {Promise<boolean>} Returns true if the subject was properly updated. This can return false if the user does not have the necessary permissions.
242
+ */
243
+ async setSubject(subject) {
244
+ const success = await this.client.pupPage.evaluate(async (chatId, subject) => {
245
+ const chatWid = window.Store.WidFactory.createWid(chatId);
246
+ try {
247
+ await window.Store.GroupUtils.setGroupSubject(chatWid, subject);
248
+ return true;
249
+ } catch (err) {
250
+ if(err.name === 'ServerStatusCodeError') return false;
251
+ throw err;
252
+ }
253
+ }, this.id._serialized, subject);
254
+
255
+ if(!success) return false;
256
+ this.name = subject;
257
+ return true;
258
+ }
259
+
260
+ /**
261
+ * Updates the group description
262
+ * @param {string} description
263
+ * @returns {Promise<boolean>} Returns true if the description was properly updated. This can return false if the user does not have the necessary permissions.
264
+ */
265
+ async setDescription(description) {
266
+ const success = await this.client.pupPage.evaluate(async (chatId, description) => {
267
+ const chatWid = window.Store.WidFactory.createWid(chatId);
268
+ let descId = window.Store.GroupMetadata.get(chatWid).descId;
269
+ let newId = await window.Store.MsgKey.newId();
270
+ try {
271
+ await window.Store.GroupUtils.setGroupDescription(chatWid, description, newId, descId);
272
+ return true;
273
+ } catch (err) {
274
+ if(err.name === 'ServerStatusCodeError') return false;
275
+ throw err;
276
+ }
277
+ }, this.id._serialized, description);
278
+
279
+ if(!success) return false;
280
+ this.groupMetadata.desc = description;
281
+ return true;
282
+ }
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
+
305
+ /**
306
+ * Updates the group settings to only allow admins to send messages.
307
+ * @param {boolean} [adminsOnly=true] Enable or disable this option
308
+ * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
309
+ */
310
+ async setMessagesAdminsOnly(adminsOnly=true) {
311
+ const success = await this.client.pupPage.evaluate(async (chatId, adminsOnly) => {
312
+ const chatWid = window.Store.WidFactory.createWid(chatId);
313
+ try {
314
+ await window.Store.GroupUtils.setGroupProperty(chatWid, 'announcement', adminsOnly ? 1 : 0);
315
+ return true;
316
+ } catch (err) {
317
+ if(err.name === 'ServerStatusCodeError') return false;
318
+ throw err;
319
+ }
320
+ }, this.id._serialized, adminsOnly);
321
+
322
+ if(!success) return false;
323
+
324
+ this.groupMetadata.announce = adminsOnly;
325
+ return true;
326
+ }
327
+
328
+ /**
329
+ * Updates the group settings to only allow admins to edit group info (title, description, photo).
330
+ * @param {boolean} [adminsOnly=true] Enable or disable this option
331
+ * @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
332
+ */
333
+ async setInfoAdminsOnly(adminsOnly=true) {
334
+ const success = await this.client.pupPage.evaluate(async (chatId, adminsOnly) => {
335
+ const chatWid = window.Store.WidFactory.createWid(chatId);
336
+ try {
337
+ await window.Store.GroupUtils.setGroupProperty(chatWid, 'restrict', adminsOnly ? 1 : 0);
338
+ return true;
339
+ } catch (err) {
340
+ if(err.name === 'ServerStatusCodeError') return false;
341
+ throw err;
342
+ }
343
+ }, this.id._serialized, adminsOnly);
344
+
345
+ if(!success) return false;
346
+
347
+ this.groupMetadata.restrict = adminsOnly;
348
+ return true;
349
+ }
350
+
351
+ /**
352
+ * Deletes the group's picture.
353
+ * @returns {Promise<boolean>} Returns true if the picture was properly deleted. This can return false if the user does not have the necessary permissions.
354
+ */
355
+ async deletePicture() {
356
+ const success = await this.client.pupPage.evaluate((chatid) => {
357
+ return window.WWebJS.deletePicture(chatid);
358
+ }, this.id._serialized);
359
+
360
+ return success;
361
+ }
362
+
363
+ /**
364
+ * Sets the group's picture.
365
+ * @param {MessageMedia} media
366
+ * @returns {Promise<boolean>} Returns true if the picture was properly updated. This can return false if the user does not have the necessary permissions.
367
+ */
368
+ async setPicture(media) {
369
+ const success = await this.client.pupPage.evaluate((chatid, media) => {
370
+ return window.WWebJS.setPicture(chatid, media);
371
+ }, this.id._serialized, media);
372
+
373
+ return success;
374
+ }
375
+
376
+ /**
377
+ * Gets the invite code for a specific group
378
+ * @returns {Promise<string>} Group's invite code
379
+ */
380
+ async getInviteCode() {
381
+ const codeRes = await this.client.pupPage.evaluate(async chatId => {
382
+ const chatWid = window.Store.WidFactory.createWid(chatId);
383
+ try {
384
+ return window.compareWwebVersions(window.Debug.VERSION, '>=', '2.3000.0')
385
+ ? await window.Store.GroupInvite.queryGroupInviteCode(chatWid, true)
386
+ : await window.Store.GroupInvite.queryGroupInviteCode(chatWid);
387
+ }
388
+ catch (err) {
389
+ if(err.name === 'ServerStatusCodeError') return undefined;
390
+ throw err;
391
+ }
392
+ }, this.id._serialized);
393
+
394
+ return codeRes?.code;
395
+ }
396
+
397
+ /**
398
+ * Invalidates the current group invite code and generates a new one
399
+ * @returns {Promise<string>} New invite code
400
+ */
401
+ async revokeInvite() {
402
+ const codeRes = await this.client.pupPage.evaluate(chatId => {
403
+ const chatWid = window.Store.WidFactory.createWid(chatId);
404
+ return window.Store.GroupInvite.resetGroupInviteCode(chatWid);
405
+ }, this.id._serialized);
406
+
407
+ return codeRes.code;
408
+ }
409
+
410
+ /**
411
+ * An object that handles the information about the group membership request
412
+ * @typedef {Object} GroupMembershipRequest
413
+ * @property {Object} id The wid of a user who requests to enter the group
414
+ * @property {Object} addedBy The wid of a user who created that request
415
+ * @property {Object|null} parentGroupId The wid of a community parent group to which the current group is linked
416
+ * @property {string} requestMethod The method used to create the request: NonAdminAdd/InviteLink/LinkedGroupJoin
417
+ * @property {number} t The timestamp the request was created at
418
+ */
419
+
420
+ /**
421
+ * Gets an array of membership requests
422
+ * @returns {Promise<Array<GroupMembershipRequest>>} An array of membership requests
423
+ */
424
+ async getGroupMembershipRequests() {
425
+ return await this.client.getGroupMembershipRequests(this.id._serialized);
426
+ }
427
+
428
+ /**
429
+ * An object that handles the result for membership request action
430
+ * @typedef {Object} MembershipRequestActionResult
431
+ * @property {string} requesterId User ID whos membership request was approved/rejected
432
+ * @property {number} error An error code that occurred during the operation for the participant
433
+ * @property {string} message A message with a result of membership request action
434
+ */
435
+
436
+ /**
437
+ * An object that handles options for {@link approveGroupMembershipRequests} and {@link rejectGroupMembershipRequests} methods
438
+ * @typedef {Object} MembershipRequestActionOptions
439
+ * @property {Array<string>|string|null} requesterIds User ID/s who requested to join the group, if no value is provided, the method will search for all membership requests for that group
440
+ * @property {Array<number>|number|null} sleep The number of milliseconds to wait before performing an operation for the next requester. If it is an array, a random sleep time between the sleep[0] and sleep[1] values will be added (the difference must be >=100 ms, otherwise, a random sleep time between sleep[1] and sleep[1] + 100 will be added). If sleep is a number, a sleep time equal to its value will be added. By default, sleep is an array with a value of [250, 500]
441
+ */
442
+
443
+ /**
444
+ * Approves membership requests if any
445
+ * @param {MembershipRequestActionOptions} options Options for performing a membership request action
446
+ * @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were approved and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
447
+ */
448
+ async approveGroupMembershipRequests(options = {}) {
449
+ return await this.client.approveGroupMembershipRequests(this.id._serialized, options);
450
+ }
451
+
452
+ /**
453
+ * Rejects membership requests if any
454
+ * @param {MembershipRequestActionOptions} options Options for performing a membership request action
455
+ * @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were rejected and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
456
+ */
457
+ async rejectGroupMembershipRequests(options = {}) {
458
+ return await this.client.rejectGroupMembershipRequests(this.id._serialized, options);
459
+ }
460
+
461
+ /**
462
+ * Makes the bot leave the group
463
+ * @returns {Promise}
464
+ */
465
+ async leave() {
466
+ await this.client.pupPage.evaluate(async chatId => {
467
+ const chatWid = window.Store.WidFactory.createWid(chatId);
468
+ const chat = await window.Store.Chat.find(chatWid);
469
+ return window.Store.GroupUtils.sendExitGroup(chat);
470
+ }, this.id._serialized);
471
+ }
472
+
473
+ }
474
+
475
+ module.exports = GroupChat;
@@ -0,0 +1,104 @@
1
+ 'use strict';
2
+
3
+ const Base = require('./Base');
4
+
5
+ /**
6
+ * Represents a GroupNotification on WhatsApp
7
+ * @extends {Base}
8
+ */
9
+ class GroupNotification extends Base {
10
+ constructor(client, data) {
11
+ super(client);
12
+
13
+ if(data) this._patch(data);
14
+ }
15
+
16
+ _patch(data) {
17
+ /**
18
+ * ID that represents the groupNotification
19
+ * @type {object}
20
+ */
21
+ this.id = data.id;
22
+
23
+ /**
24
+ * Extra content
25
+ * @type {string}
26
+ */
27
+ this.body = data.body || '';
28
+
29
+ /**
30
+ * GroupNotification type
31
+ * @type {GroupNotificationTypes}
32
+ */
33
+ this.type = data.subtype;
34
+
35
+ /**
36
+ * Unix timestamp for when the groupNotification was created
37
+ * @type {number}
38
+ */
39
+ this.timestamp = data.t;
40
+
41
+ /**
42
+ * ID for the Chat that this groupNotification was sent for.
43
+ *
44
+ * @type {string}
45
+ */
46
+ this.chatId = typeof (data.id.remote) === 'object' ? data.id.remote._serialized : data.id.remote;
47
+
48
+ /**
49
+ * ContactId for the user that produced the GroupNotification.
50
+ * @type {string}
51
+ */
52
+ this.author = typeof (data.author) === 'object' ? data.author._serialized : data.author;
53
+
54
+ /**
55
+ * Contact IDs for the users that were affected by this GroupNotification.
56
+ * @type {Array<string>}
57
+ */
58
+ this.recipientIds = [];
59
+
60
+ if (data.recipients) {
61
+ this.recipientIds = data.recipients;
62
+ }
63
+
64
+ return super._patch(data);
65
+ }
66
+
67
+ /**
68
+ * Returns the Chat this groupNotification was sent in
69
+ * @returns {Promise<Chat>}
70
+ */
71
+ getChat() {
72
+ return this.client.getChatById(this.chatId);
73
+ }
74
+
75
+ /**
76
+ * Returns the Contact this GroupNotification was produced by
77
+ * @returns {Promise<Contact>}
78
+ */
79
+ getContact() {
80
+ return this.client.getContactById(this.author);
81
+ }
82
+
83
+ /**
84
+ * Returns the Contacts affected by this GroupNotification.
85
+ * @returns {Promise<Array<Contact>>}
86
+ */
87
+ async getRecipients() {
88
+ return await Promise.all(this.recipientIds.map(async m => await this.client.getContactById(m)));
89
+ }
90
+
91
+ /**
92
+ * Sends a message to the same chat this GroupNotification was produced in.
93
+ *
94
+ * @param {string|MessageMedia|Location} content
95
+ * @param {object} options
96
+ * @returns {Promise<Message>}
97
+ */
98
+ async reply(content, options={}) {
99
+ return this.client.sendMessage(this.chatId, content, options);
100
+ }
101
+
102
+ }
103
+
104
+ module.exports = GroupNotification;
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ const Base = require('./Base');
4
+ // eslint-disable-next-line no-unused-vars
5
+ const Chat = require('./Chat');
6
+
7
+ /**
8
+ * WhatsApp Business Label information
9
+ */
10
+ class Label extends Base {
11
+ /**
12
+ * @param {Base} client
13
+ * @param {object} labelData
14
+ */
15
+ constructor(client, labelData){
16
+ super(client);
17
+
18
+ if(labelData) this._patch(labelData);
19
+ }
20
+
21
+ _patch(labelData){
22
+ /**
23
+ * Label ID
24
+ * @type {string}
25
+ */
26
+ this.id = labelData.id;
27
+
28
+ /**
29
+ * Label name
30
+ * @type {string}
31
+ */
32
+ this.name = labelData.name;
33
+
34
+ /**
35
+ * Label hex color
36
+ * @type {string}
37
+ */
38
+ this.hexColor = labelData.hexColor;
39
+ }
40
+ /**
41
+ * Get all chats that have been assigned this Label
42
+ * @returns {Promise<Array<Chat>>}
43
+ */
44
+ async getChats(){
45
+ return this.client.getChatsByLabelId(this.id);
46
+ }
47
+
48
+ }
49
+
50
+ module.exports = Label;