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,111 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const mime = require('mime');
6
+ const fetch = require('node-fetch');
7
+ const { URL } = require('url');
8
+
9
+ /**
10
+ * Media attached to a message
11
+ * @param {string} mimetype MIME type of the attachment
12
+ * @param {string} data Base64-encoded data of the file
13
+ * @param {?string} filename Document file name. Value can be null
14
+ * @param {?number} filesize Document file size in bytes. Value can be null
15
+ */
16
+ class MessageMedia {
17
+ constructor(mimetype, data, filename, filesize) {
18
+ /**
19
+ * MIME type of the attachment
20
+ * @type {string}
21
+ */
22
+ this.mimetype = mimetype;
23
+
24
+ /**
25
+ * Base64 encoded data that represents the file
26
+ * @type {string}
27
+ */
28
+ this.data = data;
29
+
30
+ /**
31
+ * Document file name. Value can be null
32
+ * @type {?string}
33
+ */
34
+ this.filename = filename;
35
+
36
+ /**
37
+ * Document file size in bytes. Value can be null
38
+ * @type {?number}
39
+ */
40
+ this.filesize = filesize;
41
+ }
42
+
43
+ /**
44
+ * Creates a MessageMedia instance from a local file path
45
+ * @param {string} filePath
46
+ * @returns {MessageMedia}
47
+ */
48
+ static fromFilePath(filePath) {
49
+ const b64data = fs.readFileSync(filePath, {encoding: 'base64'});
50
+ const mimetype = mime.getType(filePath);
51
+ const filename = path.basename(filePath);
52
+
53
+ return new MessageMedia(mimetype, b64data, filename);
54
+ }
55
+
56
+ /**
57
+ * Creates a MessageMedia instance from a URL
58
+ * @param {string} url
59
+ * @param {Object} [options]
60
+ * @param {boolean} [options.unsafeMime=false]
61
+ * @param {string} [options.filename]
62
+ * @param {object} [options.client]
63
+ * @param {object} [options.reqOptions]
64
+ * @param {number} [options.reqOptions.size=0]
65
+ * @returns {Promise<MessageMedia>}
66
+ */
67
+ static async fromUrl(url, options = {}) {
68
+ const pUrl = new URL(url);
69
+ let mimetype = mime.getType(pUrl.pathname);
70
+
71
+ if (!mimetype && !options.unsafeMime)
72
+ throw new Error('Unable to determine MIME type using URL. Set unsafeMime to true to download it anyway.');
73
+
74
+ async function fetchData (url, options) {
75
+ const reqOptions = Object.assign({ headers: { accept: 'image/* video/* text/* audio/*' } }, options);
76
+ const response = await fetch(url, reqOptions);
77
+ const mime = response.headers.get('Content-Type');
78
+ const size = response.headers.get('Content-Length');
79
+
80
+ const contentDisposition = response.headers.get('Content-Disposition');
81
+ const name = contentDisposition ? contentDisposition.match(/((?<=filename=")(.*)(?="))/) : null;
82
+
83
+ let data = '';
84
+ if (response.buffer) {
85
+ data = (await response.buffer()).toString('base64');
86
+ } else {
87
+ const bArray = new Uint8Array(await response.arrayBuffer());
88
+ bArray.forEach((b) => {
89
+ data += String.fromCharCode(b);
90
+ });
91
+ data = btoa(data);
92
+ }
93
+
94
+ return { data, mime, name, size };
95
+ }
96
+
97
+ const res = options.client
98
+ ? (await options.client.pupPage.evaluate(fetchData, url, options.reqOptions))
99
+ : (await fetchData(url, options.reqOptions));
100
+
101
+ const filename = options.filename ||
102
+ (res.name ? res.name[0] : (pUrl.pathname.split('/').pop() || 'file'));
103
+
104
+ if (!mimetype)
105
+ mimetype = res.mime;
106
+
107
+ return new MessageMedia(mimetype, res.data, filename, res.size || null);
108
+ }
109
+ }
110
+
111
+ module.exports = MessageMedia;
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ const Base = require('./Base');
4
+ const Product = require('./Product');
5
+
6
+ /**
7
+ * Represents a Order on WhatsApp
8
+ * @extends {Base}
9
+ */
10
+ class Order extends Base {
11
+ constructor(client, data) {
12
+ super(client);
13
+
14
+ if (data) this._patch(data);
15
+ }
16
+
17
+ _patch(data) {
18
+ /**
19
+ * List of products
20
+ * @type {Array<Product>}
21
+ */
22
+ if (data.products) {
23
+ this.products = data.products.map(product => new Product(this.client, product));
24
+ }
25
+ /**
26
+ * Order Subtotal
27
+ * @type {string}
28
+ */
29
+ this.subtotal = data.subtotal;
30
+ /**
31
+ * Order Total
32
+ * @type {string}
33
+ */
34
+ this.total = data.total;
35
+ /**
36
+ * Order Currency
37
+ * @type {string}
38
+ */
39
+ this.currency = data.currency;
40
+ /**
41
+ * Order Created At
42
+ * @type {number}
43
+ */
44
+ this.createdAt = data.createdAt;
45
+
46
+ return super._patch(data);
47
+ }
48
+
49
+
50
+ }
51
+
52
+ module.exports = Order;
@@ -0,0 +1,79 @@
1
+ const Base = require('./Base');
2
+
3
+ class Payment extends Base {
4
+ constructor(client, data) {
5
+ super(client);
6
+
7
+ if (data) this._patch(data);
8
+ }
9
+
10
+ _patch(data) {
11
+ /**
12
+ * The payment Id
13
+ * @type {object}
14
+ */
15
+ this.id = data.id;
16
+
17
+ /**
18
+ * The payment currency
19
+ * @type {string}
20
+ */
21
+ this.paymentCurrency = data.paymentCurrency;
22
+
23
+ /**
24
+ * The payment ammount ( R$ 1.00 = 1000 )
25
+ * @type {number}
26
+ */
27
+ this.paymentAmount1000 = data.paymentAmount1000;
28
+
29
+ /**
30
+ * The payment receiver
31
+ * @type {object}
32
+ */
33
+ this.paymentMessageReceiverJid = data.paymentMessageReceiverJid;
34
+
35
+ /**
36
+ * The payment transaction timestamp
37
+ * @type {number}
38
+ */
39
+ this.paymentTransactionTimestamp = data.paymentTransactionTimestamp;
40
+
41
+ /**
42
+ * The paymentStatus
43
+ *
44
+ * Possible Status
45
+ * 0:UNKNOWN_STATUS
46
+ * 1:PROCESSING
47
+ * 2:SENT
48
+ * 3:NEED_TO_ACCEPT
49
+ * 4:COMPLETE
50
+ * 5:COULD_NOT_COMPLETE
51
+ * 6:REFUNDED
52
+ * 7:EXPIRED
53
+ * 8:REJECTED
54
+ * 9:CANCELLED
55
+ * 10:WAITING_FOR_PAYER
56
+ * 11:WAITING
57
+ *
58
+ * @type {number}
59
+ */
60
+ this.paymentStatus = data.paymentStatus;
61
+
62
+ /**
63
+ * Integer that represents the payment Text
64
+ * @type {number}
65
+ */
66
+ this.paymentTxnStatus = data.paymentTxnStatus;
67
+
68
+ /**
69
+ * The note sent with the payment
70
+ * @type {string}
71
+ */
72
+ this.paymentNote = !data.paymentNoteMsg ? undefined : data.paymentNoteMsg.body ? data.paymentNoteMsg.body : undefined ;
73
+
74
+ return super._patch(data);
75
+ }
76
+
77
+ }
78
+
79
+ module.exports = Payment;
@@ -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;
@@ -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;
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const Chat = require('./Chat');
4
+
5
+ /**
6
+ * Represents a Private Chat on WhatsApp
7
+ * @extends {Chat}
8
+ */
9
+ class PrivateChat extends Chat {
10
+
11
+ }
12
+
13
+ module.exports = PrivateChat;
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const Contact = require('./Contact');
4
+
5
+ /**
6
+ * Represents a Private Contact on WhatsApp
7
+ * @extends {Contact}
8
+ */
9
+ class PrivateContact extends Contact {
10
+
11
+ }
12
+
13
+ module.exports = PrivateContact;
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ const Base = require('./Base');
4
+ const ProductMetadata = require('./ProductMetadata');
5
+
6
+ /**
7
+ * Represents a Product on WhatsAppBusiness
8
+ * @extends {Base}
9
+ */
10
+ class Product extends Base {
11
+ constructor(client, data) {
12
+ super(client);
13
+
14
+ if (data) this._patch(data);
15
+ }
16
+
17
+ _patch(data) {
18
+ /**
19
+ * Product ID
20
+ * @type {string}
21
+ */
22
+ this.id = data.id;
23
+ /**
24
+ * Price
25
+ * @type {string}
26
+ */
27
+ this.price = data.price ? data.price : '';
28
+ /**
29
+ * Product Thumbnail
30
+ * @type {string}
31
+ */
32
+ this.thumbnailUrl = data.thumbnailUrl;
33
+ /**
34
+ * Currency
35
+ * @type {string}
36
+ */
37
+ this.currency = data.currency;
38
+ /**
39
+ * Product Name
40
+ * @type {string}
41
+ */
42
+ this.name = data.name;
43
+ /**
44
+ * Product Quantity
45
+ * @type {number}
46
+ */
47
+ this.quantity = data.quantity;
48
+ /** Product metadata */
49
+ this.data = null;
50
+ return super._patch(data);
51
+ }
52
+
53
+ async getData() {
54
+ if (this.data === null) {
55
+ let result = await this.client.pupPage.evaluate((productId) => {
56
+ return window.WWebJS.getProductMetadata(productId);
57
+ }, this.id);
58
+ if (!result) {
59
+ this.data = undefined;
60
+ } else {
61
+ this.data = new ProductMetadata(this.client, result);
62
+ }
63
+ }
64
+ return this.data;
65
+ }
66
+ }
67
+
68
+ module.exports = Product;
@@ -0,0 +1,25 @@
1
+ const Base = require('./Base');
2
+
3
+ class ProductMetadata extends Base {
4
+ constructor(client, data) {
5
+ super(client);
6
+
7
+ if (data) this._patch(data);
8
+ }
9
+
10
+ _patch(data) {
11
+ /** Product ID */
12
+ this.id = data.id;
13
+ /** Retailer ID */
14
+ this.retailer_id = data.retailer_id;
15
+ /** Product Name */
16
+ this.name = data.name;
17
+ /** Product Description */
18
+ this.description = data.description;
19
+
20
+ return super._patch(data);
21
+ }
22
+
23
+ }
24
+
25
+ module.exports = ProductMetadata;
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ const Base = require('./Base');
4
+
5
+ /**
6
+ * Represents a Reaction on WhatsApp
7
+ * @extends {Base}
8
+ */
9
+ class Reaction extends Base {
10
+ constructor(client, data) {
11
+ super(client);
12
+
13
+ if (data) this._patch(data);
14
+ }
15
+
16
+ _patch(data) {
17
+ /**
18
+ * Reaction ID
19
+ * @type {object}
20
+ */
21
+ this.id = data.msgKey;
22
+ /**
23
+ * Orphan
24
+ * @type {number}
25
+ */
26
+ this.orphan = data.orphan;
27
+ /**
28
+ * Orphan reason
29
+ * @type {?string}
30
+ */
31
+ this.orphanReason = data.orphanReason;
32
+ /**
33
+ * Unix timestamp for when the reaction was created
34
+ * @type {number}
35
+ */
36
+ this.timestamp = data.timestamp;
37
+ /**
38
+ * Reaction
39
+ * @type {string}
40
+ */
41
+ this.reaction = data.reactionText;
42
+ /**
43
+ * Read
44
+ * @type {boolean}
45
+ */
46
+ this.read = data.read;
47
+ /**
48
+ * Message ID
49
+ * @type {object}
50
+ */
51
+ this.msgId = data.parentMsgKey;
52
+ /**
53
+ * Sender ID
54
+ * @type {string}
55
+ */
56
+ this.senderId = data.senderUserJid;
57
+ /**
58
+ * ACK
59
+ * @type {?number}
60
+ */
61
+ this.ack = data.ack;
62
+
63
+
64
+ return super._patch(data);
65
+ }
66
+
67
+ }
68
+
69
+ module.exports = Reaction;
@@ -0,0 +1,24 @@
1
+ module.exports = {
2
+ Base: require('./Base'),
3
+ BusinessContact: require('./BusinessContact'),
4
+ Chat: require('./Chat'),
5
+ ClientInfo: require('./ClientInfo'),
6
+ Contact: require('./Contact'),
7
+ GroupChat: require('./GroupChat'),
8
+ Location: require('./Location'),
9
+ Message: require('./Message'),
10
+ MessageMedia: require('./MessageMedia'),
11
+ PrivateChat: require('./PrivateChat'),
12
+ PrivateContact: require('./PrivateContact'),
13
+ GroupNotification: require('./GroupNotification'),
14
+ Label: require('./Label.js'),
15
+ Order: require('./Order'),
16
+ Product: require('./Product'),
17
+ Call: require('./Call'),
18
+ Buttons: require('./Buttons'),
19
+ List: require('./List'),
20
+ Payment: require('./Payment'),
21
+ Reaction: require('./Reaction'),
22
+ Poll: require('./Poll'),
23
+ PollVote: require('./PollVote')
24
+ };