@open-wa/wa-automate 4.76.0 → 5.0.0-alpha.2

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 (125) hide show
  1. package/README.md +14 -165
  2. package/dist/cli-runtime-B7_3MM0c.cjs +798 -0
  3. package/dist/cli-runtime-B7_3MM0c.cjs.map +1 -0
  4. package/dist/cli-runtime-CmpYxFCk.d.cts +31 -0
  5. package/dist/cli-runtime-CmpYxFCk.d.cts.map +1 -0
  6. package/dist/cli.cjs +17 -0
  7. package/dist/cli.cjs.map +1 -0
  8. package/dist/cli.d.cts +2 -0
  9. package/dist/index.cjs +224 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.cts +81 -0
  12. package/dist/index.d.cts.map +1 -0
  13. package/package.json +34 -177
  14. package/CNAME +0 -1
  15. package/_tsconfig.docs.json +0 -140
  16. package/bin/config-schema.json +0 -1
  17. package/bin/oas-type-schemas.json +0 -1
  18. package/bin/server.js +0 -45
  19. package/build/build-config-json-for-bin.ts +0 -56
  20. package/build/generate-oas-types.ts +0 -31
  21. package/dist/api/Client.d.ts +0 -2255
  22. package/dist/api/Client.js +0 -4358
  23. package/dist/api/functions/exposed.enum.d.ts +0 -7
  24. package/dist/api/functions/exposed.enum.js +0 -11
  25. package/dist/api/model/aliases.d.ts +0 -110
  26. package/dist/api/model/aliases.js +0 -3
  27. package/dist/api/model/button.d.ts +0 -24
  28. package/dist/api/model/button.js +0 -2
  29. package/dist/api/model/call.d.ts +0 -51
  30. package/dist/api/model/call.js +0 -18
  31. package/dist/api/model/chat.d.ts +0 -221
  32. package/dist/api/model/chat.js +0 -52
  33. package/dist/api/model/config.d.ts +0 -836
  34. package/dist/api/model/config.js +0 -111
  35. package/dist/api/model/contact.d.ts +0 -143
  36. package/dist/api/model/contact.js +0 -2
  37. package/dist/api/model/errors.d.ts +0 -90
  38. package/dist/api/model/errors.js +0 -117
  39. package/dist/api/model/events.d.ts +0 -120
  40. package/dist/api/model/events.js +0 -127
  41. package/dist/api/model/group-metadata.d.ts +0 -124
  42. package/dist/api/model/group-metadata.js +0 -25
  43. package/dist/api/model/id.d.ts +0 -5
  44. package/dist/api/model/id.js +0 -2
  45. package/dist/api/model/index.d.ts +0 -110
  46. package/dist/api/model/index.js +0 -128
  47. package/dist/api/model/label.d.ts +0 -24
  48. package/dist/api/model/label.js +0 -2
  49. package/dist/api/model/media.d.ts +0 -93
  50. package/dist/api/model/media.js +0 -12
  51. package/dist/api/model/message.d.ts +0 -422
  52. package/dist/api/model/message.js +0 -40
  53. package/dist/api/model/product.d.ts +0 -141
  54. package/dist/api/model/product.js +0 -2
  55. package/dist/api/model/reactions.d.ts +0 -76
  56. package/dist/api/model/reactions.js +0 -2
  57. package/dist/api/model/sessionInfo.d.ts +0 -77
  58. package/dist/api/model/sessionInfo.js +0 -2
  59. package/dist/build/build-postman.d.ts +0 -1
  60. package/dist/build/build-postman.js +0 -262
  61. package/dist/cli/cli-options.d.ts +0 -9
  62. package/dist/cli/cli-options.js +0 -289
  63. package/dist/cli/collections.d.ts +0 -2
  64. package/dist/cli/collections.js +0 -251
  65. package/dist/cli/file-utils.d.ts +0 -1
  66. package/dist/cli/file-utils.js +0 -71
  67. package/dist/cli/index.d.ts +0 -1
  68. package/dist/cli/index.js +0 -231
  69. package/dist/cli/integrations/chatwoot.d.ts +0 -49
  70. package/dist/cli/integrations/chatwoot.js +0 -672
  71. package/dist/cli/integrations/cloudflare.d.ts +0 -6
  72. package/dist/cli/integrations/cloudflare.js +0 -76
  73. package/dist/cli/logo.d.ts +0 -1
  74. package/dist/cli/logo.js +0 -49
  75. package/dist/cli/server.d.ts +0 -24
  76. package/dist/cli/server.js +0 -540
  77. package/dist/cli/setup.d.ts +0 -30
  78. package/dist/cli/setup.js +0 -308
  79. package/dist/config/puppeteer.config.d.ts +0 -11
  80. package/dist/config/puppeteer.config.js +0 -65
  81. package/dist/controllers/auth.d.ts +0 -36
  82. package/dist/controllers/auth.js +0 -322
  83. package/dist/controllers/browser.d.ts +0 -17
  84. package/dist/controllers/browser.js +0 -603
  85. package/dist/controllers/events.d.ts +0 -82
  86. package/dist/controllers/events.js +0 -173
  87. package/dist/controllers/init_patch.d.ts +0 -13
  88. package/dist/controllers/init_patch.js +0 -42
  89. package/dist/controllers/initializer.d.ts +0 -22
  90. package/dist/controllers/initializer.js +0 -511
  91. package/dist/controllers/launch_checks.d.ts +0 -8
  92. package/dist/controllers/launch_checks.js +0 -130
  93. package/dist/controllers/patch_manager.d.ts +0 -37
  94. package/dist/controllers/patch_manager.js +0 -231
  95. package/dist/controllers/popup/index.d.ts +0 -3
  96. package/dist/controllers/popup/index.html +0 -168
  97. package/dist/controllers/popup/index.js +0 -148
  98. package/dist/controllers/script_preloader.d.ts +0 -17
  99. package/dist/controllers/script_preloader.js +0 -88
  100. package/dist/index.d.ts +0 -13
  101. package/dist/index.js +0 -36
  102. package/dist/lib/README.md +0 -5
  103. package/dist/lib/base64.js +0 -1
  104. package/dist/lib/hash.js +0 -1
  105. package/dist/lib/jsSha.min.js +0 -1
  106. package/dist/lib/launch.js +0 -1
  107. package/dist/lib/qr.min.js +0 -1
  108. package/dist/lib/wapi.js +0 -2163
  109. package/dist/logging/custom_transport.d.ts +0 -9
  110. package/dist/logging/custom_transport.js +0 -35
  111. package/dist/logging/logging.d.ts +0 -50
  112. package/dist/logging/logging.js +0 -196
  113. package/dist/structures/Collector.d.ts +0 -202
  114. package/dist/structures/Collector.js +0 -391
  115. package/dist/structures/Dialog.d.ts +0 -55
  116. package/dist/structures/Dialog.js +0 -21
  117. package/dist/structures/MessageCollector.d.ts +0 -78
  118. package/dist/structures/MessageCollector.js +0 -145
  119. package/dist/structures/preProcessors.d.ts +0 -58
  120. package/dist/structures/preProcessors.js +0 -181
  121. package/dist/utils/pid_utils.d.ts +0 -1
  122. package/dist/utils/pid_utils.js +0 -26
  123. package/dist/utils/tools.d.ts +0 -152
  124. package/dist/utils/tools.js +0 -494
  125. package/tos.md +0 -77
