whatsapp-web.js 1.22.2-alpha.2 → 1.22.2-alpha.4
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/example.js +17 -1
- package/index.d.ts +28 -1
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/Client.js +13 -6
- package/src/structures/Message.js +15 -1
- package/src/structures/Poll.js +44 -0
- package/src/structures/index.js +1 -0
- package/src/util/Constants.js +1 -0
- package/src/util/Injected.js +22 -2
package/example.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { Client, Location, List, Buttons, LocalAuth } = require('./index');
|
|
1
|
+
const { Client, Location, Poll, List, Buttons, LocalAuth } = require('./index');
|
|
2
2
|
|
|
3
3
|
const client = new Client({
|
|
4
4
|
authStrategy: new LocalAuth(),
|
|
@@ -290,6 +290,22 @@ client.on('message', async msg => {
|
|
|
290
290
|
client.sendMessage(msg.from, list);
|
|
291
291
|
} else if (msg.body === '!reaction') {
|
|
292
292
|
msg.react('👍');
|
|
293
|
+
} else if (msg.body === '!sendpoll') {
|
|
294
|
+
/** By default the poll is created as a single choice poll: */
|
|
295
|
+
await msg.reply(new Poll('Winter or Summer?', ['Winter', 'Summer']));
|
|
296
|
+
/** If you want to provide a multiple choice poll, add allowMultipleAnswers as true: */
|
|
297
|
+
await msg.reply(new Poll('Cats or Dogs?', ['Cats', 'Dogs'], { allowMultipleAnswers: true }));
|
|
298
|
+
/**
|
|
299
|
+
* You can provide a custom message secret, it can be used as a poll ID:
|
|
300
|
+
* @note It has to be a unique vector with a length of 32
|
|
301
|
+
*/
|
|
302
|
+
await msg.reply(
|
|
303
|
+
new Poll('Cats or Dogs?', ['Cats', 'Dogs'], {
|
|
304
|
+
messageSecret: [
|
|
305
|
+
1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
306
|
+
]
|
|
307
|
+
})
|
|
308
|
+
);
|
|
293
309
|
} else if (msg.body === '!edit') {
|
|
294
310
|
if (msg.hasQuotedMsg) {
|
|
295
311
|
const quotedMsg = await msg.getQuotedMessage();
|
package/index.d.ts
CHANGED
|
@@ -707,6 +707,7 @@ declare namespace WAWebJS {
|
|
|
707
707
|
PROTOCOL = 'protocol',
|
|
708
708
|
REACTION = 'reaction',
|
|
709
709
|
TEMPLATE_BUTTON_REPLY = 'template_button_reply',
|
|
710
|
+
POLL_CREATION = 'poll_creation',
|
|
710
711
|
}
|
|
711
712
|
|
|
712
713
|
/** Client status */
|
|
@@ -866,6 +867,11 @@ declare namespace WAWebJS {
|
|
|
866
867
|
selectedRowId?: string,
|
|
867
868
|
/** Returns message in a raw format */
|
|
868
869
|
rawData: object,
|
|
870
|
+
pollName: string,
|
|
871
|
+
/** Avaiaible poll voting options */
|
|
872
|
+
pollOptions: string[],
|
|
873
|
+
/** False for a single choice poll, true for a multiple choice poll */
|
|
874
|
+
allowMultipleAnswers: boolean,
|
|
869
875
|
/*
|
|
870
876
|
* Reloads this Message object's data in-place with the latest values from WhatsApp Web.
|
|
871
877
|
* Note that the Message must still be in the web app cache for this to work, otherwise will return null.
|
|
@@ -946,6 +952,27 @@ declare namespace WAWebJS {
|
|
|
946
952
|
constructor(latitude: number, longitude: number, options?: LocationSendOptions)
|
|
947
953
|
}
|
|
948
954
|
|
|
955
|
+
/** Poll send options */
|
|
956
|
+
export interface PollSendOptions {
|
|
957
|
+
/** False for a single choice poll, true for a multiple choice poll (false by default) */
|
|
958
|
+
allowMultipleAnswers?: boolean,
|
|
959
|
+
/**
|
|
960
|
+
* The custom message secret, can be used as a poll ID
|
|
961
|
+
* @note It has to be a unique vector with a length of 32
|
|
962
|
+
*/
|
|
963
|
+
messageSecret: ?Array<number>
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/** Represents a Poll on WhatsApp */
|
|
967
|
+
export interface Poll {
|
|
968
|
+
pollName: string,
|
|
969
|
+
pollOptions: Array<{
|
|
970
|
+
name: string,
|
|
971
|
+
localId: number
|
|
972
|
+
}>,
|
|
973
|
+
options: PollSendOptions
|
|
974
|
+
}
|
|
975
|
+
|
|
949
976
|
export interface Label {
|
|
950
977
|
/** Label name */
|
|
951
978
|
name: string,
|
|
@@ -1037,7 +1064,7 @@ declare namespace WAWebJS {
|
|
|
1037
1064
|
static fromUrl: (url: string, options?: MediaFromURLOptions) => Promise<MessageMedia>
|
|
1038
1065
|
}
|
|
1039
1066
|
|
|
1040
|
-
export type MessageContent = string | MessageMedia | Location | Contact | Contact[] | List | Buttons
|
|
1067
|
+
export type MessageContent = string | MessageMedia | Location | Poll | Contact | Contact[] | List | Buttons
|
|
1041
1068
|
|
|
1042
1069
|
/**
|
|
1043
1070
|
* Represents a Contact on WhatsApp
|
package/index.js
CHANGED
|
@@ -18,6 +18,7 @@ module.exports = {
|
|
|
18
18
|
BusinessContact: require('./src/structures/BusinessContact'),
|
|
19
19
|
ClientInfo: require('./src/structures/ClientInfo'),
|
|
20
20
|
Location: require('./src/structures/Location'),
|
|
21
|
+
Poll: require('./src/structures/Poll'),
|
|
21
22
|
ProductMetadata: require('./src/structures/ProductMetadata'),
|
|
22
23
|
List: require('./src/structures/List'),
|
|
23
24
|
Buttons: require('./src/structures/Buttons'),
|
package/package.json
CHANGED
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, GroupNotification, Label, Call, Buttons, List, Reaction
|
|
14
|
+
const { ClientInfo, Message, MessageMedia, Contact, Location, Poll, GroupNotification, Label, Call, Buttons, List, Reaction } = require('./structures');
|
|
15
15
|
const LegacySessionAuth = require('./authStrategies/LegacySessionAuth');
|
|
16
16
|
const NoAuth = require('./authStrategies/NoAuth');
|
|
17
17
|
|
|
@@ -620,16 +620,20 @@ class Client extends EventEmitter {
|
|
|
620
620
|
}
|
|
621
621
|
});
|
|
622
622
|
|
|
623
|
-
await page.exposeFunction('onRemoveChatEvent', (chat) => {
|
|
623
|
+
await page.exposeFunction('onRemoveChatEvent', async (chat) => {
|
|
624
|
+
const _chat = await this.getChatById(chat.id);
|
|
625
|
+
|
|
624
626
|
/**
|
|
625
627
|
* Emitted when a chat is removed
|
|
626
628
|
* @event Client#chat_removed
|
|
627
629
|
* @param {Chat} chat
|
|
628
630
|
*/
|
|
629
|
-
this.emit(Events.CHAT_REMOVED,
|
|
631
|
+
this.emit(Events.CHAT_REMOVED, _chat);
|
|
630
632
|
});
|
|
631
633
|
|
|
632
|
-
await page.exposeFunction('onArchiveChatEvent', (chat, currState, prevState) => {
|
|
634
|
+
await page.exposeFunction('onArchiveChatEvent', async (chat, currState, prevState) => {
|
|
635
|
+
const _chat = await this.getChatById(chat.id);
|
|
636
|
+
|
|
633
637
|
/**
|
|
634
638
|
* Emitted when a chat is archived/unarchived
|
|
635
639
|
* @event Client#chat_archived
|
|
@@ -637,7 +641,7 @@ class Client extends EventEmitter {
|
|
|
637
641
|
* @param {boolean} currState
|
|
638
642
|
* @param {boolean} prevState
|
|
639
643
|
*/
|
|
640
|
-
this.emit(Events.CHAT_ARCHIVED,
|
|
644
|
+
this.emit(Events.CHAT_ARCHIVED, _chat, currState, prevState);
|
|
641
645
|
});
|
|
642
646
|
|
|
643
647
|
await page.exposeFunction('onEditMessageEvent', (msg, newBody, prevBody) => {
|
|
@@ -816,7 +820,7 @@ class Client extends EventEmitter {
|
|
|
816
820
|
/**
|
|
817
821
|
* Send a message to a specific chatId
|
|
818
822
|
* @param {string} chatId
|
|
819
|
-
* @param {string|MessageMedia|Location|Contact|Array<Contact>|Buttons|List} content
|
|
823
|
+
* @param {string|MessageMedia|Location|Poll|Contact|Array<Contact>|Buttons|List} content
|
|
820
824
|
* @param {MessageSendOptions} [options] - Options used when sending the message
|
|
821
825
|
*
|
|
822
826
|
* @returns {Promise<Message>} Message that was just sent
|
|
@@ -853,6 +857,9 @@ class Client extends EventEmitter {
|
|
|
853
857
|
} else if (content instanceof Location) {
|
|
854
858
|
internalOptions.location = content;
|
|
855
859
|
content = '';
|
|
860
|
+
} else if (content instanceof Poll) {
|
|
861
|
+
internalOptions.poll = content;
|
|
862
|
+
content = '';
|
|
856
863
|
} else if (content instanceof Contact) {
|
|
857
864
|
internalOptions.contactCard = content.id._serialized;
|
|
858
865
|
content = '';
|
|
@@ -51,7 +51,7 @@ class Message extends Base {
|
|
|
51
51
|
* Message content
|
|
52
52
|
* @type {string}
|
|
53
53
|
*/
|
|
54
|
-
this.body = this.hasMedia ? data.caption || '' : data.body || '';
|
|
54
|
+
this.body = this.hasMedia ? data.caption || '' : data.body || data.pollName || '';
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Message type
|
|
@@ -271,6 +271,20 @@ class Message extends Base {
|
|
|
271
271
|
this.selectedRowId = data.listResponse.singleSelectReply.selectedRowId;
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
if (this.type === MessageTypes.POLL_CREATION) {
|
|
275
|
+
this.pollName = data.pollName;
|
|
276
|
+
this.pollOptions = data.pollOptions;
|
|
277
|
+
this.allowMultipleAnswers = Boolean(!data.pollSelectableOptionsCount);
|
|
278
|
+
this.pollInvalidated = data.pollInvalidated;
|
|
279
|
+
this.isSentCagPollCreation = data.isSentCagPollCreation;
|
|
280
|
+
|
|
281
|
+
delete this._data.pollName;
|
|
282
|
+
delete this._data.pollOptions;
|
|
283
|
+
delete this._data.pollSelectableOptionsCount;
|
|
284
|
+
delete this._data.pollInvalidated;
|
|
285
|
+
delete this._data.isSentCagPollCreation;
|
|
286
|
+
}
|
|
287
|
+
|
|
274
288
|
return super._patch(data);
|
|
275
289
|
}
|
|
276
290
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Poll send options
|
|
5
|
+
* @typedef {Object} PollSendOptions
|
|
6
|
+
* @property {boolean} [allowMultipleAnswers=false] If false it is a single choice poll, otherwise it is a multiple choice poll (false by default)
|
|
7
|
+
* @property {?Array<number>} messageSecret The custom message secret, can be used as a poll ID. NOTE: it has to be a unique vector with a length of 32
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Represents a Poll on WhatsApp */
|
|
11
|
+
class Poll {
|
|
12
|
+
/**
|
|
13
|
+
* @param {string} pollName
|
|
14
|
+
* @param {Array<string>} pollOptions
|
|
15
|
+
* @param {PollSendOptions} options
|
|
16
|
+
*/
|
|
17
|
+
constructor(pollName, pollOptions, options = {}) {
|
|
18
|
+
/**
|
|
19
|
+
* The name of the poll
|
|
20
|
+
* @type {string}
|
|
21
|
+
*/
|
|
22
|
+
this.pollName = pollName.trim();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The array of poll options
|
|
26
|
+
* @type {Array.<{name: string, localId: number}>}
|
|
27
|
+
*/
|
|
28
|
+
this.pollOptions = pollOptions.map((option, index) => ({
|
|
29
|
+
name: option.trim(),
|
|
30
|
+
localId: index
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The send options for the poll
|
|
35
|
+
* @type {PollSendOptions}
|
|
36
|
+
*/
|
|
37
|
+
this.options = {
|
|
38
|
+
allowMultipleAnswers: options.allowMultipleAnswers === true,
|
|
39
|
+
messageSecret: options.messageSecret
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = Poll;
|
package/src/structures/index.js
CHANGED
package/src/util/Constants.js
CHANGED
package/src/util/Injected.js
CHANGED
|
@@ -62,7 +62,6 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|
|
62
62
|
/* eslint-disable no-undef, no-cond-assign */
|
|
63
63
|
window.Store.QueryExist = ((m = window.mR.findModule('queryExists')[0]) ? m.queryExists : window.mR.findModule('queryExist')[0].queryWidExists);
|
|
64
64
|
window.Store.ReplyUtils = (m = window.mR.findModule('canReplyMsg')).length > 0 && m[0];
|
|
65
|
-
if ((m = window.mR.findModule('ChatCollection')[0]) && m.ChatCollection && typeof m.ChatCollection.findImpl === 'undefined' && typeof m.ChatCollection._find !== 'undefined') m.ChatCollection.findImpl = m.ChatCollection._find;
|
|
66
65
|
/* eslint-enable no-undef, no-cond-assign */
|
|
67
66
|
|
|
68
67
|
window.Store.StickerTools = {
|
|
@@ -100,6 +99,9 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|
|
100
99
|
});
|
|
101
100
|
};
|
|
102
101
|
}
|
|
102
|
+
|
|
103
|
+
// eslint-disable-next-line no-undef
|
|
104
|
+
if ((m = window.mR.findModule('ChatCollection')[0]) && m.ChatCollection && typeof m.ChatCollection.findImpl === 'undefined' && typeof m.ChatCollection._find !== 'undefined') m.ChatCollection.findImpl = m.ChatCollection._find;
|
|
103
105
|
|
|
104
106
|
// TODO remove these once everybody has been updated to WWebJS with legacy sessions removed
|
|
105
107
|
const _linkPreview = window.mR.findModule('queryLinkPreview');
|
|
@@ -140,7 +142,7 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|
|
140
142
|
const modifiedFunction = (...args) => callback(originalFunction, ...args);
|
|
141
143
|
module[target.index][target.property] = modifiedFunction;
|
|
142
144
|
};
|
|
143
|
-
|
|
145
|
+
|
|
144
146
|
window.injectToFunction({ moduleId: 'mediaTypeFromProtobuf', index: 0, property: 'mediaTypeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage ? null : func(...args); });
|
|
145
147
|
|
|
146
148
|
window.injectToFunction({ moduleId: 'typeAttributeFromProtobuf', index: 0, property: 'typeAttributeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage || proto.groupInviteMessage ? 'text' : func(...args); });
|
|
@@ -213,6 +215,23 @@ exports.LoadUtils = () => {
|
|
|
213
215
|
delete options.location;
|
|
214
216
|
}
|
|
215
217
|
|
|
218
|
+
let _pollOptions = {};
|
|
219
|
+
if (options.poll) {
|
|
220
|
+
const { pollName, pollOptions } = options.poll;
|
|
221
|
+
const { allowMultipleAnswers, messageSecret } = options.poll.options;
|
|
222
|
+
_pollOptions = {
|
|
223
|
+
type: 'poll_creation',
|
|
224
|
+
pollName: pollName,
|
|
225
|
+
pollOptions: pollOptions,
|
|
226
|
+
pollSelectableOptionsCount: allowMultipleAnswers ? 0 : 1,
|
|
227
|
+
messageSecret:
|
|
228
|
+
Array.isArray(messageSecret) && messageSecret.length === 32
|
|
229
|
+
? new Uint8Array(messageSecret)
|
|
230
|
+
: window.crypto.getRandomValues(new Uint8Array(32))
|
|
231
|
+
};
|
|
232
|
+
delete options.poll;
|
|
233
|
+
}
|
|
234
|
+
|
|
216
235
|
let vcardOptions = {};
|
|
217
236
|
if (options.contactCard) {
|
|
218
237
|
let contact = window.Store.Contact.get(options.contactCard);
|
|
@@ -332,6 +351,7 @@ exports.LoadUtils = () => {
|
|
|
332
351
|
type: 'chat',
|
|
333
352
|
...ephemeralFields,
|
|
334
353
|
...locationOptions,
|
|
354
|
+
..._pollOptions,
|
|
335
355
|
...attOptions,
|
|
336
356
|
...(attOptions.toJSON ? attOptions.toJSON() : {}),
|
|
337
357
|
...quotedMsgOptions,
|