fca-zoebakaaa 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. package/.eslintrc.js +35 -0
  2. package/CHANGELOG.md +2 -0
  3. package/Controllers/Remote.js +4 -0
  4. package/DOCS.md +1738 -0
  5. package/Extra/ExtraAddons.js +80 -0
  6. package/Extra/ExtraFindUID.js +62 -0
  7. package/Extra/ExtraGetThread.js +118 -0
  8. package/Extra/ExtraTranslate.js +62 -0
  9. package/Extra/ExtraUptimeRobot.js +62 -0
  10. package/Extra/Html/Classic/script.js +233 -0
  11. package/Extra/Html/Classic/style.css +8 -0
  12. package/Extra/PM2/ecosystem.config.js +23 -0
  13. package/Extra/Security/Index.js +174 -0
  14. package/Extra/Security/Step_1.js +15 -0
  15. package/Extra/Security/Step_2.js +23 -0
  16. package/Extra/Security/Step_3.js +23 -0
  17. package/Extra/Src/History.js +117 -0
  18. package/Extra/Src/Last-Run.js +65 -0
  19. package/Extra/Src/Premium.js +88 -0
  20. package/Extra/Src/SecurityCheck.js +7 -0
  21. package/Extra/database/SyntheticDatabase.sqlite +0 -0
  22. package/Extra/database/index.js +360 -0
  23. package/Extra/logger.js +74 -0
  24. package/Func/AcceptAgreement.js +36 -0
  25. package/Func/ClearCache.js +68 -0
  26. package/Func/ReportV1.js +55 -0
  27. package/README.md +112 -0
  28. package/Settings/Database.js +21 -0
  29. package/Settings/Location.js +59 -0
  30. package/broadcast.js +40 -0
  31. package/index.js +1353 -0
  32. package/logger.js +75 -0
  33. package/package.json +56 -0
  34. package/src/Premium.js +39 -0
  35. package/src/addExternalModule.js +23 -0
  36. package/src/addUserToGroup.js +101 -0
  37. package/src/appstate.json +0 -0
  38. package/src/changeAdminStatus.js +95 -0
  39. package/src/changeArchivedStatus.js +47 -0
  40. package/src/changeAvt.js +95 -0
  41. package/src/changeBio.js +66 -0
  42. package/src/changeBlockedStatus.js +42 -0
  43. package/src/changeGroupImage.js +124 -0
  44. package/src/changeNickname.js +54 -0
  45. package/src/changeThreadColor.js +67 -0
  46. package/src/changeThreadEmoji.js +50 -0
  47. package/src/createNewGroup.js +78 -0
  48. package/src/createPoll.js +66 -0
  49. package/src/deleteMessage.js +51 -0
  50. package/src/deleteThread.js +49 -0
  51. package/src/forwardAttachment.js +53 -0
  52. package/src/getAccessToken.js +36 -0
  53. package/src/getCurrentUserID.js +8 -0
  54. package/src/getEmojiUrl.js +29 -0
  55. package/src/getFriendsList.js +81 -0
  56. package/src/getMessage.js +85 -0
  57. package/src/getThreadHistory.js +633 -0
  58. package/src/getThreadInfo.js +248 -0
  59. package/src/getThreadList.js +276 -0
  60. package/src/getThreadPictures.js +71 -0
  61. package/src/getUID.js +61 -0
  62. package/src/getUserID.js +62 -0
  63. package/src/getUserInfo.js +68 -0
  64. package/src/getUserInfoV2.js +32 -0
  65. package/src/getUserInfoV3.js +72 -0
  66. package/src/getUserInfoV4.js +57 -0
  67. package/src/getUserInfoV5.js +68 -0
  68. package/src/handleFriendRequest.js +47 -0
  69. package/src/handleMessageRequest.js +63 -0
  70. package/src/httpGet.js +54 -0
  71. package/src/httpPost.js +53 -0
  72. package/src/httpPostFormData.js +46 -0
  73. package/src/listenMqtt.js +1056 -0
  74. package/src/logout.js +73 -0
  75. package/src/markAsDelivered.js +54 -0
  76. package/src/markAsRead.js +82 -0
  77. package/src/markAsReadAll.js +47 -0
  78. package/src/markAsSeen.js +58 -0
  79. package/src/muteThread.js +51 -0
  80. package/src/removeUserFromGroup.js +72 -0
  81. package/src/resolvePhotoUrl.js +39 -0
  82. package/src/searchForThread.js +48 -0
  83. package/src/sendMessage.js +429 -0
  84. package/src/sendTypingIndicator.js +83 -0
  85. package/src/setMessageReaction.js +114 -0
  86. package/src/setPostReaction.js +103 -0
  87. package/src/setTitle.js +86 -0
  88. package/src/threadColors.js +40 -0
  89. package/src/toolspincoinmaster +89 -0
  90. package/src/unfriend.js +48 -0
  91. package/src/unsendMessage.js +40 -0
  92. package/utils.js +2244 -0
  93. package/zoebaka.code-workspace +8 -0