package/dist/lib/wapi.js DELETED
@@ -1,2163 +0,0 @@
1
- /**
2
- * This script contains WAPI functions that need to be run in the context of the webpage
3
- */
4
-
5
- /**
6
- * Auto discovery the webpack object references of instances that contains all functions used by the WAPI
7
- * functions and creates the Store object.
8
- */
9
-
10
- if (!window.Store || !window.Store.Msg) {
11
- (function () {
12
- function getStore() {
13
- let neededObjects = [
14
- { id: "MediaCollection", module: "WAWebAttachMediaCollection", conditions: (module) => (module.default && module.default.prototype && (module.default.prototype.processFiles !== undefined || module.default.prototype.processAttachments !== undefined)) ? module.default : null },
15
- { id: "Archive", module: "WAWebSetArchiveChatAction", conditions: (module) => (module.setArchive) ? module : null },
16
- { id: "Block", module: "WAWebBlockContactUtils", conditions: (module) => (module.blockContact && module.unblockContact) ? module : null },
17
- { id: "ChatUtil", module: "WAWebSendClearChatAction", conditions: (module) => (module.sendClear) ? module : null },
18
- { id: "GroupInvite", module: "WAWebGroupInviteJob", conditions: (module) => (module.queryGroupInviteCode) ? module : null },
19
- { id: "Wap", module: "WAWebCreateGroupAction", conditions: (module) => (module.createGroup) ? module : null },
20
- { id: "State", module: "WAWebSocketModel", conditions: (module) => (module.STATE && module.STREAM) ? module : null },
21
- { id: "_Presence", module: "WAWebContactPresenceBridge", conditions: (module) => (module.setPresenceAvailable && module.setPresenceUnavailable) ? module : null },
22
- { id: "WapDelete", module: "WAWebChatDeleteBridge", conditions: (module) => (module.sendConversationDelete && module.sendConversationDelete.length == 2) ? module : null },
23
- { id: "WapQuery", module: "WAWebQueryExistsJob", conditions: (module) => (module.queryExist) ? module : ((module.default && module.default.queryExist) ? module.default : null) },
24
- { id: "UserConstructor", module: "WAWebWid", conditions: (module) => (module.default && module.default.prototype && module.default.prototype.isServer && module.default.prototype.isUser) ? module.default : null },
25
- { id: "SendTextMsgToChat", module: "WAWebSendTextMsgChatAction", resolver: (module) => module.sendTextMsgToChat},
26
- { id: "ReadSeen", module: "WAWebUpdateUnreadChatAction", conditions: (module) => (module.sendSeen) ? module : null },
27
- { id: "sendDelete", module: "WAWebDeleteChatAction", conditions: (module) => (module.sendDelete) ? module.sendDelete : null },
28
- { id: "addAndSendMsgToChat", module: "WAWebSendMsgChatAction", conditions: (module) => (module.addAndSendMsgToChat) ? module.addAndSendMsgToChat : null },
29
- { id: "Catalog", module: "WAWebCatalogCollection", conditions: (module) => (module.Catalog) ? module.Catalog : null },
30
- { id: "MsgKey", module: "WAWebMsgKey", conditions: (module) => (module.default && module.default.toString && module.default.toString().includes('MsgKey error: obj is null/undefined')) ? module.default : null },
31
- { id: "Parser", module: "WAWebE2EProtoUtils", conditions: (module) => (module.convertToTextWithoutSpecialEmojis) ? module.default : null },
32
- { id: "Builders", module: "WAWebProtobufsE2E.pb", conditions: (module) => (module.TemplateMessage && module.HydratedFourRowTemplate) ? module : null },
33
- { id: "Me", module: "WAWebUserPrefsMeUser", conditions: (module) => (module.PLATFORMS && module.Conn) ? module.default : null },
34
- { id: "MyStatus", module: "WAWebContactStatusBridge", conditions: (module) => (module.getStatus && module.setMyStatus) ? module : null },
35
- { id: "ChatStates", module: "WAWebChatStateBridge", conditions: (module) => (module.sendChatStatePaused && module.sendChatStateRecording && module.sendChatStateComposing) ? module : null },
36
- { id: "GroupActions", module: "WAWebExitGroupAction", conditions: (module) => (module.sendExitGroup && module.localExitGroup) ? module : null },
37
- { id: "Participants", module: "WAWebGroupsParticipantsApi", conditions: (module) => (module.addParticipants && module.removeParticipants && module.promoteParticipants && module.demoteParticipants) ? module : null },
38
- { id: "WidFactory", module: "WAWebWidFactory", conditions: (module) => (module.isWidlike && module.createWid && module.createWidFromWidLike) ? module : null },
39
- { id: "Sticker", module: "WAWebStickerPackCollection", resolver: m=> m.StickerPackCollection, conditions: (module) => (module.default && module.default.Sticker) ? module.default.Sticker : null },
40
- { id: "UploadUtils", module: "WAWebUploadManager", conditions: (module) => (module.default && module.default.encryptAndUpload) ? module.default : null }
41
- ];
42
- const e = (m) => require("__debug").modulesMap[m] || false
43
- const shouldRequire = m => {
44
- const a = e(m);
45
- if(!a) return false;
46
- return a.dependencies != null && a.depPosition >= a.dependencies.length
47
- }
48
- neededObjects.map((needObj) => {
49
- const m = needObj.module;
50
- if (!m) return;
51
- if(!e(m)) return;
52
- if(shouldRequire(m)) {
53
- let neededModule = require(m)
54
- needObj.foundedModule = neededModule;
55
- }
56
- });
57
- window.Store = {...{...require("WAWebCollections")},...(window.Store || {})}
58
- neededObjects.forEach((needObj) => {
59
- if (needObj.foundedModule) {
60
- window.Store[needObj.id] = needObj.resolver ? needObj.resolver(needObj.foundedModule) : needObj.foundedModule;
61
- }
62
- });
63
- if (window.Store.Chat) window.Store.Chat.modelClass.prototype.sendMessage = function (e) {
64
- window.Store.SendTextMsgToChat(this, ...arguments);
65
- }
66
- return window.Store;
67
- }
68
- getStore()
69
- }) ();
70
- }
71
-
72
- window.WAPI = {};
73
- window._WAPI = {};
74
-
75
- window.WAPI._serializeRawObj = (obj) => {
76
- if (obj && obj.toJSON) {
77
- return obj.toJSON();
78
- }
79
- return {}
80
- };
81
-
82
- /**
83
- * Serializes a chat object
84
- *
85
- * @param rawChat Chat object
86
- * @returns {{}}
87
- */
88
-
89
- window.WAPI._serializeChatObj = (obj) => {
90
- if (obj == undefined) {
91
- return null;
92
- }
93
- return Object.assign(window.WAPI._serializeRawObj(obj), {
94
- id: obj.id._serialized,
95
- kind: obj.kind,
96
- isGroup: obj.isGroup,
97
- formattedTitle: obj.formattedTitle,
98
- contact: obj['contact'] ? window.WAPI._serializeContactObj(obj['contact']) : null,
99
- groupMetadata: obj["groupMetadata"] ? window.WAPI._serializeRawObj(obj["groupMetadata"]) : null,
100
- presence: obj["presence"] ? window.WAPI._serializeRawObj(obj["presence"]) : null,
101
- msgs: null
102
- });
103
- };
104
-
105
- window.WAPI._serializeContactObj = (obj) => {
106
- if (obj == undefined) {
107
- return null;
108
- }
109
- return Object.assign(window.WAPI._serializeRawObj(obj), {
110
- id: obj.id._serialized,
111
- formattedName: obj.formattedName,
112
- isHighLevelVerified: obj.isHighLevelVerified,
113
- isMe: obj.isMe,
114
- isMyContact: obj.isMyContact,
115
- isPSA: obj.isPSA,
116
- isUser: obj.isUser,
117
- isVerified: obj.isVerified,
118
- isWAContact: obj.isWAContact,
119
- profilePicThumbObj: obj.profilePicThumb ? WAPI._serializeProfilePicThumb(obj.profilePicThumb) : {},
120
- statusMute: obj.statusMute,
121
- msgs: null
122
- });
123
- };
124
-
125
-
126
- window.WAPI._serializeMessageObj = (obj) => {
127
- if (obj == undefined) {
128
- return null;
129
- }
130
- const _chat = obj['chat'] ? WAPI._serializeChatObj(obj['chat']) : {};
131
- if (obj.quotedMsg) obj.quotedMsgObj();
132
- return Object.assign(window.WAPI._serializeRawObj(obj), {
133
- id: obj.id._serialized,
134
- from: obj.from._serialized,
135
- quotedParticipant: obj.quotedParticipant ? obj.quotedParticipant._serialized ? obj.quotedParticipant._serialized : undefined : undefined,
136
- author: obj.author ? obj.author._serialized ? obj.author._serialized : undefined : undefined,
137
- chatId: obj.chatId ? obj.chatId._serialized ? obj.chatId._serialized : undefined : undefined,
138
- to: obj.to ? obj.to._serialized ? obj.to._serialized : undefined : undefined,
139
- fromMe: obj.id.fromMe,
140
- sender: obj["senderObj"] ? WAPI._serializeContactObj(obj["senderObj"]) : null,
141
- timestamp: obj["t"],
142
- content: obj["body"],
143
- isGroupMsg: obj.isGroupMsg,
144
- isLink: obj.isLink,
145
- isMMS: obj.isMMS,
146
- isMedia: obj.isMedia,
147
- isNotification: obj.isNotification,
148
- isPSA: obj.isPSA,
149
- type: obj.type,
150
- chat: _chat,
151
- isOnline: _chat.isOnline,
152
- lastSeen: _chat.lastSeen,
153
- chatId: obj.id.remote,
154
- quotedMsgObj: WAPI._serializeMessageObj(obj['_quotedMsgObj']),
155
- mediaData: window.WAPI._serializeRawObj(obj['mediaData']),
156
- reply: body => window.WAPI.reply(_chat.id._serialized, body, obj)
157
- });
158
- };
159
-
160
- window.WAPI._serializeNumberStatusObj = (obj) => {
161
- if (obj == undefined) {
162
- return null;
163
- }
164
-
165
- return Object.assign({}, {
166
- id: obj.jid,
167
- status: obj.status,
168
- isBusiness: (obj.biz === true),
169
- canReceiveMessage: (obj.status === 200)
170
- });
171
- };
172
-
173
- window.WAPI._serializeProfilePicThumb = (obj) => {
174
- if (obj == undefined) {
175
- return null;
176
- }
177
-
178
- return Object.assign({}, {
179
- eurl: obj.eurl,
180
- id: obj.id,
181
- img: obj.img,
182
- imgFull: obj.imgFull,
183
- raw: obj.raw,
184
- tag: obj.tag
185
- });
186
- }
187
-
188
- window.WAPI.createGroup = async function (name, contactsId) {
189
- if (!Array.isArray(contactsId)) {
190
- contactsId = [contactsId];
191
- }
192
- return await window.Store.WapQuery.createGroup(name, contactsId);
193
- };
194
-
195
- /**
196
- * Sends the command for your device to leave a group.
197
- * @param groupId stirng, the is for the group.
198
- * returns Promise<void>
199
- */
200
- window.WAPI.leaveGroup = function (groupId) {
201
- groupId = typeof groupId == "string" ? groupId : groupId._serialized;
202
- var group = WAPI.getChat(groupId);
203
- return Store.GroupActions.sendExitGroup(group)
204
- };
205
-
206
-
207
- window.WAPI.getAllContacts = function () {
208
- return window.Store.Contact.map((contact) => WAPI._serializeContactObj(contact));
209
- };
210
-
211
- /**
212
- * Fetches all contact objects from store, filters them
213
- *
214
- * @returns {Array|*} List of contacts
215
- */
216
- window.WAPI.getMyContacts = function () {
217
- return window.Store.Contact.filter((contact) => contact.isMyContact === true).map((contact) => WAPI._serializeContactObj(contact));
218
- };
219
-
220
- /**
221
- * Fetches contact object from store by ID
222
- *
223
- * @param id ID of contact
224
- * @returns {T|*} Contact object
225
- */
226
- window.WAPI.getContact = function (id) {
227
- const found = window.Store.Contact.get(id);
228
- return window.WAPI._serializeContactObj(found);
229
- };
230
-
231
- window.WAPI.syncContacts = function () {
232
- Store.Contact.sync()
233
- return true;
234
- }
235
-
236
- /**
237
- * Fetches all chat objects from store
238
- *
239
- * @returns {Array|*} List of chats
240
- */
241
- window.WAPI.getAllChats = function () {
242
- return window.Store.Chat.map((chat) => WAPI._serializeChatObj(chat));
243
- };
244
-
245
- window.WAPI.haveNewMsg = function (chat) {
246
- return chat.unreadCount > 0;
247
- };
248
-
249
- window.WAPI.getAllChatsWithNewMsg = function () {
250
- return window.Store.Chat.filter(window.WAPI.haveNewMsg).map((chat) => WAPI._serializeChatObj(chat));
251
- };
252
-
253
- /**
254
- * Fetches all chat IDs from store
255
- *
256
- * @returns {Array|*} List of chat id's
257
- */
258
- window.WAPI.getAllChatIds = function () {
259
- return window.Store.Chat.map((chat) => chat.id._serialized || chat.id);
260
- };
261
-
262
- window.WAPI.getAllNewMessages = async function () {
263
- return WAPI.getAllChatsWithNewMsg().map(c => WAPI.getChat(c.id)).flatMap(c => c.msgs._models.filter(x => x.isNewMsg)).map(WAPI._serializeMessageObj) || [];
264
- }
265
-
266
- // nnoo longer determined by x.ack==-1
267
- window.WAPI.getAllUnreadMessages = async function () {
268
- return Store.Chat.models.filter(chat => chat.unreadCount && chat.unreadCount > 0).map(unreadChat => unreadChat.msgs.models.slice(-1 * unreadChat.unreadCount)).flat().map(WAPI._serializeMessageObj)
269
- }
270
-
271
- window.WAPI.getIndicatedNewMessages = async function () {
272
- return JSON.stringify(Store.Chat.models.filter(chat => chat.unreadCount).map(chat => { return { id: chat.id, indicatedNewMessages: chat.msgs.models.slice(Math.max(chat.msgs.length - chat.unreadCount, 0)).filter(msg => !msg.id.fromMe) } }))
273
- }
274
-
275
- window.WAPI.getSingleProperty = function (namespace, id, property) {
276
- if (Store[namespace] && Store[namespace].get(id) && Object.keys(Store[namespace].get(id)).find(x => x.includes(property))) return Store[namespace].get(id)[property];
277
- return 404
278
- }
279
-
280
- window.WAPI.getAllChatsWithMessages = async function (onlyNew) {
281
- let x = [];
282
- if (onlyNew) { x.push(WAPI.getAllChatsWithNewMsg().map(c => WAPI.getChat(c.id._serialized))); }
283
- else {
284
- x.push(WAPI.getAllChatIds().map((c) => WAPI.getChat(c)));
285
- }
286
- const result = (await Promise.all(x)).flatMap(x => x);
287
- return JSON.stringify(result);
288
- }
289
-
290
- /**
291
- * Fetches all groups objects from store
292
- *
293
- * @returns {Array|*} List of chats
294
- */
295
- window.WAPI.getAllGroups = function () {
296
- return window.WAPI.getAllChats().filter((chat) => chat.isGroup);
297
- };
298
-
299
- /**
300
- * Sets the chat state
301
- *
302
- * @param {0|1|2} chatState The state you want to set for the chat. Can be TYPING (1), RECRDING (2) or PAUSED (3);
303
- * returns {boolean}
304
- */
305
- window.WAPI.sendChatstate = async function (state, chatId) {
306
- switch (state) {
307
- case 0:
308
- await window.Store.ChatStates.sendChatStateComposing(chatId);
309
- break;
310
- case 1:
311
- await window.Store.ChatStates.sendChatStateRecording(chatId);
312
- break;
313
- case 2:
314
- await window.Store.ChatStates.sendChatStatePaused(chatId);
315
- break;
316
- default:
317
- return false
318
- }
319
- return true;
320
- };
321
-
322
- /**
323
- * Fetches chat object from store by ID
324
- *
325
- * @param id ID of chat
326
- * @returns {T|*} Chat object
327
- */
328
- window.WAPI.getChat = function (id) {
329
- if (!id) return false;
330
- id = typeof id == "string" ? id : id._serialized;
331
- const found = window.Store.Chat.get(id);
332
- if (found) found.sendMessage = (found.sendMessage) ? found.sendMessage : function () { return window.Store.sendMessage.apply(this, arguments); };
333
- return found;
334
- }
335
-
336
- /**
337
- * Get your status
338
- * @param {string} to '000000000000@c.us'
339
- * returns: {string,string} and string -"Hi, I am using WA"
340
- */
341
- window.WAPI.getStatus = async (id) => {
342
- return await Store.MyStatus.getStatus(id)
343
- }
344
-
345
- window.WAPI.getChatByName = function (name) {
346
- return window.WAPI.getAllChats().find((chat) => chat.name === name);
347
- };
348
-
349
- window.WAPI.sendImageFromDatabasePicBot = function (picId, chatId, caption) {
350
- var chatDatabase = window.WAPI.getChatByName('DATABASEPICBOT');
351
- var msgWithImg = chatDatabase.msgs.find((msg) => msg.caption == picId);
352
-
353
- if (msgWithImg === undefined) {
354
- return false;
355
- }
356
- var chatSend = WAPI.getChat(chatId);
357
- if (chatSend === undefined) {
358
- return false;
359
- }
360
- const oldCaption = msgWithImg.caption;
361
-
362
- msgWithImg.id.id = window.WAPI.getNewId();
363
- msgWithImg.id.remote = chatId;
364
- msgWithImg.t = Math.ceil(new Date().getTime() / 1000);
365
- msgWithImg.to = chatId;
366
-
367
- if (caption !== undefined && caption !== '') {
368
- msgWithImg.caption = caption;
369
- } else {
370
- msgWithImg.caption = '';
371
- }
372
-
373
- msgWithImg.collection.send(msgWithImg).then(function (e) {
374
- msgWithImg.caption = oldCaption;
375
- });
376
-
377
- return true;
378
- };
379
-
380
- window.WAPI.getGeneratedUserAgent = function (useragent) {
381
- if (!useragent.includes('WhatsApp')) return 'WhatsApp/0.4.315 ' + useragent;
382
- return useragent.replace(useragent.match(/WhatsApp\/([.\d])*/g)[0].match(/[.\d]*/g).find(x => x), window.Debug.VERSION)
383
- }
384
-
385
- window.WAPI.getWAVersion = function () {
386
- return window.Debug.VERSION;
387
- }
388
-
389
- /**
390
- * Automatically sends a link with the auto generated link preview. You can also add a custom message to be added.
391
- * @param chatId
392
- * @param url string A link, for example for youtube. e.g https://www.youtube.com/watch?v=61O-Galzc5M
393
- * @param text string Custom text as body of the message, this needs to include the link or it will be appended after the link.
394
- */
395
- window.WAPI.sendLinkWithAutoPreview = async function (chatId, url, text) {
396
- text = text || '';
397
- var chatSend = WAPI.getChat(chatId);
398
- if (chatSend === undefined) {
399
- return false;
400
- }
401
- const linkPreview = await Store.WapQuery.queryLinkPreview(url);
402
- return (await chatSend.sendMessage(text.includes(url) ? text : `${url}\n${text}`, { linkPreview })) == 'OK'
403
- }
404
-
405
- window.WAPI.sendMessageWithThumb = function (thumb, url, title, description, text, chatId) {
406
- var chatSend = WAPI.getChat(chatId);
407
- if (chatSend === undefined) {
408
- return false;
409
- }
410
- var linkPreview = {
411
- canonicalUrl: url,
412
- description: description,
413
- matchedText: url,
414
- title: title,
415
- thumbnail: thumb // Thumbnail max size allowed: 200x200
416
- };
417
- chatSend.sendMessage(text.includes(url) ? text : `${url}\n${text}`, { linkPreview: linkPreview, mentionedJidList: [], quotedMsg: null, quotedMsgAdminGroupJid: null });
418
- return true;
419
- };
420
-
421
- window.WAPI.revokeGroupInviteLink = async function (chatId) {
422
- var chat = Store.Chat.get(chatId);
423
- if (!chat.isGroup) return false;
424
- await Store.GroupInvite.revokeGroupInvite(chat);
425
- return true;
426
- }
427
-
428
- window.WAPI.getGroupInviteLink = async function (chatId) {
429
- var chat = Store.Chat.get(chatId);
430
- if (!chat.isGroup) return false;
431
- await Store.GroupInvite.queryGroupInviteCode(chat);
432
- return `https://chat.whatsapp.com/${chat.inviteCode}`
433
- }
434
-
435
- window.WAPI.inviteInfo = async function (link) {
436
- return await Store.WapQuery.groupInviteInfo(link.split('\/').pop()).then(r => r.status === 200 ? WAPI.quickClean(r) : r.status);
437
- }
438
-
439
- window.WAPI.getNewId = function () {
440
- var text = "";
441
- var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
442
-
443
- for (var i = 0; i < 20; i++)
444
- text += possible.charAt(Math.floor(Math.random() * possible.length));
445
- return text;
446
- };
447
-
448
- window.WAPI.getChatById = function (id) {
449
- let found = WAPI.getChat(id);
450
- if (found) {
451
- found = WAPI._serializeChatObj(found);
452
- } else {
453
- found = false;
454
- }
455
- return found;
456
- };
457
-
458
-
459
- /**
460
- * I return all unread messages from an asked chat and mark them as read.
461
- *
462
- * :param id: chat id
463
- * :type id: string
464
- *
465
- * :param includeMe: indicates if user messages have to be included
466
- * :type includeMe: boolean
467
- *
468
- * :param includeNotifications: indicates if notifications have to be included
469
- * :type includeNotifications: boolean
470
- *
471
- * :returns: list of unread messages from asked chat
472
- * :rtype: object
473
- */
474
- window.WAPI.getUnreadMessagesInChat = function (id, includeMe, includeNotifications) {
475
- // get chat and its messages
476
- let chat = WAPI.getChat(id);
477
- let messages = chat.msgs._models;
478
-
479
- // initialize result list
480
- let output = [];
481
-
482
- // look for unread messages, newest is at the end of array
483
- for (let i = messages.length - 1; i >= 0; i--) {
484
- // system message: skip it
485
- if (i === "remove") {
486
- continue;
487
- }
488
-
489
- // get message
490
- let messageObj = messages[i];
491
-
492
- // found a read message: stop looking for others
493
- if (typeof (messageObj.isNewMsg) !== "boolean" || messageObj.isNewMsg === false) {
494
- continue;
495
- } else {
496
- messageObj.isNewMsg = false;
497
- // process it
498
- let message = WAPI.processMessageObj(messageObj,
499
- includeMe,
500
- includeNotifications);
501
-
502
- // save processed message on result list
503
- if (message)
504
- output.push(message);
505
- }
506
- }
507
- // return result list
508
- return output;
509
- };
510
-
511
-
512
- /**
513
- * Load more messages in chat object from server. Use this in a while loop
514
- *
515
- * @param id ID of chat
516
- * @returns None
517
- */
518
- window.WAPI.loadEarlierMessages = async function (id) {
519
- const chat = WAPI.getChat(id);
520
- if (chat) {
521
- const someEarlierMessages = await chat.loadEarlierMsgs();
522
- if (someEarlierMessages) return someEarlierMessages.map(WAPI._serializeMessageObj);
523
- }
524
- return false;
525
- };
526
-
527
- /**
528
- * Load more messages in chat object from store by ID
529
- *
530
- * @param id ID of chat
531
- * @returns None
532
- */
533
- window.WAPI.loadAllEarlierMessages = async function (id) {
534
- const found = WAPI.getChat(id);
535
- while (!found.msgs.msgLoadState.noEarlierMsgs) {
536
- console.log('loading more messages')
537
- await found.loadEarlierMsgs();
538
- }
539
- return true
540
- };
541
-
542
- window.WAPI.asyncLoadAllEarlierMessages = async function (id) {
543
- return await window.WAPI.loadAllEarlierMessages(id);
544
- };
545
-
546
- window.WAPI.areAllMessagesLoaded = function (id) {
547
- const found = WAPI.getChat(id);
548
- if (!found.msgs.msgLoadState.noEarlierMsgs) {
549
- return false
550
- }
551
- return true
552
- };
553
-
554
- /**
555
- * Load more messages in chat object from store by ID till a particular date
556
- *
557
- * @param id ID of chat
558
- * @param lastMessage UTC timestamp of last message to be loaded
559
- * @returns None
560
- */
561
-
562
- window.WAPI.loadEarlierMessagesTillDate = async function (id, lastMessage) {
563
- const found = WAPI.getChat(id);
564
- x = async function () {
565
- if (found.msgs.models[0].t > lastMessage && !found.msgs.msgLoadState.noEarlierMsgs) {
566
- return await found.loadEarlierMsgs().then(x);
567
- } else {
568
- return true
569
- }
570
- };
571
- return await x();
572
- };
573
-
574
-
575
- /**
576
- * Fetches all group metadata objects from store
577
- *
578
- * @returns {Array|*} List of group metadata
579
- */
580
- window.WAPI.getAllGroupMetadata = function () {
581
- return window.Store.GroupMetadata.map((groupData) => groupData.all);
582
- };
583
-
584
- /**
585
- * Fetches group metadata object from store by ID
586
- *
587
- * @param id ID of group
588
- * @returns {T|*} Group metadata object
589
- */
590
- window.WAPI.getGroupMetadata = async function (id) {
591
- return window.Store.GroupMetadata.find(id);
592
- };
593
-
594
-
595
- /**
596
- * Fetches group participants
597
- *
598
- * @param id ID of group
599
- * @returns {Promise.<*>} Yields group metadata
600
- * @private
601
- */
602
- window.WAPI._getGroupParticipants = async function (id) {
603
- return (await WAPI.getGroupMetadata(id)).participants;
604
- };
605
-
606
- /**
607
- * Fetches IDs of group participants
608
- *
609
- * @param id ID of group
610
- * @returns {Promise.<Array|*>} Yields list of IDs
611
- */
612
- window.WAPI.getGroupParticipantIDs = async function (id) {
613
- return (await WAPI._getGroupParticipants(id))
614
- .map((participant) => participant.id._serialized);
615
- };
616
-
617
- window.WAPI.getGroupAdmins = async function (id) {
618
- return (await WAPI._getGroupParticipants(id))
619
- .filter((participant) => participant.isAdmin)
620
- .map((admin) => admin.id._serialized);
621
- };
622
-
623
- WAPI.iAmAdmin = async function () {
624
- return (await Promise.all(Store.GroupMetadata.models.map(({ id }) => Store.GroupMetadata.find(id)))).filter(({ participants }) => participants.iAmAdmin() || participants.iAmSuperAdmin()).map(({ id }) => id._serialized);
625
- }
626
-
627
- /**
628
- * Returns an object with all of your host device details
629
- */
630
- window.WAPI.getMe = function () {
631
- return {
632
- ...WAPI.quickClean({
633
- ...Store.Contact.get(Store.Me.wid).attributes,
634
- ...Store.Me.attributes
635
- }),
636
- me: Store.Me.me
637
- };
638
- }
639
-
640
- window.WAPI.isLoggedIn = function () {
641
- // Contact always exists when logged in
642
- const isLogged = window.Store.Contact && window.Store.Contact.checksum !== undefined;
643
- return isLogged;
644
- };
645
-
646
- window.WAPI.isConnected = function () {
647
- // Phone or connection Disconnected icon appears when phone or connection is disconnected
648
- const isConnected = (document.querySelector('[data-testid="alert-phone"]') == null && document.querySelector('[data-testid="alert-computer"]') == null) ? true : false;
649
- return isConnected;
650
- };
651
-
652
- //I dont think this will work for group chats.
653
- window.WAPI.isChatOnline = async function (id) {
654
- return Store.Chat.get(id) ? await Store.Chat.get(id).presence.subscribe().then(_ => Store.Chat.get(id).presence.attributes.isOnline) : false;
655
- }
656
-
657
- window.WAPI.processMessageObj = function (messageObj, includeMe, includeNotifications) {
658
- if (messageObj.isNotification) {
659
- if (includeNotifications)
660
- return WAPI._serializeMessageObj(messageObj);
661
- else
662
- return;
663
- // System message
664
- // (i.e. "Messages you send to this chat and calls are now secured with end-to-end encryption...")
665
- } else if (messageObj.id.fromMe === false || includeMe) {
666
- return WAPI._serializeMessageObj(messageObj);
667
- }
668
- return;
669
- };
670
-
671
- window.WAPI.getAllMessagesInChat = function (id, includeMe = false, includeNotifications = false, clean = false) {
672
- const chat = WAPI.getChat(id);
673
- let output = chat.msgs._models || [];
674
- if (!includeMe) output = output.filter(m => !m.id.fromMe)
675
- if (!includeNotifications) output = output.filter(m => !m.isNotification)
676
- return (clean ? output.map(WAPI.quickClean) : output.map(WAPI._serializeMessageObj)) || [];
677
- };
678
-
679
- window.WAPI.loadAndGetAllMessagesInChat = function (id, includeMe, includeNotifications) {
680
- return WAPI.loadAllEarlierMessages(id).then(_ => {
681
- const chat = WAPI.getChat(id);
682
- let output = [];
683
- const messages = chat.msgs._models;
684
-
685
- for (const i in messages) {
686
- if (i === "remove") {
687
- continue;
688
- }
689
- const messageObj = messages[i];
690
-
691
- let message = WAPI.processMessageObj(messageObj, includeMe, includeNotifications)
692
- if (message)
693
- output.push(message);
694
- }
695
- return output;
696
- })
697
- };
698
-
699
- window.WAPI.getAllMessageIdsInChat = function (id, includeMe, includeNotifications) {
700
- const chat = WAPI.getChat(id);
701
- let output = [];
702
- const messages = chat.msgs._models;
703
-
704
- for (const i in messages) {
705
- if ((i === "remove")
706
- || (!includeMe && messages[i].isMe)
707
- || (!includeNotifications && messages[i].isNotification)) {
708
- continue;
709
- }
710
- output.push(messages[i].id._serialized);
711
- }
712
- return output;
713
- };
714
-
715
- window.WAPI.getMessageById = function (id) {
716
- let result = false;
717
- try {
718
- let msg = window.Store.Msg.get(id);
719
- if (msg) {
720
- result = WAPI.processMessageObj(msg, true, true);
721
- }
722
- } catch (err) { }
723
- return result;
724
- };
725
-
726
- window.WAPI.sendMessageWithMentions = async function (ch, body) {
727
- var chat = ch.id ? ch : Store.Chat.get(ch);
728
- var chatId = chat.id._serialized;
729
- var msgIveSent = chat.msgs.filter(msg => msg.__x_isSentByMe)[0];
730
- if (!msgIveSent) return chat.sendMessage(body);
731
- var tempMsg = Object.create(msgIveSent);
732
- var newId = window.WAPI.getNewMessageId(chatId);
733
- var mentionedJidList = body.match(/@(\d*)/g).filter(x => x.length > 5).map(x => Store.Contact.get(x.replace("@", "") + "@c.us") ? new Store.WidFactory.createUserWid(x.replace("@", "")) : '') || undefined;
734
- var extend = {
735
- ack: 0,
736
- id: newId,
737
- local: !0,
738
- self: "out",
739
- t: parseInt(new Date().getTime() / 1000),
740
- to: new Store.WidFactory.createWid(chatId),
741
- isNewMsg: !0,
742
- type: "chat",
743
- body,
744
- quotedMsg: null,
745
- mentionedJidList
746
- };
747
- Object.assign(tempMsg, extend);
748
- await Store.addAndSendMsgToChat(chat, tempMsg)
749
- return newId._serialized;
750
- }
751
-
752
- window.WAPI.sendMessageReturnId = async function (ch, body) {
753
- var chat = ch.id ? ch : Store.Chat.get(ch);
754
- var chatId = chat.id._serialized;
755
- var msgIveSent = chat.msgs.filter(msg => msg.__x_isSentByMe)[0];
756
- if (!msgIveSent) return chat.sendMessage(body);
757
- var tempMsg = Object.create(msgIveSent);
758
- var newId = window.WAPI.getNewMessageId(chatId);
759
- var extend = {
760
- ack: 0,
761
- id: newId,
762
- local: !0,
763
- self: "out",
764
- t: parseInt(new Date().getTime() / 1000),
765
- to: new Store.WidFactory.createWid(chatId),
766
- isNewMsg: !0,
767
- type: "chat",
768
- body,
769
- quotedMsg: null
770
- };
771
- Object.assign(tempMsg, extend);
772
- await Store.addAndSendMsgToChat(chat, tempMsg)
773
- return newId._serialized;
774
- }
775
-
776
-
777
- window.WAPI.sendMessage = async function (id, message) {
778
- if (id === 'status@broadcast') return 'Not able to send message to broadcast';
779
- let chat = WAPI.getChat(id);
780
- if ((!chat && !id.includes('g') || chat.msgs.models.length == 0)) {
781
- var contact = WAPI.getContact(id)
782
- if (!contact || !contact.isMyContact) return 'Not a contact';
783
- await Store.Chat.find(Store.Contact.get(id).id)
784
- chat = WAPI.getChat(id);
785
- }
786
- if (chat !== undefined) {
787
- // return WAPI.sendMessageReturnId(chat,message).then(id=>{return id})
788
- return await chat.sendMessage(message).then(_ => chat.lastReceivedKey._serialized);
789
- }
790
- return false;
791
- };
792
-
793
-
794
- window.WAPI.sendSeen = async function (id) {
795
- if (!id) return false;
796
- var chat = window.WAPI.getChat(id);
797
- if (chat !== undefined) {
798
- await Store.ReadSeen.sendSeen(chat, false);
799
- return true;
800
- }
801
- return false;
802
- };
803
-
804
- window.WAPI.markAsUnread = async function (id) {
805
- var chat = window.WAPI.getChat(id);
806
- if (chat !== undefined) {
807
- await Store.ReadSeen.markUnread(chat, true);
808
- return true;
809
- }
810
- return false;
811
- };
812
-
813
- window.isChatMessage = function (message) {
814
- if (message.isSentByMe) {
815
- return false;
816
- }
817
- if (message.isNotification) {
818
- return false;
819
- }
820
- if (!message.isUserCreatedType) {
821
- return false;
822
- }
823
- return true;
824
- }
825
-
826
- window.WAPI.setPresence = function (available) {
827
- if (available) Store._Presence.setPresenceAvailable();
828
- else Store._Presence.setPresenceUnavailable();
829
- }
830
-
831
- window.WAPI.getUnreadMessages = function (includeMe, includeNotifications, use_unread_count) {
832
- const chats = window.Store.Chat.models;
833
- let output = [];
834
-
835
- for (let chat in chats) {
836
- if (isNaN(chat)) {
837
- continue;
838
- }
839
-
840
- let messageGroupObj = chats[chat];
841
- let messageGroup = WAPI._serializeChatObj(messageGroupObj);
842
-
843
- messageGroup.messages = [];
844
-
845
- const messages = messageGroupObj.msgs._models;
846
- for (let i = messages.length - 1; i >= 0; i--) {
847
- let messageObj = messages[i];
848
- if (typeof (messageObj.isNewMsg) != "boolean" || messageObj.isNewMsg === false) {
849
- continue;
850
- } else {
851
- messageObj.isNewMsg = false;
852
- let message = WAPI.processMessageObj(messageObj, includeMe, includeNotifications);
853
- if (message) {
854
- messageGroup.messages.push(message);
855
- }
856
- }
857
- }
858
-
859
- if (messageGroup.messages.length > 0) {
860
- output.push(messageGroup);
861
- } else { // no messages with isNewMsg true
862
- if (use_unread_count) {
863
- let n = messageGroupObj.unreadCount; // will use unreadCount attribute to fetch last n messages from sender
864
- for (let i = messages.length - 1; i >= 0; i--) {
865
- let messageObj = messages[i];
866
- if (n > 0) {
867
- if (!messageObj.isSentByMe) {
868
- let message = WAPI.processMessageObj(messageObj, includeMe, includeNotifications);
869
- messageGroup.messages.unshift(message);
870
- n -= 1;
871
- }
872
- } else if (n === -1) { // chat was marked as unread so will fetch last message as unread
873
- if (!messageObj.isSentByMe) {
874
- let message = WAPI.processMessageObj(messageObj, includeMe, includeNotifications);
875
- messageGroup.messages.unshift(message);
876
- break;
877
- }
878
- } else { // unreadCount = 0
879
- break;
880
- }
881
- }
882
- if (messageGroup.messages.length > 0) {
883
- messageGroupObj.unreadCount = 0; // reset unread counter
884
- output.push(messageGroup);
885
- }
886
- }
887
- }
888
- }
889
- return output;
890
- };
891
-
892
- window.WAPI.getGroupOwnerID = async function (id) {
893
- const output = (await WAPI.getGroupMetadata(id)).owner.id;
894
- return output;
895
-
896
- };
897
-
898
- window.WAPI.getCommonGroups = async function (id) {
899
- let output = [];
900
-
901
- groups = window.WAPI.getAllGroups();
902
-
903
- for (let idx in groups) {
904
- try {
905
- participants = await window.WAPI.getGroupParticipantIDs(groups[idx].id);
906
- if (participants.filter((participant) => participant == id).length) {
907
- output.push(groups[idx]);
908
- }
909
- } catch (err) {
910
- console.log("Error in group:");
911
- console.log(groups[idx]);
912
- console.log(err);
913
- }
914
- }
915
- return output;
916
- };
917
-
918
- window.WAPI.getProfilePicFromServer = function (id) {
919
- return Store.WapQuery.profilePicFind(id).then(x => x.eurl);
920
- }
921
-
922
- window.WAPI.getProfilePicSmallFromId = async function (id) {
923
- return await window.Store.ProfilePicThumb.find(id).then(async d => {
924
- if (d.img !== undefined) {
925
- return await window.WAPI.downloadFileWithCredentials(d.img);
926
- } else {
927
- return false
928
- }
929
- }, function (e) {
930
- return false
931
- })
932
- };
933
-
934
- window.WAPI.getProfilePicFromId = async function (id) {
935
- return await window.Store.ProfilePicThumb.find(id).then(async d => {
936
- if (d.imgFull !== undefined) {
937
- return await window.WAPI.downloadFileWithCredentials(d.imgFull);
938
- } else {
939
- return false
940
- }
941
- }, function (e) {
942
- return false
943
- })
944
- };
945
-
946
- window.WAPI.downloadFileWithCredentials = async function (url) {
947
- if (!axios || !url) return false;
948
- const ab = (await axios.get(url, { responseType: 'arraybuffer' })).data
949
- return btoa(new Uint8Array(ab).reduce((data, byte) => data + String.fromCharCode(byte), ''));
950
- };
951
-
952
- window.WAPI.downloadFile = async function (url) {
953
- return await new Promise((resolve, reject) => {
954
- let xhr = new XMLHttpRequest();
955
- xhr.onload = function () {
956
- if (xhr.readyState == 4) {
957
- if (xhr.status == 200) {
958
- let reader = new FileReader();
959
- reader.readAsDataURL(xhr.response);
960
- reader.onload = function (e) {
961
- resolve(reader.result.substr(reader.result.indexOf(',') + 1))
962
- };
963
- } else {
964
- console.error(xhr.statusText);
965
- }
966
- } else {
967
- console.log(err);
968
- resolve(false);
969
- }
970
- };
971
-
972
- xhr.open("GET", url, true);
973
- xhr.responseType = 'blob';
974
- xhr.send(null);
975
- })
976
- };
977
-
978
- window.WAPI.getBatteryLevel = function () {
979
- return 'DEPRECATED'
980
- };
981
-
982
- window.WAPI.getIsPlugged = function () {
983
- return 'DEPRECATED'
984
- };
985
-
986
- window.WAPI.deleteConversation = async function (chatId) {
987
- let userId = new window.Store.UserConstructor(chatId, { intentionallyUsePrivateConstructor: true });
988
- let conversation = WAPI.getChat(userId);
989
- if (!conversation) {
990
- return false;
991
- }
992
- return await window.Store.sendDelete(conversation, false).then(() => {
993
- return true;
994
- }).catch(() => {
995
- return false;
996
- });
997
- };
998
-
999
- window.WAPI.smartDeleteMessages = async function (chatId, messageArray, onlyLocal) {
1000
- var userId = new Store.WidFactory.createWid(chatId);
1001
- let conversation = WAPI.getChat(userId);
1002
- if (!conversation) return false;
1003
-
1004
- if (!Array.isArray(messageArray)) {
1005
- messageArray = [messageArray];
1006
- }
1007
-
1008
- let messagesToDelete = messageArray.map(msgId => (typeof msgId == 'string') ? window.Store.Msg.get(msgId) : msgId).filter(x => x);
1009
- if (messagesToDelete.length == 0) return true;
1010
- let jobs = onlyLocal ? [conversation.sendDeleteMsgs(messagesToDelete, conversation)] : [
1011
- conversation.sendRevokeMsgs(messagesToDelete.filter(msg => msg.isSentByMe), conversation),
1012
- conversation.sendDeleteMsgs(messagesToDelete.filter(msg => !msg.isSentByMe), conversation)
1013
- ]
1014
- return Promise.all(jobs).then(_ => true)
1015
- };
1016
-
1017
- window.WAPI.deleteMessage = async function (chatId, messageArray, revoke = false) {
1018
- let userId = new window.Store.UserConstructor(chatId, { intentionallyUsePrivateConstructor: true });
1019
- let conversation = WAPI.getChat(userId);
1020
-
1021
- if (!conversation) return false;
1022
-
1023
- if (!Array.isArray(messageArray)) {
1024
- messageArray = [messageArray];
1025
- }
1026
-
1027
- let messagesToDelete = messageArray.map(msgId => window.Store.Msg.get(msgId));
1028
-
1029
- if (revoke) {
1030
- conversation.sendRevokeMsgs(messagesToDelete, conversation);
1031
- } else {
1032
- conversation.sendDeleteMsgs(messagesToDelete, conversation);
1033
- }
1034
-
1035
- return true;
1036
- };
1037
-
1038
- window.WAPI.clearChat = async function (id) {
1039
- return await Store.ChatUtil.sendClear(Store.Chat.get(id), true);
1040
- }
1041
-
1042
- /**
1043
- * @param id The id of the conversation
1044
- * @param archive boolean true => archive, false => unarchive
1045
- * @return boolean true: worked, false: didnt work (probably already in desired state)
1046
- */
1047
- window.WAPI.archiveChat = async function (id, archive) {
1048
- return await Store.Archive.setArchive(Store.Chat.get(id), archive).then(_ => true).catch(_ => false)
1049
- }
1050
-
1051
- /**
1052
- * Extracts vcards from a message
1053
- * @param id string id of the message to extract the vcards from
1054
- * @returns [vcard]
1055
- * ```
1056
- * [
1057
- * {
1058
- * displayName:"Contact name",
1059
- * vcard: "loong vcard string"
1060
- * }
1061
- * ]
1062
- * ``` or false if no valid vcards found
1063
- */
1064
- window.WAPI.getVCards = function (id) {
1065
- var msg = Store.Msg.get(id);
1066
- if (msg) {
1067
- if (msg.type == 'vcard') {
1068
- return [
1069
- {
1070
- displayName: msg.subtype,
1071
- vcard: msg.body
1072
- }
1073
- ]
1074
- } else if (msg.type == 'multi_vcard') {
1075
- return msg.vcardList
1076
- } else return false;
1077
- } else {
1078
- return false
1079
- }
1080
- }
1081
-
1082
- window.WAPI.checkNumberStatus = async function (id) {
1083
- try {
1084
- const result = await window.Store.WapQuery.queryExist(id);
1085
- if (result.jid === undefined) throw 404;
1086
- const data = window.WAPI._serializeNumberStatusObj(result);
1087
- if (data.status == 200) data.numberExists = true
1088
- return data;
1089
- } catch (e) {
1090
- return window.WAPI._serializeNumberStatusObj({
1091
- status: e,
1092
- jid: id
1093
- });
1094
- }
1095
- };
1096
-
1097
- window.WAPI.onAnyMessage = callback => window.Store.Msg.on('add', (newMessage) => {
1098
- if (newMessage && newMessage.isNewMsg) {
1099
- if (!newMessage.clientUrl && (newMessage.mediaKeyTimestamp || newMessage.filehash)) {
1100
- const cb = (msg) => {
1101
- if (msg.id._serialized === newMessage.id._serialized && msg.clientUrl) {
1102
- callback(WAPI.processMessageObj(msg, true, false));
1103
- Store.Msg.off('change:isUnsentMedia', cb);
1104
- }
1105
- };
1106
- Store.Msg.on('change:isUnsentMedia', cb);
1107
- } else {
1108
- let pm = window.WAPI.processMessageObj(newMessage, true, true);
1109
- let message = pm ? JSON.parse(JSON.stringify(pm)) : WAPI.quickClean(newMessage.attributes);
1110
- if (message) {
1111
- callback(message)
1112
- }
1113
- }
1114
- }
1115
- });
1116
-
1117
- /**
1118
- * Registers a callback to be called when a the acknowledgement state of the phone connection.
1119
- * @param callback - function - Callback function to be called when the device state changes. this returns 'CONNECTED' or 'TIMEOUT'
1120
- * @returns {boolean}
1121
- */
1122
- window.WAPI.onStateChanged = function (callback) {
1123
- window.Store.State.default.on('change:state', ({ state }) => callback(state))
1124
- return true;
1125
- }
1126
-
1127
- /**
1128
- * Returns the current state of the session. Possible state values:
1129
- * "CONFLICT"
1130
- * "CONNECTED"
1131
- * "DEPRECATED_VERSION"
1132
- * "OPENING"
1133
- * "PAIRING"
1134
- * "PROXYBLOCK"
1135
- * "SMB_TOS_BLOCK"
1136
- * "TIMEOUT"
1137
- * "TOS_BLOCK"
1138
- * "UNLAUNCHED"
1139
- * "UNPAIRED"
1140
- * "UNPAIRED_IDLE"
1141
- */
1142
- window.WAPI.getState = function () {
1143
- return Store.State.default.state;
1144
- }
1145
-
1146
- /**
1147
- * Registers a callback to be called when your phone receives a new call request.
1148
- * @param callback - function - Callback function to be called upon a new call. returns a call object.
1149
- * @returns {boolean}
1150
- */
1151
- window.WAPI.onIncomingCall = function (callback) {
1152
- window.Store.Call.on('add', callback);
1153
- return true;
1154
- }
1155
-
1156
- /**
1157
- * @param label: either the id or the name of the label. id will be something simple like anhy nnumber from 1-10, name is the label of the label if that makes sense.
1158
- * @param objectId The Chat, message or contact id to which you want to add a label
1159
- * @param type The type of the action. It can be either "add" or "remove"
1160
- * @returns boolean true if it worked otherwise false
1161
- */
1162
- window.WAPI.addOrRemoveLabels = async function (label, objectId, type) {
1163
- var { id } = Store.Label.models.find(x => x.id == label || x.name == label)
1164
- var to = Store.Chat.get(objectId) || Store.Msg.get(objectId) || Store.Contact.get(objectId);
1165
- if (!id || !to) return false;
1166
- const { status } = await Store.Label.addOrRemoveLabels([{ id, type }], [to]);
1167
- return status === 200;
1168
- }
1169
-
1170
- /**
1171
- * Registers a callback to be called when a the acknowledgement state of a message changes.
1172
- * @param callback - function - Callback function to be called when a message acknowledgement changes.
1173
- * @returns {boolean}
1174
- */
1175
- window.WAPI.onAck = function (callback) {
1176
- Store.Msg.on("change:ack", m => callback(WAPI.quickClean(m)));
1177
- return true;
1178
- }
1179
-
1180
- //returns an array of liveLocationChangeObjects
1181
- window.WAPI.forceUpdateLiveLocation = async function (chatId) {
1182
- if (!Store.LiveLocation.get(chatId)) return false;
1183
- return WAPI.quickClean(await Store.LiveLocation.update(chatId)).participants.map(l => {
1184
- return {
1185
- ...l,
1186
- msgId: l.msg.id._serialized
1187
- }
1188
- });
1189
- }
1190
-
1191
- window.WAPI.onLiveLocation = function (chatId, callback) {
1192
- var lLChat = Store.LiveLocation.get(chatId);
1193
- if (lLChat) {
1194
- var validLocs = lLChat.participants.validLocations();
1195
- validLocs.map(x => x.on('change:lastUpdated', (x, y, z) => {
1196
- const { id, lat, lng, accuracy, degrees, speed, lastUpdated } = x;
1197
- const l = {
1198
- id: id.toString(), lat, lng, accuracy, degrees, speed, lastUpdated
1199
- };
1200
- callback(l);
1201
- }));
1202
- return true;
1203
- } else {
1204
- return false;
1205
- }
1206
- }
1207
-
1208
- window.WAPI.onBattery = function (callback) {
1209
- // window.Store.Conn.on('change:battery', ({battery}) => callback(battery));
1210
- return true;
1211
- }
1212
-
1213
- window.WAPI.onPlugged = function (callback) {
1214
- // window.Store.Conn.on('change:plugged', ({plugged}) => callback(plugged));
1215
- return true;
1216
- }
1217
-
1218
- /**
1219
- * A new approach to listening to add and remove events from groups. This takes only a callback and is prevents memory leaks
1220
- */
1221
- WAPI.onGlobalParicipantsChanged = function (callback) {
1222
- const events = [
1223
- 'change:isAdmin',
1224
- 'remove',
1225
- 'add'
1226
- ]
1227
- //const id = eventName.replace('group_participant_change','');
1228
- const chats = Store.GroupMetadata.models
1229
- //.filter(group=>group.participants.models.find(participant=>participant.id._serialized===id))
1230
- .filter(x => x.id.server !== 'broadcast').map(group => window.Store.Chat.get(group.id._serialized));
1231
- const cb = (eventName, eventData, extra) => {
1232
- if (events.includes(eventName)) {
1233
- let action = eventName;
1234
- if (eventName == 'change:isAdmin') {
1235
- action = extra ? 'promote' : 'demote';
1236
- }
1237
- callback({
1238
- by: undefined,
1239
- action: action,
1240
- who: eventData.id._serialized,
1241
- chat: extra.parent.id._serialized
1242
- });
1243
- chats.map(chat => {
1244
- chat.groupMetadata.participants.off('all', cb)
1245
- chat.groupMetadata.participants.off(cb)
1246
- });
1247
- }
1248
- }
1249
- chats.map(chat => chat.groupMetadata.participants.on('all', cb));
1250
- Store.GroupMetadata.on('all', (eventName, groupId) => chats.map(chat => chat.groupMetadata.participants.on('all', cb)))
1251
- return true;
1252
- }
1253
-
1254
- /**
1255
- * Registers a callback to participant changes on a certain, specific group
1256
- * @param groupId - string - The id of the group that you want to attach the callback to.
1257
- * @param callback - function - Callback function to be called when a message acknowledgement changes. The callback returns 3 variables
1258
- * @returns {boolean}
1259
- */
1260
- window.WAPI.onParticipantsChanged = function (groupId, callback) {
1261
- const subtypeEvents = [
1262
- "invite",
1263
- "add",
1264
- "remove",
1265
- "leave",
1266
- "promote",
1267
- "demote"
1268
- ];
1269
- const events = [
1270
- 'change:isAdmin',
1271
- 'remove',
1272
- 'add'
1273
- ]
1274
- const chat = window.Store.Chat.get(groupId);
1275
- chat.groupMetadata.participants.on('all', (eventName, eventData, extra) => {
1276
- if (events.includes(eventName)) {
1277
- let action = eventName;
1278
- if (eventName == 'change:isAdmin') {
1279
- action = extra ? 'promote' : 'demote';
1280
- }
1281
- callback({
1282
- by: undefined,
1283
- action: action,
1284
- who: eventData.id._serialized
1285
- });
1286
- }
1287
- })
1288
- }
1289
-
1290
- /**
1291
- * Registers a callback to participant changes on a certain, specific group
1292
- * @param groupId - string - The id of the group that you want to attach the callback to.
1293
- * @param callback - function - Callback function to be called when a message acknowledgement changes. The callback returns 3 variables
1294
- * @returns {boolean}
1295
- */
1296
- window.groupParticpiantsEvents = {};
1297
- window.WAPI._onParticipantsChanged = function (groupId, callback) {
1298
- const subtypeEvents = [
1299
- "invite",
1300
- "add",
1301
- "remove",
1302
- "leave",
1303
- "promote",
1304
- "demote"
1305
- ];
1306
- const chat = window.Store.Chat.get(groupId);
1307
- //attach all group Participants to the events object as 'add'
1308
- const metadata = window.Store.GroupMetadata.get(groupId);
1309
- if (!groupParticpiantsEvents[groupId]) {
1310
- groupParticpiantsEvents[groupId] = {};
1311
- metadata.participants.forEach(participant => {
1312
- groupParticpiantsEvents[groupId][participant.id.toString()] = {
1313
- subtype: "add",
1314
- from: metadata.owner
1315
- }
1316
- });
1317
- }
1318
- let i = 0;
1319
- chat.on("change:groupMetadata.participants",
1320
- _ => chat.on("all", (x, y) => {
1321
- const { isGroup, previewMessage } = y;
1322
- if (isGroup && x === "change" && previewMessage && previewMessage.type === "gp2" && subtypeEvents.includes(previewMessage.subtype)) {
1323
- const { subtype, author, recipients } = previewMessage;
1324
- const rec = recipients[0].toString();
1325
- if (groupParticpiantsEvents[groupId][rec] && groupParticpiantsEvents[groupId][recipients[0]].subtype == subtype) {
1326
- //ignore, this is a duplicate entry
1327
- // console.log('duplicate event')
1328
- } else {
1329
- //ignore the first message
1330
- if (i == 0) {
1331
- //ignore it, plus 1,
1332
- i++;
1333
- } else {
1334
- groupParticpiantsEvents[groupId][rec] = { subtype, author };
1335
- //fire the callback
1336
- // // previewMessage.from.toString()
1337
- // x removed y
1338
- // x added y
1339
- callback({
1340
- by: author.toString(),
1341
- action: subtype,
1342
- who: recipients
1343
- });
1344
- chat.off("all", this)
1345
- i = 0;
1346
- }
1347
- }
1348
- }
1349
- })
1350
- )
1351
- return true;
1352
- }
1353
-
1354
-
1355
- /**
1356
- * Registers a callback that fires when your host phone is added to a group.
1357
- * @param callback - function - Callback function to be called when a message acknowledgement changes. The callback returns 3 variables
1358
- * @returns {boolean}
1359
- */
1360
- window.WAPI.onAddedToGroup = function (callback) {
1361
- Store.Chat.on('change:previewMessage', async event => {
1362
- if (event.isGroup && event.previewMessage && event.previewMessage.type == 'gp2' && event.previewMessage.subtype == 'add' && event.previewMessage.recipients && event.previewMessage.recipients.map(x => x._serialized).includes(Store.Me.wid._serialized)) {
1363
- const tdiff = (Date.now() - Store.Msg.get(event.previewMessage.id._serialized).t * 1000) / 1000;
1364
- if (tdiff < 10.0) {
1365
- console.log('added', tdiff, 'seconds ago')
1366
- await WAPI.sendSeen(event.id);
1367
- callback(WAPI._serializeChatObj(Store.Chat.get(event.id)));
1368
- } else console.log('Not a new group add', event.id._serialized)
1369
- }
1370
- })
1371
- return true;
1372
- }
1373
-
1374
- /**
1375
- * Reads buffered new messages.
1376
- * @returns {Array}
1377
- */
1378
- window.WAPI.getBufferedNewMessages = function () {
1379
- let bufferedMessages = window._WAPI._newMessagesBuffer;
1380
- window._WAPI._newMessagesBuffer = [];
1381
- return bufferedMessages;
1382
- };
1383
- /** End new messages observable functions **/
1384
-
1385
- /** Joins a group via the invite link, code, or message
1386
- * @param link This param is the string which includes the invite link or code. The following work:
1387
- * - Follow this link to join my WA group: https://chat.whatsapp.com/DHTGJUfFJAV9MxOpZO1fBZ
1388
- * - https://chat.whatsapp.com/DHTGJUfFJAV9MxOpZO1fBZ
1389
- * - DHTGJUfFJAV9MxOpZO1fBZ
1390
- * @returns Promise<string | boolean> Either false if it didn't work, or the group id.
1391
- */
1392
- window.WAPI.joinGroupViaLink = async function (link) {
1393
- return await Store.WapQuery.acceptGroupInvite(link.split('\/').pop()).then(res => res.status === 200 ? res.gid._serialized : res.status);
1394
- let code = link;
1395
- //is it a link? if not, assume it's a code, otherwise, process the link to get the code.
1396
- if (link.includes('chat.whatsapp.com')) {
1397
- if (!link.match(/chat.whatsapp.com\/([\w\d]*)/g).length) return false;
1398
- code = link.match(/chat.whatsapp.com\/([\w\d]*)/g)[0].replace('chat.whatsapp.com\/', '');
1399
- }
1400
- const group = await Store.GroupInvite.joinGroupViaInvite(code);
1401
- if (!group.id) return false;
1402
- return group.id._serialized
1403
- }
1404
-
1405
- window.WAPI.sendImage = async function (imgBase64, chatid, filename, caption, quotedMsg, waitForKey, ptt) {
1406
- if (!chatid.includes('@g') && !chatid.includes('@c')) return false;
1407
- let extras = {};
1408
- if (quotedMsg) {
1409
- if (typeof quotedMsg !== "object") quotedMsg = Store.Msg.get(quotedMsg);
1410
- extras = {
1411
- quotedMsg,
1412
- quotedParticipant: quotedMsg.author || quotedMsg.from,
1413
- quotedStanzaID: quotedMsg.id.id
1414
- };
1415
- }
1416
- return await Store.Chat.find(chatid).then(async (chat) => {
1417
- var mediaBlob = window.WAPI.base64ImageToFile(imgBase64, filename);
1418
- return await window.WAPI.procFiles(chat, mediaBlob).then(async mc => {
1419
- var media = mc.models[0];
1420
- if (ptt) media.mediaPrep._mediaData.type = 'ptt';
1421
- await media.sendToChat(chat, { caption, ...extras });
1422
- return waitForKey ? await new Promise(async (resolve, reject) => {
1423
- const cb = msg => {
1424
- if (media.attributes.file.size === msg.size) resolve(msg.id._serialized);
1425
- Store.Msg.off('change:clientUrl', cb);
1426
- };
1427
- Store.Msg.on('change:clientUrl', cb);
1428
- }) : true
1429
- });
1430
- });
1431
- }
1432
-
1433
- /**
1434
- * This function sts the profile name of the number.
1435
- *
1436
- * Please note this DOES NOT WORK ON BUSINESS ACCOUNTS!
1437
- *
1438
- * @param newName - string the new name to set as profile name
1439
- */
1440
- window.WAPI.setMyName = async function (newName) {
1441
- return require("WAWebSetPushnameConnAction").setPushname(newName)
1442
- }
1443
-
1444
- /** Change the icon for the group chat
1445
- * @param groupId 123123123123_1312313123@g.us The id of the group
1446
- * @param imgData 'data:image/jpeg;base64,...` The base 64 data uri
1447
- * @returns boolean true if it was set, false if it didn't work. It usually doesn't work if the image file is too big.
1448
- */
1449
- window.WAPI.setGroupIcon = async function (groupId, imgData) {
1450
- const { status } = await Store.WapQuery.sendSetPicture(groupId, imgData, imgData);
1451
- return status == 200;
1452
- }
1453
-
1454
- /**
1455
- * Update your status
1456
- * @param newStatus string new Status
1457
- */
1458
- window.WAPI.setMyStatus = function (newStatus) {
1459
- return Store.MyStatus.setMyStatus(newStatus)
1460
- }
1461
-
1462
- window.WAPI.sendVideoAsGif = async function (imgBase64, chatid, filename, caption, quotedMsg) {
1463
- let extras = {};
1464
- if (quotedMsg) {
1465
- if (typeof quotedMsg !== "object") quotedMsg = Store.Msg.get(quotedMsg);
1466
- extras = {
1467
- quotedMsg,
1468
- quotedParticipant: quotedMsg.author || quotedMsg.from,
1469
- quotedStanzaID: quotedMsg.id.id
1470
- };
1471
- }
1472
- // create new chat
1473
- return await Store.Chat.find(chatid).then(async (chat) => {
1474
- var mediaBlob = window.WAPI.base64ImageToFile(imgBase64, filename);
1475
- var mc = new Store.MediaCollection(chat);
1476
- return await window.WAPI.procFiles(chat, mediaBlob).then(async mc => {
1477
- var media = mc.models[0];
1478
- media.mediaPrep._mediaData.isGif = true;
1479
- media.mediaPrep._mediaData.gifAttribution = 1;
1480
- await media.mediaPrep.sendToChat(chat, { caption, ...extras });
1481
- return chat.lastReceivedKey._serialized;
1482
- });
1483
- });
1484
- }
1485
-
1486
- window.WAPI.refreshBusinessProfileProducts = async function () {
1487
- await Promise.all(Store.BusinessProfile.models.map(async x => {
1488
- try {
1489
- await Store.Catalog.findCarouselCatalog(x.id._serialized)
1490
- } catch (error) { }
1491
- }));
1492
- return true;
1493
- }
1494
-
1495
- /**
1496
- * Find any product listings of the given number. Use this to query a catalog
1497
- *
1498
- * @param id id of buseinss profile (i.e the number with @c.us)
1499
- * @returns None
1500
- */
1501
- window.WAPI.getBusinessProfilesProducts = async function (id) {
1502
- try {
1503
- if (!Store.Catalog.get(id)) await Store.Catalog.findCarouselCatalog(id)
1504
- const catalog = Store.Catalog.get(id);
1505
- if (catalog.productCollection && catalog.productCollection._models.length)
1506
- return JSON.parse(JSON.stringify(catalog.productCollection._models));
1507
- else return [];
1508
- } catch (error) {
1509
- return false;
1510
- }
1511
- };
1512
-
1513
-
1514
- window.WAPI.procFiles = async function (chat, blobs) {
1515
- if (!Array.isArray(blobs)) {
1516
- blobs = [blobs];
1517
- }
1518
- var mc = new Store.MediaCollection(chat);
1519
- await mc.processFiles((Debug.VERSION === '0.4.613') ? blobs : blobs.map(blob => { return { file: blob } }), chat, 1);
1520
- return mc
1521
- }
1522
- /**
1523
- * Sends product with image to chat
1524
- * @param imgBase64 Base64 image data
1525
- * @param chatid string the id of the chat that you want to send this product to
1526
- * @param caption string the caption you want to add to this message
1527
- * @param bizNumber string the @c.us number of the business account from which you want to grab the product
1528
- * @param productId string the id of the product within the main catalog of the aforementioned business
1529
- * @returns
1530
- */
1531
- window.WAPI.sendImageWithProduct = async function (imgBase64, chatid, caption, bizNumber, productId) {
1532
- await WAPI.refreshBusinessProfileProducts();
1533
- return await Store.Catalog.findCarouselCatalog(bizNumber).then(async cat => {
1534
- if (cat && cat[0]) {
1535
- const product = cat[0].productCollection.get(productId);
1536
- const temp = {
1537
- productMsgOptions: {
1538
- businessOwnerJid: product.catalogWid.toString({
1539
- legacy: !0
1540
- }),
1541
- productId: product.id.toString(),
1542
- url: product.url,
1543
- productImageCount: product.productImageCollection.length,
1544
- title: product.name,
1545
- description: product.description,
1546
- currencyCode: product.currency,
1547
- priceAmount1000: product.priceAmount1000,
1548
- type: "product"
1549
- },
1550
- caption
1551
- }
1552
-
1553
- // var idUser = new Store.WidFactory.createWid(chatid);
1554
-
1555
- return Store.Chat.find(chatid).then(async (chat) => {
1556
- var mediaBlob = window.WAPI.base64ImageToFile(imgBase64, "filename.jpg");
1557
- // var mc = new Store.MediaCollection(chat);
1558
- // mc.processFiles([mediaBlob], chat, 1)
1559
- return await window.WAPI.procFiles(chat, mediaBlob).then(async mc => {
1560
- var media = mc.models[0];
1561
- Object.entries(temp.productMsgOptions).map(([k, v]) => media.mediaPrep._mediaData[k] = v)
1562
- await media.mediaPrep.sendToChat(chat, temp);
1563
- return chat.lastReceivedKey._serialized;
1564
- });
1565
- });
1566
- }
1567
- })
1568
- }
1569
-
1570
- window.WAPI.base64ImageToFile = function (b64Data, filename) {
1571
- var arr = b64Data.split(',');
1572
- var mime = arr[0].match(/:(.*?);/)[1];
1573
- var bstr = window.Base64 ? window.Base64.atob(arr[1]) : atob(arr[1]);
1574
- var n = bstr.length;
1575
- var u8arr = new Uint8Array(n);
1576
-
1577
- while (n--) {
1578
- u8arr[n] = bstr.charCodeAt(n);
1579
- }
1580
-
1581
- return new File([u8arr], filename, { type: mime });
1582
- };
1583
-
1584
- /**
1585
- * Send contact card to a specific chat using the chat ids
1586
- *
1587
- * @param {string} to '000000000000@c.us'
1588
- * @param {string|array} contact '111111111111@c.us' | ['222222222222@c.us', '333333333333@c.us, ... 'nnnnnnnnnnnn@c.us']
1589
- */
1590
- window.WAPI.sendContact = function (to, contact) {
1591
- if (!Array.isArray(contact)) {
1592
- contact = [contact];
1593
- }
1594
- contact = contact.map((c) => {
1595
- return WAPI.getChat(c).__x_contact;
1596
- });
1597
-
1598
- if (contact.length > 1) {
1599
- window.WAPI.getChat(to).sendContactList(contact);
1600
- } else if (contact.length === 1) {
1601
- window.WAPI.getChat(to).sendContact(contact[0]);
1602
- }
1603
- };
1604
-
1605
- /**
1606
- * Ghost forwarding is like a normal forward but as if it were sent from the host phone.
1607
- */
1608
- window.WAPI.ghostForward = async function (chatId, messageId) {
1609
- if (!chatId.includes('@g') && !chatId.includes('@c')) return false;
1610
- var chat = Store.Chat.get(chatId);
1611
- if (!Store.Msg.get(messageId)) return false;
1612
- var tempMsg = Object.create(Store.Msg.get(messageId));
1613
- var newId = window.WAPI.getNewMessageId(chatId);
1614
- var extend = {
1615
- ...JSON.parse(JSON.stringify(tempMsg)),
1616
- ack: 0,
1617
- id: newId,
1618
- local: !0,
1619
- self: "out",
1620
- t: parseInt(new Date().getTime() / 1000),
1621
- to: new Store.WidFactory.createWid(chatId),
1622
- from: Store.Me.wid,
1623
- isNewMsg: true
1624
- };
1625
- Object.assign(tempMsg, extend);
1626
- const res = await Promise.all(Store.addAndSendMsgToChat(chat, extend))
1627
- return res[1] == 'success';
1628
- }
1629
-
1630
-
1631
- /**
1632
- * Forward an array of messages to a specific chat using the message ids or Objects
1633
- *
1634
- * @param {string} to '000000000000@c.us'
1635
- * @param {string|array[Message | string]} messages this can be any mixture of message ids or message objects
1636
- * @param {boolean} skipMyMessages This indicates whether or not to skip your own messages from the array
1637
- */
1638
- window.WAPI.forwardMessages = async function (to, messages, skipMyMessages) {
1639
- if (!Array.isArray(messages)) {
1640
- messages = [messages];
1641
- }
1642
- const finalForwardMessages = messages.map(msg => {
1643
- if (typeof msg == 'string') {
1644
- //msg is string, get the message object
1645
- return window.Store.Msg.get(msg);
1646
- } else {
1647
- return window.Store.Msg.get(msg.id);
1648
- }
1649
- }).filter(msg => skipMyMessages ? !msg.__x_isSentByMe : true);
1650
-
1651
- // let userId = new window.Store.UserConstructor(to);
1652
- let conversation = window.Store.Chat.get(to);
1653
- return await conversation.forwardMessages(finalForwardMessages)
1654
- };
1655
-
1656
- /**
1657
- * Create an chat ID based in a cloned one
1658
- *
1659
- * @param {string} chatId '000000000000@c.us'
1660
- */
1661
- window.WAPI.getNewMessageId = function (chatId) {
1662
- var newMsgId = new Store.MsgKey(Object.assign({}, Store.Msg.models[0].__x_id))
1663
- // .clone();
1664
-
1665
- newMsgId.fromMe = true;
1666
- newMsgId.id = WAPI.getNewId().toUpperCase();
1667
- newMsgId.remote = new Store.WidFactory.createWid(chatId);
1668
- newMsgId._serialized = `${newMsgId.fromMe}_${newMsgId.remote}_${newMsgId.id}`
1669
-
1670
- return newMsgId;
1671
- };
1672
-
1673
-
1674
- /**
1675
- * Simulate '...typing' in the chat.
1676
- *
1677
- * @param {string} chatId '000000000000@c.us'
1678
- * @param {boolean} on true to turn on similated typing, false to turn it off //you need to manually turn this off.
1679
- */
1680
- window.WAPI.simulateTyping = async function (chatId, on) {
1681
- if (on) Store.ChatStates.sendChatStateComposing(chatId)
1682
- else Store.ChatStates.sendChatStatePaused(chatId)
1683
- return true
1684
- };
1685
-
1686
- /**
1687
- * Send location
1688
- *
1689
- * @param {string} chatId '000000000000@c.us'
1690
- * @param {string} lat latitude
1691
- * @param {string} lng longitude
1692
- * @param {string} loc Text to go with the location message
1693
- */
1694
- window.WAPI.sendLocation = async function (chatId, lat, lng, loc) {
1695
- loc = loc || '';
1696
- var chat = Store.Chat.get(chatId);
1697
- if (!chat) return false;
1698
- var tempMsg = Object.create(Store.Msg.models.filter(msg => msg.__x_isSentByMe && !msg.quotedMsg)[0]);
1699
- var newId = window.WAPI.getNewMessageId(chatId);
1700
- var extend = {
1701
- ack: 0,
1702
- id: newId,
1703
- local: !0,
1704
- self: "out",
1705
- t: parseInt(new Date().getTime() / 1000),
1706
- to: chatId,
1707
- isNewMsg: !0,
1708
- type: "location",
1709
- lat,
1710
- lng,
1711
- loc,
1712
- clientUrl: undefined,
1713
- directPath: undefined,
1714
- filehash: undefined,
1715
- uploadhash: undefined,
1716
- mediaKey: undefined,
1717
- isQuotedMsgAvailable: false,
1718
- invis: false,
1719
- mediaKeyTimestamp: undefined,
1720
- mimetype: undefined,
1721
- height: undefined,
1722
- width: undefined,
1723
- ephemeralStartTimestamp: undefined,
1724
- body: undefined,
1725
- mediaData: undefined,
1726
- isQuotedMsgAvailable: false
1727
- };
1728
- Object.assign(tempMsg, extend);
1729
- return (await Promise.all(Store.addAndSendMsgToChat(chat, tempMsg)))[1] === 'success' ? newId._serialized : false;
1730
- };
1731
-
1732
- /**
1733
- * Send VCARD
1734
- *
1735
- * @param {string} chatId '000000000000@c.us'
1736
- * @param {string} vcard vcard as a string
1737
- * @param {string} contactName The display name for the contact. CANNOT BE NULL OTHERWISE IT WILL SEND SOME RANDOM CONTACT FROM YOUR ADDRESS BOOK.
1738
- * @param {string} contactNumber If supplied, this will be injected into the vcard (VERSION 3 ONLY FROM VCARDJS) with the WA id to make it show up with the correct buttons on WA.
1739
- */
1740
- window.WAPI.sendVCard = async function (chatId, vcard, contactName, contactNumber) {
1741
- var chat = Store.Chat.get(chatId);
1742
- var tempMsg = Object.create(Store.Msg.models.filter(msg => msg.__x_isSentByMe && !msg.quotedMsg)[0]);
1743
- var newId = window.WAPI.getNewMessageId(chatId);
1744
- var extend = {
1745
- ack: 0,
1746
- id: newId,
1747
- local: !0,
1748
- self: "out",
1749
- t: parseInt(new Date().getTime() / 1000),
1750
- to: chatId,
1751
- isNewMsg: !0,
1752
- type: "vcard",
1753
- clientUrl: undefined,
1754
- directPath: undefined,
1755
- filehash: undefined,
1756
- uploadhash: undefined,
1757
- mediaKey: undefined,
1758
- isQuotedMsgAvailable: false,
1759
- invis: false,
1760
- mediaKeyTimestamp: undefined,
1761
- mimetype: undefined,
1762
- height: undefined,
1763
- width: undefined,
1764
- ephemeralStartTimestamp: undefined,
1765
- body: contactNumber ? vcard.replace('TEL;TYPE=WORK,VOICE:', `TEL;TYPE=WORK,VOICE;waid=${contactNumber}:`) : vcard,
1766
- mediaData: undefined,
1767
- isQuotedMsgAvailable: false,
1768
- subtype: contactName
1769
- };
1770
- Object.assign(tempMsg, extend);
1771
- return (await Promise.all(Store.addAndSendMsgToChat(chat, tempMsg)))[1] == "success"
1772
- };
1773
-
1774
- window.WAPI.reply = async function (chatId, body, quotedMsg) {
1775
- if (typeof quotedMsg !== "object") quotedMsg = Store.Msg.get(quotedMsg)
1776
- var chat = Store.Chat.get(chatId);
1777
- if (!chat) return false;
1778
- let extras = {};
1779
- if (quotedMsg) {
1780
- extras = {
1781
- quotedParticipant: quotedMsg.author || quotedMsg.from,
1782
- quotedStanzaID: quotedMsg.id.id
1783
- };
1784
- }
1785
- var tempMsg = Object.create(Store.Msg.models.filter(msg => msg.__x_isSentByMe && !msg.quotedMsg)[0]);
1786
- var newId = window.WAPI.getNewMessageId(chatId);
1787
- var extend = {
1788
- ack: 0,
1789
- id: newId,
1790
- local: !0,
1791
- self: "out",
1792
- t: parseInt(new Date().getTime() / 1000),
1793
- to: new Store.WidFactory.createWid(chatId),
1794
- isNewMsg: !0,
1795
- type: "chat",
1796
- quotedMsg,
1797
- body,
1798
- ...extras
1799
- };
1800
- Object.assign(tempMsg, extend);
1801
- const res = await Promise.all(await Store.addAndSendMsgToChat(chat, tempMsg));
1802
- if (res[1] != 'success') return false;
1803
- return res[0].id._serialized
1804
- };
1805
-
1806
- /**
1807
- * Send Payment Request
1808
- *
1809
- * @param {string} chatId '000000000000@c.us'
1810
- * @param {string} amount1000 The amount in base value / 10 (e.g 50000 in GBP = £50)
1811
- * @param {string} currency Three letter currency code (e.g SAR, GBP, USD, INR, AED, EUR)
1812
- * @param {string} note message to send with the payment request
1813
- */
1814
- window.WAPI.sendPaymentRequest = async function (chatId, amount1000, currency, noteMessage) {
1815
- var chat = Store.Chat.get(chatId);
1816
- var tempMsg = Object.create(Store.Msg.models.filter(msg => msg.__x_isSentByMe && !msg.quotedMsg)[0]);
1817
- var newId = window.WAPI.getNewMessageId(chatId);
1818
- var extend = {
1819
- ack: 0,
1820
- id: newId,
1821
- local: !0,
1822
- self: "out",
1823
- t: parseInt(new Date().getTime() / 1000),
1824
- to: chatId,
1825
- isNewMsg: !0,
1826
- type: "payment",
1827
- subtype: "request",
1828
- amount1000,
1829
- requestFrom: chatId,
1830
- currency,
1831
- noteMessage,
1832
- expiryTimestamp: parseInt(new Date(new Date().setDate(new Date().getDate() + 1)).getTime() / 1000)
1833
- };
1834
- Object.assign(tempMsg, extend);
1835
- await Store.addAndSendMsgToChat(chat, tempMsg)
1836
- };
1837
-
1838
-
1839
-
1840
- /**
1841
- * Send Customized VCard without the necessity of contact be a WA Contact
1842
- *
1843
- * @param {string} chatId '000000000000@c.us'
1844
- * @param {object|array} vcard { displayName: 'Contact Name', vcard: 'BEGIN:VCARD\nVERSION:3.0\nN:;Contact Name;;;\nEND:VCARD' } | [{ displayName: 'Contact Name 1', vcard: 'BEGIN:VCARD\nVERSION:3.0\nN:;Contact Name 1;;;\nEND:VCARD' }, { displayName: 'Contact Name 2', vcard: 'BEGIN:VCARD\nVERSION:3.0\nN:;Contact Name 2;;;\nEND:VCARD' }]
1845
- */
1846
- window.WAPI._sendVCard = function (chatId, vcard) {
1847
- var chat = Store.Chat.get(chatId);
1848
- var tempMsg = Object.create(Store.Msg.models.filter(msg => msg.__x_isSentByMe && !msg.quotedMsg)[0]);
1849
- var newId = window.WAPI.getNewMessageId(chatId);
1850
-
1851
- var extend = {
1852
- ack: 0,
1853
- id: newId,
1854
- local: !0,
1855
- self: "out",
1856
- t: parseInt(new Date().getTime() / 1000),
1857
- to: chatId,
1858
- isNewMsg: !0,
1859
- isQuotedMsgAvailable: false,
1860
- };
1861
-
1862
- if (Array.isArray(vcard)) {
1863
- Object.assign(extend, {
1864
- type: "multi_vcard",
1865
- vcardList: vcard
1866
- });
1867
-
1868
- delete extend.body;
1869
- } else {
1870
- Object.assign(extend, {
1871
- type: "vcard",
1872
- subtype: vcard.displayName,
1873
- body: vcard.vcard
1874
- });
1875
-
1876
- delete extend.vcardList;
1877
- }
1878
-
1879
- Object.assign(tempMsg, extend);
1880
-
1881
- Store.addAndSendMsgToChat(chat, tempMsg)
1882
- };
1883
-
1884
- /**
1885
- * Block contact
1886
- * @param {string} id '000000000000@c.us'
1887
- */
1888
- window.WAPI.contactBlock = async function (id) {
1889
- const contact = window.Store.Contact.get(id);
1890
- if (contact !== undefined) {
1891
- await Store.Block.blockContact(contact)
1892
- return true;
1893
- }
1894
- return false;
1895
- }
1896
- /**
1897
- * Unblock contact
1898
- * @param {string} id '000000000000@c.us'
1899
- */
1900
- window.WAPI.contactUnblock = async function (id) {
1901
- const contact = window.Store.Contact.get(id);
1902
- if (contact !== undefined) {
1903
- await Store.Block.unblockContact(contact)
1904
- return true;
1905
- }
1906
- return false;
1907
- }
1908
-
1909
- /**
1910
- * Remove participant of Group
1911
- * @param {*} idGroup '0000000000-00000000@g.us'
1912
- * @param {*} idParticipant '000000000000@c.us'
1913
- */
1914
- window.WAPI.removeParticipant = async function (idGroup, idParticipant) {
1915
- const chat = Store.Chat.get(idGroup);
1916
- const rm = chat.groupMetadata.participants.get(idParticipant);
1917
- await window.Store.Participants.removeParticipants(chat, [rm]);
1918
- return true;
1919
- }
1920
-
1921
-
1922
- /**
1923
- * Add participant to Group
1924
- * @param {*} idGroup '0000000000-00000000@g.us'
1925
- * @param {*} idParticipant '000000000000@c.us'
1926
- */
1927
- window.WAPI.addParticipant = async function (idGroup, idParticipant) {
1928
- const chat = Store.Chat.get(idGroup);
1929
- const add = Store.Contact.get(idParticipant);
1930
- await window.Store.Participants.addParticipants(chat, [add]);
1931
- return true;
1932
- }
1933
-
1934
- /**
1935
- * Promote Participant to Admin in Group
1936
- * @param {*} idGroup '0000000000-00000000@g.us'
1937
- * @param {*} idParticipant '000000000000@c.us'
1938
- */
1939
- window.WAPI.promoteParticipant = async function (idGroup, idParticipant) {
1940
- const chat = Store.Chat.get(idGroup);
1941
- const promote = chat.groupMetadata.participants.get(idParticipant);
1942
- await window.Store.Participants.promoteParticipants(chat, [promote]);
1943
- return true;
1944
- }
1945
-
1946
- /**
1947
- * Demote Admin of Group
1948
- * @param {*} idGroup '0000000000-00000000@g.us'
1949
- * @param {*} idParticipant '000000000000@c.us'
1950
- */
1951
- window.WAPI.demoteParticipant = async function (idGroup, idParticipant) {
1952
- await window.Store.WapQuery.demoteParticipants(idGroup, [idParticipant])
1953
- const chat = Store.Chat.get(idGroup);
1954
- const demote = chat.groupMetadata.participants.get(idParticipant);
1955
- await window.Store.Participants.demoteParticipants(chat, [demote])
1956
- return true
1957
-
1958
- }
1959
-
1960
- /**
1961
- * @private
1962
- * Send Sticker
1963
- * @param {*} sticker
1964
- * @param {*} chatId '000000000000@c.us'
1965
- * @param metadata about the image. Based on [sharp metadata](https://sharp.pixelplumbing.com/api-input#metadata)
1966
- */
1967
- window.WAPI._sendSticker = async function (sticker, chatId, metadata) {
1968
- var chat = Store.Chat.get(chatId)
1969
- let stick = new window.Store.Sticker.modelClass();
1970
- stick.__x_clientUrl = sticker.clientUrl;
1971
- stick.__x_filehash = sticker.filehash;
1972
- stick.__x_id = sticker.filehash;
1973
- stick.__x_uploadhash = sticker.uploadhash;
1974
- stick.__x_mediaKey = sticker.mediaKey;
1975
- stick.__x_initialized = false;
1976
- stick.__x_mediaData.mediaStage = 'INIT';
1977
- stick.mimetype = 'image/webp';
1978
- stick.height = (metadata && metadata.height) ? metadata.height : 512;
1979
- stick.width = (metadata && metadata.width) ? metadata.width : 512;
1980
- await stick.initialize();
1981
- return await stick.sendToChat(chat);
1982
- };
1983
-
1984
- window.WAPI.getFileHash = async (data) => {
1985
- let buffer = await data.arrayBuffer();
1986
- var sha = new jsSHA("SHA-256", "ARRAYBUFFER");
1987
- sha.update(buffer);
1988
- return sha.getHash("B64");
1989
- };
1990
-
1991
- window.WAPI.generateMediaKey = async (length) => {
1992
- var result = '';
1993
- var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1994
- var charactersLength = characters.length;
1995
- for (var i = 0; i < length; i++) {
1996
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
1997
- }
1998
- return result;
1999
- };
2000
-
2001
- /**
2002
- * @param type: The type of file. {'audio' | 'sticker' | 'video' | 'product' | 'document' | 'gif' | 'image' | 'ptt' | 'template' | 'history' | 'ppic'}
2003
- * @param blob: file
2004
- */
2005
- window.WAPI.encryptAndUploadFile = async function (type, blob) {
2006
- let filehash = await window.WAPI.getFileHash(blob);
2007
- let mediaKey = await window.WAPI.generateMediaKey(32);
2008
- let controller = new AbortController();
2009
- let signal = controller.signal;
2010
- let encrypted = await window.Store.UploadUtils.encryptAndUpload({
2011
- blob,
2012
- type,
2013
- signal,
2014
- mediaKey
2015
- });
2016
- return {
2017
- ...encrypted,
2018
- clientUrl: encrypted.url,
2019
- filehash,
2020
- id: filehash,
2021
- uploadhash: encrypted.encFilehash,
2022
- };
2023
- };
2024
-
2025
- /**
2026
- * Send Image As Sticker
2027
- * @param {*} imageBase64 A valid webp image is required.
2028
- * @param {*} chatId '000000000000@c.us'
2029
- * @param metadata about the image. Based on [sharp metadata](https://sharp.pixelplumbing.com/api-input#metadata)
2030
- */
2031
- window.WAPI.sendImageAsSticker = async function (imageBase64, chatId, metadata) {
2032
- let mediaBlob = await window.WAPI.base64ImageToFile(
2033
- 'data:image/webp;base64,' + imageBase64,
2034
- 'file.webp'
2035
- );
2036
- let encrypted = await window.WAPI.encryptAndUploadFile("sticker", mediaBlob);
2037
- return await window.WAPI._sendSticker(encrypted, chatId, metadata);
2038
- };
2039
-
2040
- /**
2041
- This will dump all possible stickers into the chat. ONLY FOR TESTING. THIS IS REALLY ANNOYING!!
2042
- */
2043
- window.WAPI._STICKERDUMP = async function (chatId) {
2044
- var chat = Store.Chat.get(chatId);
2045
- let prIdx = await Store.StickerPack.pageWithIndex(0);
2046
- await Store.StickerPack.fetchAt(0);
2047
- await Store.StickerPack._pageFetchPromises[prIdx];
2048
- return await Promise.race(Store.StickerPack.models.forEach(pack => pack.stickers.fetch().then(_ => pack.stickers.models.forEach(stkr => stkr.sendToChat(chat))))).catch(e => { })
2049
- }
2050
-
2051
-
2052
- window.WAPI.getLastSeen = async function (id) {
2053
- if (!Store.Chat.get(id)) return false;
2054
- let { presence } = Store.Chat.get(id)
2055
- await presence.subscribe();
2056
- return presence.chatstate.t;
2057
- }
2058
-
2059
- window.WAPI.getUseHereString = async function () {
2060
- if (!window.l10n.localeStrings['en']) {
2061
- const originalLocale = window.l10n.getLocale();
2062
- await window.l10n.init('en');
2063
- await window.l10n.init(originalLocale)
2064
- }
2065
- return window.l10n.localeStrings[window.l10n.getLocale()][0][window.l10n.localeStrings.en[0].findIndex(x => x.toLowerCase() === 'use here')]
2066
- }
2067
-
2068
- window.WAPI.getAmountOfLoadedMessages = function () {
2069
- return Store.Msg.models.length;
2070
- }
2071
-
2072
- WAPI.getChatWithNonContacts = async function () {
2073
- return Store.Chat.models.map(chat => chat.contact && !chat.contact.isMyContact ? chat.contact : null).filter(x => x && !x.isGroup).map(WAPI._serializeContactObj)
2074
- }
2075
-
2076
- window.WAPI.cutMsgCache = function () {
2077
- Store.Msg.models.map(msg => Store.Msg.remove(msg));
2078
- return true;
2079
- }
2080
-
2081
- window.WAPI.getHostNumber = function () {
2082
- return WAPI.getMe().me.user;
2083
- }
2084
-
2085
- //All of the following features can be unlocked using a license key: https://github.com/open-wa/wa-automate-nodejs#license-key
2086
- window.WAPI.getStoryStatusByTimeStamp = function () { return false; }
2087
- window.WAPI.deleteAllStatus = function () { return false; }
2088
- window.WAPI.getMyStatusArray = function () { return false; }
2089
- window.WAPI.deleteStatus = function () { return false; }
2090
- window.WAPI.setGroupToAdminsOnly = function () { return false; }
2091
- window.WAPI.setGroupEditToAdminsOnly = function () { return false; }
2092
- window.WAPI.postTextStatus = function () { return false; }
2093
- window.WAPI.postImageStatus = function () { return false; }
2094
- window.WAPI.postVideoStatus = function () { return false; }
2095
- window.WAPI.onRemovedFromGroup = function () { return false; }
2096
- window.WAPI.onContactAdded = function () { return false; }
2097
- window.WAPI.sendReplyWithMentions = function () { return false; }
2098
- window.WAPI.clearAllChats = function () { return false; }
2099
- window.WAPI.getCommonGroups = function () { return false; }
2100
- window.WAPI.setChatBackgroundColourHex = function () { return false; }
2101
- window.WAPI.darkMode = function () { return false; }
2102
- window.WAPI.onChatOpened = function () { return false; }
2103
- window.WAPI.onStory = function () { return false; }
2104
- window.WAPI.getStoryViewers = function () { return false; }
2105
- window.WAPI.onChatState = function () { return false; }
2106
- window.WAPI.getStickerDecryptable = function () { return false; }
2107
- window.WAPI.forceStaleMediaUpdate = function () { return false; }
2108
- window.WAPI.setProfilePic = function () { return false; }
2109
- window.WAPI.setGroupDescription = function () { return false; }
2110
- window.WAPI.setGroupTitle = function () { return false; }
2111
- window.WAPI.tagEveryone = function () { return false; }
2112
-
2113
- /**
2114
- * Patches
2115
- */
2116
- window.WAPI.sendGiphyAsSticker = function () { return false; }
2117
- window.WAPI.getBlockedIds = function () { return false; }
2118
-
2119
- window.WAPI.quickClean = function (ob) {
2120
- var r = JSON.parse(JSON.stringify(ob));
2121
- if (r.mediaData && Object.keys(r.mediaData).length == 0) delete r.mediaData;
2122
- if (r.chat && Object.keys(r.chat).length == 0) delete r.chat;
2123
- Object.keys(r).filter(k => r[k] == "" || r[k] == [] || r[k] == {} || r[k] == null).forEach(k => delete r[k]);
2124
- Object.keys(r).filter(k => r[k] ? r[k]._serialized : false).forEach(k => r[k] = r[k]._serialized);
2125
- Object.keys(r).filter(k => r[k] ? r[k].id : false).forEach(k => r[k] = r[k].id);
2126
- return r;
2127
- };
2128
-
2129
- window.WAPI.pyFunc = async function (fn, done) {
2130
- return done(await fn())
2131
- }
2132
-
2133
- /**
2134
- * If you're using WAPI.js outside of open-wa: https://github.com/open-wa/wa-automate-nodejs/ then you can use the following code to enable the locked features above if you've got a license keu.
2135
- *
2136
- * THIS WILL NOT WORK OUT OF THE BOX. YOU WILL NEED TO DISAVLE CONTENT SECURITY POLICY (WHICH IS HIGHLY DISCOURAGED AND THE MAINTAINERS OF THIS CODE ASSUME NO RESPONSIBILITY FOR AY SECURITY VUNERABILITIES RESULTING IN DISABLING CSP)
2137
- *
2138
- * This is meant to act as an example of how to enable new features in wapi.js. You should implement this outside of the WA WEB browser context.
2139
- *
2140
- * Please use google to find out how to disable CSP. You can also use this extension: https://chrome.google.com/webstore/detail/disable-content-security/ieelmcmcagommplceebfedjlakkhpden/related?hl=en
2141
- */
2142
- window.WAPI.addLicenseKey = async function (key) {
2143
- const pkgR = await fetch('https://raw.githubusercontent.com/open-wa/wa-automate-nodejs/master/package.json');
2144
- const pkg = await pkgR.json();
2145
- const body = JSON.stringify({
2146
- number: Store.Me.me._serialized,
2147
- key
2148
- });
2149
- const r = await fetch(pkg.licenseCheckUrl, {
2150
- method: 'POST',
2151
- mode: 'cors',
2152
- cache: 'no-cache',
2153
- headers: {
2154
- 'Content-Type': 'application/json'
2155
- },
2156
- credentials: 'same-origin',
2157
- redirect: 'follow',
2158
- referrerPolicy: 'no-referrer',
2159
- body
2160
- })
2161
- const x = await r.text()
2162
- return eval(x);
2163
- }