@@ -0,0 +1,429 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Được Fix Hay Làm Màu Bởi: @HarryWakazaki
5
+ * 21/4/2022
6
+ */
7
+
8
+ var utils = require("../utils");
9
+ var log = require("npmlog");
10
+ var bluebird = require("bluebird");
11
+
12
+ var allowedProperties = {
13
+ attachment: true,
14
+ url: true,
15
+ sticker: true,
16
+ emoji: true,
17
+ emojiSize: true,
18
+ body: true,
19
+ mentions: true,
20
+ location: true,
21
+ };
22
+
23
+ module.exports = function (defaultFuncs, api, ctx) {
24
+ function uploadAttachment(attachments, callback) {
25
+ var uploads = [];
26
+
27
+ // create an array of promises
28
+ for (var i = 0; i < attachments.length; i++) {
29
+ if (!utils.isReadableStream(attachments[i]))
30
+ throw {
31
+ error:
32
+ "Attachment should be a readable stream and not " +
33
+ utils.getType(attachments[i]) +
34
+ ".",
35
+ };
36
+ var form = {
37
+ upload_1024: attachments[i],
38
+ voice_clip: "true",
39
+ };
40
+
41
+ uploads.push(
42
+ defaultFuncs
43
+ .postFormData(
44
+ "https://upload.facebook.com/ajax/mercury/upload.php",
45
+ ctx.jar,
46
+ form,
47
+ {},
48
+ )
49
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
50
+ .then(function (resData) {
51
+ if (resData.error) throw resData;
52
+ // We have to return the data unformatted unless we want to change it
53
+ // back in sendMessage.
54
+ return resData.payload.metadata[0];
55
+ }),
56
+ );
57
+ }
58
+
59
+ // resolve all promises
60
+ bluebird
61
+ .all(uploads)
62
+ .then((resData) => callback(null, resData))
63
+ .catch(function (err) {
64
+ log.error("uploadAttachment", err);
65
+ return callback(err);
66
+ });
67
+ }
68
+
69
+ function getUrl(url, callback) {
70
+ var form = {
71
+ image_height: 960,
72
+ image_width: 960,
73
+ uri: url,
74
+ };
75
+
76
+ defaultFuncs
77
+ .post(
78
+ "https://www.facebook.com/message_share_attachment/fromURI/",
79
+ ctx.jar,
80
+ form,
81
+ )
82
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
83
+ .then(function (resData) {
84
+ if (resData.error) return callback(resData);
85
+ if (!resData.payload) return callback({ error: "Invalid url" });
86
+ callback(null, resData.payload.share_data.share_params);
87
+ })
88
+ .catch(function (err) {
89
+ log.error("getUrl", err);
90
+ return callback(err);
91
+ });
92
+ }
93
+
94
+ function sendContent(form, threadID, isSingleUser, messageAndOTID, callback) {
95
+ // There are three cases here:
96
+ // 1. threadID is of type array, where we're starting a new group chat with users
97
+ // specified in the array.
98
+ // 2. User is sending a message to a specific user.
99
+ // 3. No additional form params and the message goes to an existing group chat.
100
+ if (utils.getType(threadID) === "Array") {
101
+ for (var i = 0; i < threadID.length; i++)
102
+ form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
103
+ form["specific_to_list[" + threadID.length + "]"] = "fbid:" + ctx.userID;
104
+ form["client_thread_id"] = "root:" + messageAndOTID;
105
+ log.info("sendMessage", "Sending message to multiple users: " + threadID);
106
+ } else {
107
+ // This means that threadID is the id of a user, and the chat
108
+ // is a single person chat
109
+ if (isSingleUser) {
110
+ form["specific_to_list[0]"] = "fbid:" + threadID;
111
+ form["specific_to_list[1]"] = "fbid:" + ctx.userID;
112
+ form["other_user_fbid"] = threadID;
113
+ } else form["thread_fbid"] = threadID;
114
+ }
115
+
116
+ if (ctx.globalOptions.pageID) {
117
+ form["author"] = "fbid:" + ctx.globalOptions.pageID;
118
+ form["specific_to_list[1]"] = "fbid:" + ctx.globalOptions.pageID;
119
+ form["creator_info[creatorID]"] = ctx.userID;
120
+ form["creator_info[creatorType]"] = "direct_admin";
121
+ form["creator_info[labelType]"] = "sent_message";
122
+ form["creator_info[pageID]"] = ctx.globalOptions.pageID;
123
+ form["request_user_id"] = ctx.globalOptions.pageID;
124
+ form["creator_info[profileURI]"] =
125
+ "https://www.facebook.com/profile.php?id=" + ctx.userID;
126
+ }
127
+
128
+ defaultFuncs
129
+ .post("https://www.facebook.com/messaging/send/", ctx.jar, form)
130
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
131
+ .then(function (resData) {
132
+ if (!resData) return callback({ error: "Send message failed." });
133
+ if (resData.error) {
134
+ if (resData.error === 1545012)
135
+ log.warn(
136
+ "sendMessage",
137
+ "Got error 1545012. This might mean that you're not part of the conversation " +
138
+ threadID,
139
+ );
140
+ return callback(resData);
141
+ }
142
+
143
+ var messageInfo = resData.payload.actions.reduce(function (p, v) {
144
+ return (
145
+ {
146
+ threadID: v.thread_fbid,
147
+ messageID: v.message_id,
148
+ timestamp: v.timestamp,
149
+ } || p
150
+ );
151
+ }, null);
152
+ return callback(null, messageInfo);
153
+ })
154
+ .catch(function (err) {
155
+ log.error("sendMessage", err);
156
+ if (utils.getType(err) == "Object" && err.error === "Not logged in.")
157
+ ctx.loggedIn = false;
158
+ return callback(err, null);
159
+ });
160
+ }
161
+
162
+ function send(form, threadID, messageAndOTID, callback, isGroup) {
163
+ //Full Fix sendMessage
164
+ if (utils.getType(threadID) === "Array")
165
+ sendContent(form, threadID, false, messageAndOTID, callback);
166
+ else {
167
+ var THREADFIX = "ThreadID".replace("ThreadID", threadID); // i cũng đôn nâu
168
+ if (THREADFIX.length <= 15 || globalThis.Fca.isUser.includes(threadID))
169
+ sendContent(form, threadID, !isGroup, messageAndOTID, callback);
170
+ else if (
171
+ (THREADFIX.length >= 15 && THREADFIX.indexOf(1) != 0) ||
172
+ globalThis.Fca.isThread.includes(threadID)
173
+ )
174
+ sendContent(
175
+ form,
176
+ threadID,
177
+ threadID.length === 15,
178
+ messageAndOTID,
179
+ callback,
180
+ );
181
+ else {
182
+ if (globalThis.Fca.Data.event.isGroup) {
183
+ sendContent(
184
+ form,
185
+ threadID,
186
+ threadID.length === 15,
187
+ messageAndOTID,
188
+ callback,
189
+ );
190
+ globalThis.Fca.isThread.push(threadID);
191
+ } else {
192
+ sendContent(form, threadID, !isGroup, messageAndOTID, callback);
193
+ globalThis.Fca.isUser.push(threadID);
194
+ }
195
+ }
196
+ }
197
+ }
198
+
199
+ function handleUrl(msg, form, callback, cb) {
200
+ if (msg.url) {
201
+ form["shareable_attachment[share_type]"] = "100";
202
+ getUrl(msg.url, function (err, params) {
203
+ if (err) return callback(err);
204
+ form["shareable_attachment[share_params]"] = params;
205
+ cb();
206
+ });
207
+ } else cb();
208
+ }
209
+
210
+ function handleLocation(msg, form, callback, cb) {
211
+ if (msg.location) {
212
+ if (msg.location.latitude == null || msg.location.longitude == null)
213
+ return callback({
214
+ error: "location property needs both latitude and longitude",
215
+ });
216
+ form["location_attachment[coordinates][latitude]"] =
217
+ msg.location.latitude;
218
+ form["location_attachment[coordinates][longitude]"] =
219
+ msg.location.longitude;
220
+ form["location_attachment[is_current_location]"] = !!msg.location.current;
221
+ }
222
+ cb();
223
+ }
224
+
225
+ function handleSticker(msg, form, callback, cb) {
226
+ if (msg.sticker) form["sticker_id"] = msg.sticker;
227
+ cb();
228
+ }
229
+
230
+ function handleEmoji(msg, form, callback, cb) {
231
+ if (msg.emojiSize != null && msg.emoji == null)
232
+ return callback({ error: "emoji property is empty" });
233
+ if (msg.emoji) {
234
+ if (msg.emojiSize == null) msg.emojiSize = "medium";
235
+ if (
236
+ msg.emojiSize != "small" &&
237
+ msg.emojiSize != "medium" &&
238
+ msg.emojiSize != "large"
239
+ )
240
+ return callback({ error: "emojiSize property is invalid" });
241
+ if (form["body"] != null && form["body"] != "")
242
+ return callback({ error: "body is not empty" });
243
+ form["body"] = msg.emoji;
244
+ form["tags[0]"] = "hot_emoji_size:" + msg.emojiSize;
245
+ }
246
+ cb();
247
+ }
248
+
249
+ function handleAttachment(msg, form, callback, cb) {
250
+ if (msg.attachment) {
251
+ form["image_ids"] = [];
252
+ form["gif_ids"] = [];
253
+ form["file_ids"] = [];
254
+ form["video_ids"] = [];
255
+ form["audio_ids"] = [];
256
+
257
+ if (utils.getType(msg.attachment) !== "Array")
258
+ msg.attachment = [msg.attachment];
259
+
260
+ uploadAttachment(msg.attachment, function (err, files) {
261
+ if (err) return callback(err);
262
+ files.forEach(function (file) {
263
+ var key = Object.keys(file);
264
+ var type = key[0]; // image_id, file_id, etc
265
+ form["" + type + "s"].push(file[type]); // push the id
266
+ });
267
+ cb();
268
+ });
269
+ } else cb();
270
+ }
271
+
272
+ function handleMention(msg, form, callback, cb) {
273
+ if (msg.mentions) {
274
+ for (let i = 0; i < msg.mentions.length; i++) {
275
+ const mention = msg.mentions[i];
276
+ const tag = mention.tag;
277
+ if (typeof tag !== "string")
278
+ return callback({ error: "Mention tags must be strings." });
279
+ const offset = msg.body.indexOf(tag, mention.fromIndex || 0);
280
+ if (offset < 0)
281
+ log.warn(
282
+ "handleMention",
283
+ 'Mention for "' + tag + '" not found in message string.',
284
+ );
285
+ if (mention.id == null)
286
+ log.warn("handleMention", "Mention id should be non-null.");
287
+
288
+ const id = mention.id || 0;
289
+ const emptyChar = "\u200E";
290
+ form["body"] = emptyChar + msg.body;
291
+ form["profile_xmd[" + i + "][offset]"] = offset + 1;
292
+ form["profile_xmd[" + i + "][length]"] = tag.length;
293
+ form["profile_xmd[" + i + "][id]"] = id;
294
+ form["profile_xmd[" + i + "][type]"] = "p";
295
+ }
296
+ }
297
+ cb();
298
+ }
299
+
300
+ return function sendMessage(
301
+ msg,
302
+ threadID,
303
+ callback,
304
+ replyToMessage,
305
+ isGroup,
306
+ ) {
307
+ typeof isGroup == "undefined" ? (isGroup = null) : "";
308
+ if (
309
+ !callback &&
310
+ (utils.getType(threadID) === "Function" ||
311
+ utils.getType(threadID) === "AsyncFunction")
312
+ )
313
+ return threadID({ error: "Pass a threadID as a second argument." });
314
+ if (!replyToMessage && utils.getType(callback) === "String") {
315
+ replyToMessage = callback;
316
+ callback = function () {};
317
+ }
318
+
319
+ var resolveFunc = function () {};
320
+ var rejectFunc = function () {};
321
+ var returnPromise = new Promise(function (resolve, reject) {
322
+ resolveFunc = resolve;
323
+ rejectFunc = reject;
324
+ });
325
+
326
+ if (!callback) {
327
+ callback = function (err, data) {
328
+ if (err) return rejectFunc(err);
329
+ resolveFunc(data);
330
+ };
331
+ }
332
+
333
+ var msgType = utils.getType(msg);
334
+ var threadIDType = utils.getType(threadID);
335
+ var messageIDType = utils.getType(replyToMessage);
336
+
337
+ if (msgType !== "String" && msgType !== "Object")
338
+ return callback({
339
+ error:
340
+ "Message should be of type string or object and not " + msgType + ".",
341
+ });
342
+
343
+ // Changing this to accomodate an array of users
344
+ if (
345
+ threadIDType !== "Array" &&
346
+ threadIDType !== "Number" &&
347
+ threadIDType !== "String"
348
+ )
349
+ return callback({
350
+ error:
351
+ "ThreadID should be of type number, string, or array and not " +
352
+ threadIDType +
353
+ ".",
354
+ });
355
+
356
+ if (replyToMessage && messageIDType !== "String")
357
+ return callback({
358
+ error:
359
+ "MessageID should be of type string and not " + threadIDType + ".",
360
+ });
361
+
362
+ if (msgType === "String") msg = { body: msg };
363
+ var disallowedProperties = Object.keys(msg).filter(
364
+ (prop) => !allowedProperties[prop],
365
+ );
366
+ if (disallowedProperties.length > 0)
367
+ return callback({
368
+ error: "Dissallowed props: `" + disallowedProperties.join(", ") + "`",
369
+ });
370
+
371
+ var messageAndOTID = utils.generateOfflineThreadingID();
372
+
373
+ var form = {
374
+ client: "mercury",
375
+ action_type: "ma-type:user-generated-message",
376
+ author: "fbid:" + ctx.userID,
377
+ timestamp: Date.now(),
378
+ timestamp_absolute: "Today",
379
+ timestamp_relative: utils.generateTimestampRelative(),
380
+ timestamp_time_passed: "0",
381
+ is_unread: false,
382
+ is_cleared: false,
383
+ is_forward: false,
384
+ is_filtered_content: false,
385
+ is_filtered_content_bh: false,
386
+ is_filtered_content_account: false,
387
+ is_filtered_content_quasar: false,
388
+ is_filtered_content_invalid_app: false,
389
+ is_spoof_warning: false,
390
+ source: "source:chat:web",
391
+ "source_tags[0]": "source:chat",
392
+ body: msg.body
393
+ ? msg.body
394
+ .toString()
395
+ .replace(
396
+ "\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f\ufe0f",
397
+ " ",
398
+ )
399
+ : "",
400
+ html_body: false,
401
+ ui_push_phase: "V3",
402
+ status: "0",
403
+ offline_threading_id: messageAndOTID,
404
+ message_id: messageAndOTID,
405
+ threading_id: utils.generateThreadingID(ctx.clientID),
406
+ "ephemeral_ttl_mode:": "0",
407
+ manual_retry_cnt: "0",
408
+ has_attachment: !!(msg.attachment || msg.url || msg.sticker),
409
+ signatureID: utils.getSignatureID(),
410
+ replied_to_message_id: replyToMessage,
411
+ };
412
+
413
+ handleLocation(msg, form, callback, () =>
414
+ handleSticker(msg, form, callback, () =>
415
+ handleAttachment(msg, form, callback, () =>
416
+ handleUrl(msg, form, callback, () =>
417
+ handleEmoji(msg, form, callback, () =>
418
+ handleMention(msg, form, callback, () =>
419
+ send(form, threadID, messageAndOTID, callback, isGroup),
420
+ ),
421
+ ),
422
+ ),
423
+ ),
424
+ ),
425
+ );
426
+
427
+ return returnPromise;
428
+ };
429
+ };
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+
3
+ import { getType, parseAndCheckLogin } from "../utils";
4
+ import { error, warn } from "npmlog";
5
+
6
+ export default function (defaultFuncs, api, ctx) {
7
+ function makeTypingIndicator(typ, threadID, callback, isGroup) {
8
+ var form = {
9
+ typ: +typ,
10
+ to: "",
11
+ source: "mercury-chat",
12
+ thread: threadID,
13
+ };
14
+
15
+ // Check if thread is a single person chat or a group chat
16
+ // More info on this is in api.sendMessage
17
+ if (getType(isGroup) == "Boolean") {
18
+ if (!isGroup) {
19
+ form.to = threadID;
20
+ }
21
+ defaultFuncs
22
+ .post("https://www.facebook.com/ajax/messaging/typ.php", ctx.jar, form)
23
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
24
+ .then(function (resData) {
25
+ if (resData.error) throw resData;
26
+ return callback();
27
+ })
28
+ .catch(function (err) {
29
+ error("sendTypingIndicator", err);
30
+ if (getType(err) == "Object" && err.error === "Not logged in") {
31
+ ctx.loggedIn = false;
32
+ }
33
+ return callback(err);
34
+ });
35
+ } else {
36
+ api.getUserInfo(threadID, function (err, res) {
37
+ if (err) return callback(err);
38
+ // If id is single person chat
39
+ if (Object.keys(res).length > 0) form.to = threadID;
40
+ defaultFuncs
41
+ .post(
42
+ "https://www.facebook.com/ajax/messaging/typ.php",
43
+ ctx.jar,
44
+ form,
45
+ )
46
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
47
+ .then(function (resData) {
48
+ if (resData.error) throw resData;
49
+ return callback();
50
+ })
51
+ .catch(function (err) {
52
+ error("sendTypingIndicator", err);
53
+ if (getType(err) == "Object" && err.error === "Not logged in.")
54
+ ctx.loggedIn = false;
55
+ return callback(err);
56
+ });
57
+ });
58
+ }
59
+ }
60
+
61
+ return function sendTypingIndicator(threadID, callback, isGroup) {
62
+ if (
63
+ getType(callback) !== "Function" &&
64
+ getType(callback) !== "AsyncFunction"
65
+ ) {
66
+ if (callback)
67
+ warn("sendTypingIndicator", "callback is not a function - ignoring.");
68
+ callback = () => {};
69
+ }
70
+
71
+ makeTypingIndicator(true, threadID, callback, isGroup);
72
+
73
+ return function end(cb) {
74
+ if (getType(cb) !== "Function" && getType(cb) !== "AsyncFunction") {
75
+ if (cb)
76
+ warn("sendTypingIndicator", "callback is not a function - ignoring.");
77
+ cb = () => {};
78
+ }
79
+
80
+ makeTypingIndicator(false, threadID, cb, isGroup);
81
+ };
82
+ };
83
+ }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+
3
+ import { parseAndCheckLogin } from "../utils";
4
+ import { error as _error } from "npmlog";
5
+
6
+ export default function (defaultFuncs, api, ctx) {
7
+ return function setMessageReaction(
8
+ reaction,
9
+ messageID,
10
+ callback,
11
+ forceCustomReaction,
12
+ ) {
13
+ var resolveFunc = function () {};
14
+ var rejectFunc = function () {};
15
+ var returnPromise = new Promise(function (resolve, reject) {
16
+ resolveFunc = resolve;
17
+ rejectFunc = reject;
18
+ });
19
+
20
+ if (!callback) {
21
+ callback = function (err, data) {
22
+ if (err) return rejectFunc(err);
23
+ resolveFunc(data);
24
+ };
25
+ }
26
+
27
+ switch (reaction) {
28
+ case "\uD83D\uDE0D": //:heart_eyes:
29
+ case "\uD83D\uDE06": //:laughing:
30
+ case "\uD83D\uDE2E": //:open_mouth:
31
+ case "\uD83D\uDE22": //:cry:
32
+ case "\uD83D\uDE20": //:angry:
33
+ case "\uD83D\uDC4D": //:thumbsup:
34
+ case "\uD83D\uDC4E": //:thumbsdown:
35
+ case "\u2764": //:heart:
36
+ case "\uD83D\uDC97": //:glowingheart:
37
+ case "":
38
+ //valid
39
+ break;
40
+ case ":heart_eyes:":
41
+ case ":love:":
42
+ reaction = "\uD83D\uDE0D";
43
+ break;
44
+ case ":laughing:":
45
+ case ":haha:":
46
+ reaction = "\uD83D\uDE06";
47
+ break;
48
+ case ":open_mouth:":
49
+ case ":wow:":
50
+ reaction = "\uD83D\uDE2E";
51
+ break;
52
+ case ":cry:":
53
+ case ":sad:":
54
+ reaction = "\uD83D\uDE22";
55
+ break;
56
+ case ":angry:":
57
+ reaction = "\uD83D\uDE20";
58
+ break;
59
+ case ":thumbsup:":
60
+ case ":like:":
61
+ reaction = "\uD83D\uDC4D";
62
+ break;
63
+ case ":thumbsdown:":
64
+ case ":dislike:":
65
+ reaction = "\uD83D\uDC4E";
66
+ break;
67
+ case ":heart:":
68
+ reaction = "\u2764";
69
+ break;
70
+ case ":glowingheart:":
71
+ reaction = "\uD83D\uDC97";
72
+ break;
73
+ default:
74
+ if (forceCustomReaction) break;
75
+ return callback({ error: "Reaction is not a valid emoji." });
76
+ }
77
+
78
+ var variables = {
79
+ data: {
80
+ client_mutation_id: ctx.clientMutationId++,
81
+ actor_id: ctx.userID,
82
+ action: reaction == "" ? "REMOVE_REACTION" : "ADD_REACTION",
83
+ message_id: messageID,
84
+ reaction: reaction,
85
+ },
86
+ };
87
+
88
+ var qs = {
89
+ doc_id: "1491398900900362",
90
+ variables: JSON.stringify(variables),
91
+ dpr: 1,
92
+ };
93
+
94
+ defaultFuncs
95
+ .postFormData(
96
+ "https://www.facebook.com/webgraphql/mutation/",
97
+ ctx.jar,
98
+ {},
99
+ qs,
100
+ )
101
+ .then(parseAndCheckLogin(ctx.jar, defaultFuncs))
102
+ .then(function (resData) {
103
+ if (!resData) throw { error: "setReaction returned empty object." };
104
+ if (resData.error) throw resData;
105
+ callback(null);
106
+ })
107
+ .catch(function (err) {
108
+ _error("setReaction", err);
109
+ return callback(err);
110
+ });
111
+
112
+ return returnPromise;
113
+ };
114
+ }