fb-nextgen 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fb-nextgen might be problematic. Click here for more details.

Files changed (76) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -0
  2. package/.cache/replit/nix/env.json +1 -0
  3. package/.config/configstore/update-notifier-npm.json +4 -0
  4. package/.github/workflows/nodejs.yml +26 -0
  5. package/.github/workflows/npmpublish.yml +30 -0
  6. package/.travis.yml +6 -0
  7. package/LICENSE-MIT +21 -0
  8. package/README.md +216 -0
  9. package/index.js +613 -0
  10. package/package.json +108 -0
  11. package/replit.nix +6 -0
  12. package/src/addExternalModule.js +19 -0
  13. package/src/addUserToGroup.js +113 -0
  14. package/src/changeAdminStatus.js +79 -0
  15. package/src/changeArchivedStatus.js +55 -0
  16. package/src/changeBio.js +77 -0
  17. package/src/changeBlockedStatus.js +47 -0
  18. package/src/changeGroupImage.js +129 -0
  19. package/src/changeNickname.js +59 -0
  20. package/src/changeThreadColor.js +71 -0
  21. package/src/changeThreadEmoji.js +55 -0
  22. package/src/createNewGroup.js +86 -0
  23. package/src/createPoll.js +71 -0
  24. package/src/deleteMessage.js +56 -0
  25. package/src/deleteThread.js +56 -0
  26. package/src/forwardAttachment.js +60 -0
  27. package/src/getCurrentUserID.js +7 -0
  28. package/src/getEmojiUrl.js +29 -0
  29. package/src/getFriendsList.js +84 -0
  30. package/src/getThreadHistory.js +645 -0
  31. package/src/getThreadHistoryDeprecated.js +93 -0
  32. package/src/getThreadInfo.js +148 -0
  33. package/src/getThreadInfoDeprecated.js +80 -0
  34. package/src/getThreadList.js +238 -0
  35. package/src/getThreadListDeprecated.js +75 -0
  36. package/src/getThreadPictures.js +79 -0
  37. package/src/getUserID.js +66 -0
  38. package/src/getUserInfo.js +76 -0
  39. package/src/handleFriendRequest.js +61 -0
  40. package/src/handleMessageRequest.js +65 -0
  41. package/src/httpGet.js +52 -0
  42. package/src/httpPost.js +52 -0
  43. package/src/listenMqtt.js +788 -0
  44. package/src/logout.js +75 -0
  45. package/src/markAsDelivered.js +58 -0
  46. package/src/markAsRead.js +80 -0
  47. package/src/markAsReadAll.js +50 -0
  48. package/src/markAsSeen.js +59 -0
  49. package/src/muteThread.js +52 -0
  50. package/src/removeUserFromGroup.js +79 -0
  51. package/src/resolvePhotoUrl.js +37 -0
  52. package/src/searchForThread.js +53 -0
  53. package/src/sendMessage.js +383 -0
  54. package/src/sendTypingIndicator.js +103 -0
  55. package/src/setMessageReaction.js +117 -0
  56. package/src/setPostReaction.js +76 -0
  57. package/src/setTitle.js +86 -0
  58. package/src/threadColors.js +57 -0
  59. package/src/unfriend.js +52 -0
  60. package/src/unsendMessage.js +49 -0
  61. package/src-cmd/bard.js +5048 -0
  62. package/src-cmd/gptdm.js +4175 -0
  63. package/src-cmd/gptgo.js +4253 -0
  64. package/src-cmd/gscholar.js +3747 -0
  65. package/src-cmd/openai.js +7370 -0
  66. package/src-cmd/playstore.js +1 -0
  67. package/src-cmd/skibiditoilet.js +4034 -0
  68. package/test/data/shareAttach.js +146 -0
  69. package/test/data/something.mov +0 -0
  70. package/test/data/test.png +0 -0
  71. package/test/data/test.txt +7 -0
  72. package/test/example-config.json +18 -0
  73. package/test/test-page.js +140 -0
  74. package/test/test.js +385 -0
  75. package/uptime.js +1 -0
  76. package/utils.js +1241 -0
@@ -0,0 +1,383 @@
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])) throw { error: "Attachment should be a readable stream and not " + utils.getType(attachments[i]) + "." };
30
+ var form = {
31
+ upload_1024: attachments[i],
32
+ voice_clip: "true"
33
+ };
34
+
35
+ uploads.push(
36
+ defaultFuncs
37
+ .postFormData("https://upload.facebook.com/ajax/mercury/upload.php", ctx.jar, form, {})
38
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
39
+ .then(function (resData) {
40
+ if (resData.error) throw resData;
41
+ // We have to return the data unformatted unless we want to change it
42
+ // back in sendMessage.
43
+ return resData.payload.metadata[0];
44
+ })
45
+ );
46
+ }
47
+
48
+ // resolve all promises
49
+ bluebird
50
+ .all(uploads)
51
+ .then(resData => callback(null, resData)
52
+ )
53
+ .catch(function (err) {
54
+ log.error("uploadAttachment", err);
55
+ return callback(err);
56
+ });
57
+ }
58
+
59
+ function getUrl(url, callback) {
60
+ var form = {
61
+ image_height: 960,
62
+ image_width: 960,
63
+ uri: url
64
+ };
65
+
66
+ defaultFuncs
67
+ .post("https://www.facebook.com/message_share_attachment/fromURI/", ctx.jar, form)
68
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
69
+ .then(function (resData) {
70
+ if (resData.error) return callback(resData);
71
+ if (!resData.payload) return callback({ error: "Invalid url" });
72
+ callback(null, resData.payload.share_data.share_params);
73
+ })
74
+ .catch(function (err) {
75
+ log.error("getUrl", err);
76
+ return callback(err);
77
+ });
78
+ }
79
+
80
+ function sendContent(form, threadID, isSingleUser, messageAndOTID, callback) {
81
+ // There are three cases here:
82
+ // 1. threadID is of type array, where we're starting a new group chat with users
83
+ // specified in the array.
84
+ // 2. User is sending a message to a specific user.
85
+ // 3. No additional form params and the message goes to an existing group chat.
86
+ if (utils.getType(threadID) === "Array") {
87
+ for (var i = 0; i < threadID.length; i++) form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
88
+ form["specific_to_list[" + threadID.length + "]"] = "fbid:" + ctx.userID;
89
+ form["client_thread_id"] = "root:" + messageAndOTID;
90
+ log.info("sendMessage", "Sending message to multiple users: " + threadID);
91
+ }
92
+ else {
93
+ // This means that threadID is the id of a user, and the chat
94
+ // is a single person chat
95
+ if (isSingleUser) {
96
+ form["specific_to_list[0]"] = "fbid:" + threadID;
97
+ form["specific_to_list[1]"] = "fbid:" + ctx.userID;
98
+ form["other_user_fbid"] = threadID;
99
+ }
100
+ else form["thread_fbid"] = threadID;
101
+ }
102
+
103
+ if (ctx.globalOptions.pageID) {
104
+ form["author"] = "fbid:" + ctx.globalOptions.pageID;
105
+ form["specific_to_list[1]"] = "fbid:" + ctx.globalOptions.pageID;
106
+ form["creator_info[creatorID]"] = ctx.userID;
107
+ form["creator_info[creatorType]"] = "direct_admin";
108
+ form["creator_info[labelType]"] = "sent_message";
109
+ form["creator_info[pageID]"] = ctx.globalOptions.pageID;
110
+ form["request_user_id"] = ctx.globalOptions.pageID;
111
+ form["creator_info[profileURI]"] = "https://www.facebook.com/profile.php?id=" + ctx.userID;
112
+ }
113
+
114
+ defaultFuncs
115
+ .post("https://www.facebook.com/messaging/send/", ctx.jar, form)
116
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
117
+ .then(function (resData) {
118
+ if (!resData) return callback({ error: "Send message failed." });
119
+ if (resData.error) {
120
+ if (resData.error === 1545012) log.warn("sendMessage", "Got error 1545012. This might mean that you're not part of the conversation " + threadID);
121
+ return callback(resData);
122
+ }
123
+
124
+ var messageInfo = resData.payload.actions.reduce(function (p, v) {
125
+ return (
126
+ {
127
+ threadID: v.thread_fbid,
128
+ messageID: v.message_id,
129
+ timestamp: v.timestamp
130
+ } || p
131
+ );
132
+ }, null);
133
+ return callback(null, messageInfo);
134
+ })
135
+ .catch(function (err) {
136
+ log.error("sendMessage", err);
137
+ if (utils.getType(err) == "Object" && err.error === "Not logged in.") ctx.loggedIn = false;
138
+ return callback(err,null);
139
+ });
140
+ }
141
+
142
+ function send(form, threadID, messageAndOTID, callback, isGroup) {
143
+ //Full Fix sendMessage
144
+ if (utils.getType(threadID) === "Array") sendContent(form, threadID, false, messageAndOTID, callback);
145
+ else {
146
+ var THREADFIX = "ThreadID".replace("ThreadID",threadID); // i cũng đôn nâu
147
+ if (THREADFIX.length <= 15 || global.Fca.isUser.includes(threadID)) sendContent(form, threadID, !isGroup, messageAndOTID, callback);
148
+ else if (THREADFIX.length >= 15 && THREADFIX.indexOf(1) != 0 || global.Fca.isThread.includes(threadID)) sendContent(form, threadID, threadID.length === 15, messageAndOTID, callback);
149
+ else {
150
+ if (global.Fca.Data.event.isGroup) {
151
+ sendContent(form, threadID, threadID.length === 15, messageAndOTID, callback);
152
+ global.Fca.isThread.push(threadID);
153
+ }
154
+ else {
155
+ sendContent(form, threadID, !isGroup, messageAndOTID, callback);
156
+ global.Fca.isUser.push(threadID)
157
+ }
158
+ }
159
+ }
160
+ }
161
+
162
+ function handleUrl(msg, form, callback, cb) {
163
+ if (msg.url) {
164
+ form["shareable_attachment[share_type]"] = "100";
165
+ getUrl(msg.url, function (err, params) {
166
+ if (err) return callback(err);
167
+ form["shareable_attachment[share_params]"] = params;
168
+ cb();
169
+ });
170
+ }
171
+ else cb();
172
+ }
173
+
174
+ function handleLocation(msg, form, callback, cb) {
175
+ if (msg.location) {
176
+ if (msg.location.latitude == null || msg.location.longitude == null) return callback({ error: "location property needs both latitude and longitude" });
177
+ form["location_attachment[coordinates][latitude]"] = msg.location.latitude;
178
+ form["location_attachment[coordinates][longitude]"] = msg.location.longitude;
179
+ form["location_attachment[is_current_location]"] = !!msg.location.current;
180
+ }
181
+ cb();
182
+ }
183
+
184
+ function handleSticker(msg, form, callback, cb) {
185
+ if (msg.sticker) form["sticker_id"] = msg.sticker;
186
+ cb();
187
+ }
188
+
189
+ function handleEmoji(msg, form, callback, cb) {
190
+ if (msg.emojiSize != null && msg.emoji == null) return callback({ error: "emoji property is empty" });
191
+ if (msg.emoji) {
192
+ if (msg.emojiSize == null) msg.emojiSize = "medium";
193
+ if (msg.emojiSize != "small" && msg.emojiSize != "medium" && msg.emojiSize != "large") return callback({ error: "emojiSize property is invalid" });
194
+ if (form["body"] != null && form["body"] != "") return callback({ error: "body is not empty" });
195
+ form["body"] = msg.emoji;
196
+ form["tags[0]"] = "hot_emoji_size:" + msg.emojiSize;
197
+ }
198
+ cb();
199
+ }
200
+
201
+ function handleAttachment(msg, form, callback, cb) {
202
+ if (msg.attachment) {
203
+ form["image_ids"] = [];
204
+ form["gif_ids"] = [];
205
+ form["file_ids"] = [];
206
+ form["video_ids"] = [];
207
+ form["audio_ids"] = [];
208
+
209
+ if (utils.getType(msg.attachment) !== "Array") msg.attachment = [msg.attachment];
210
+
211
+ uploadAttachment(msg.attachment, function (err, files) {
212
+ if (err) return callback(err);
213
+ files.forEach(function (file) {
214
+ var key = Object.keys(file);
215
+ var type = key[0]; // image_id, file_id, etc
216
+ form["" + type + "s"].push(file[type]); // push the id
217
+ });
218
+ cb();
219
+ });
220
+ }
221
+ else cb();
222
+ }
223
+
224
+ function handleMention(msg, form, callback, cb) {
225
+ if (msg.mentions) {
226
+ for (let i = 0; i < msg.mentions.length; i++) {
227
+ const mention = msg.mentions[i];
228
+ const tag = mention.tag;
229
+ if (typeof tag !== "string") return callback({ error: "Mention tags must be strings." });
230
+ const offset = msg.body.indexOf(tag, mention.fromIndex || 0);
231
+ if (offset < 0) log.warn("handleMention", 'Mention for "' + tag + '" not found in message string.');
232
+ if (mention.id == null) log.warn("handleMention", "Mention id should be non-null.");
233
+
234
+ const id = mention.id || 0;
235
+ const emptyChar = '\u200E';
236
+ form["body"] = emptyChar + msg.body;
237
+ form["profile_xmd[" + i + "][offset]"] = offset + 1;
238
+ form["profile_xmd[" + i + "][length]"] = tag.length;
239
+ form["profile_xmd[" + i + "][id]"] = id;
240
+ form["profile_xmd[" + i + "][type]"] = "p";
241
+ }
242
+ }
243
+ cb();
244
+ }
245
+ function convertToCustomFont(text) {
246
+ const customFontMap = {
247
+ a: "𝖺", b: "𝖻", c: "𝖼", d: "𝖽", e: "𝖾", f: "𝖿", g: "𝗀", h: "𝗁", i: "𝗂",
248
+ j: "𝗃", k: "𝗄", l: "𝗅", m: "𝗆", n: "𝗇", o: "𝗈", p: "𝗉", q: "𝗊", r: "𝗋",
249
+ s: "𝗌", t: "𝗍", u: "𝗎", v: "𝗏", w: "𝗐", x: "𝗑", y: "𝗒", z: "𝗓",
250
+ A: "𝖠", B: "𝖡", C: "𝖢", D: "𝖣", E: "𝖤", F: "𝖥", G: "𝖦", H: "𝖧", I: "𝖨",
251
+ J: "𝖩", K: "𝖪", L: "𝖫", M: "𝖬", N: "𝖭", O: "𝖮", P: "𝖯", Q: "𝖰", R: "𝖱",
252
+ S: "𝖲", T: "𝖳", U: "𝖴", V: "𝖵", W: "𝖶", X: "𝖷", Y: "𝖸", Z: "𝖹",
253
+ };
254
+
255
+ // Regular expression to detect URLs in the text
256
+ const urlRegex = /(\bhttps?:\/\/\S+\.\S+\b|\bwww\.\S+\.\S+\b)/gi;
257
+
258
+ return text.split(" ").map((word) => {
259
+ // Skip conversion if the word is a URL
260
+ if (urlRegex.test(word)) {
261
+ return word;
262
+ } else {
263
+ return word.split("").map((char) => customFontMap[char] || char).join("");
264
+ }
265
+ }).join(" ");
266
+ }
267
+
268
+ function convertMsgToCustomFont(msg) {
269
+ if (typeof msg === 'string') {
270
+ return { body: convertToCustomFont(msg) };
271
+ } else if (typeof msg === 'object') {
272
+ const convertedMsg = {};
273
+ for (const prop in msg) {
274
+ if (msg.hasOwnProperty(prop)) {
275
+ if (typeof msg[prop] === 'string') {
276
+ convertedMsg[prop] = convertToCustomFont(msg[prop]);
277
+ } else {
278
+ convertedMsg[prop] = msg[prop];
279
+ }
280
+ }
281
+ }
282
+ return convertedMsg;
283
+ } else {
284
+ return msg;
285
+ }
286
+ }
287
+ if (!global.Fca) {
288
+ global.Fca = {};
289
+ }
290
+
291
+ if (!global.Fca.isUser) {
292
+ global.Fca.isUser = [];
293
+ }
294
+ return function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
295
+ typeof isGroup == "undefined" ? isGroup = null : "";
296
+ if (!callback && (utils.getType(threadID) === "Function" || utils.getType(threadID) === "AsyncFunction")) return threadID({ error: "Pass a threadID as a second argument." });
297
+ if (!replyToMessage && utils.getType(callback) === "String") {
298
+ replyToMessage = callback;
299
+ callback = function () { };
300
+ }
301
+
302
+ var resolveFunc = function () { };
303
+ var rejectFunc = function () { };
304
+ var returnPromise = new Promise(function (resolve, reject) {
305
+ resolveFunc = resolve;
306
+ rejectFunc = reject;
307
+ });
308
+
309
+ if (!callback) {
310
+ callback = function (err, data) {
311
+ if (err) return rejectFunc(err);
312
+ resolveFunc(data);
313
+ };
314
+ }
315
+
316
+ var msgType = utils.getType(msg);
317
+ var threadIDType = utils.getType(threadID);
318
+ var messageIDType = utils.getType(replyToMessage);
319
+
320
+ if (msgType !== "String" && msgType !== "Object") return callback({ error: "Message should be of type string or object and not " + msgType + "." });
321
+
322
+ // Changing this to accomodate an array of users
323
+ if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") return callback({ error: "ThreadID should be of type number, string, or array and not " + threadIDType + "." });
324
+
325
+ if (replyToMessage && messageIDType !== 'String') return callback({ error: "MessageID should be of type string and not " + threadIDType + "." });
326
+
327
+ msg = convertMsgToCustomFont(msg);
328
+ var disallowedProperties = Object.keys(msg).filter(prop => !allowedProperties[prop]);
329
+ if (disallowedProperties.length > 0) return callback({ error: "Dissallowed props: `" + disallowedProperties.join(", ") + "`" });
330
+
331
+ var messageAndOTID = utils.generateOfflineThreadingID();
332
+
333
+ var form = {
334
+ client: "mercury",
335
+ action_type: "ma-type:user-generated-message",
336
+ author: "fbid:" + ctx.userID,
337
+ timestamp: Date.now(),
338
+ timestamp_absolute: "Today",
339
+ timestamp_relative: utils.generateTimestampRelative(),
340
+ timestamp_time_passed: "0",
341
+ is_unread: false,
342
+ is_cleared: false,
343
+ is_forward: false,
344
+ is_filtered_content: false,
345
+ is_filtered_content_bh: false,
346
+ is_filtered_content_account: false,
347
+ is_filtered_content_quasar: false,
348
+ is_filtered_content_invalid_app: false,
349
+ is_spoof_warning: false,
350
+ source: "source:chat:web",
351
+ "source_tags[0]": "source:chat",
352
+ body: msg.body ? msg.body.toString().replace("\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",' ') : "",
353
+ html_body: false,
354
+ ui_push_phase: "V3",
355
+ status: "0",
356
+ offline_threading_id: messageAndOTID,
357
+ message_id: messageAndOTID,
358
+ threading_id: utils.generateThreadingID(ctx.clientID),
359
+ "ephemeral_ttl_mode:": "0",
360
+ manual_retry_cnt: "0",
361
+ has_attachment: !!(msg.attachment || msg.url || msg.sticker),
362
+ signatureID: utils.getSignatureID(),
363
+ replied_to_message_id: replyToMessage
364
+ };
365
+
366
+ handleLocation(msg, form, callback, () =>
367
+ handleSticker(msg, form, callback, () =>
368
+ handleAttachment(msg, form, callback, () =>
369
+ handleUrl(msg, form, callback, () =>
370
+ handleEmoji(msg, form, callback, () =>
371
+ handleMention(msg, form, callback, () =>
372
+ send(form, threadID, messageAndOTID, callback, isGroup)
373
+ )
374
+ )
375
+ )
376
+ )
377
+ )
378
+ );
379
+
380
+ return returnPromise;
381
+ };
382
+ };
383
+
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = 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 (utils.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(utils.parseAndCheckLogin(ctx, defaultFuncs))
24
+ .then(function (resData) {
25
+ if (resData.error) {
26
+ throw resData;
27
+ }
28
+
29
+ return callback();
30
+ })
31
+ .catch(function (err) {
32
+ log.error("sendTypingIndicator", err);
33
+ if (utils.getType(err) == "Object" && err.error === "Not logged in") {
34
+ ctx.loggedIn = false;
35
+ }
36
+ return callback(err);
37
+ });
38
+ } else {
39
+ api.getUserInfo(threadID, function (err, res) {
40
+ if (err) {
41
+ return callback(err);
42
+ }
43
+
44
+ // If id is single person chat
45
+ if (Object.keys(res).length > 0) {
46
+ form.to = threadID;
47
+ }
48
+
49
+ defaultFuncs
50
+ .post("https://www.facebook.com/ajax/messaging/typ.php", ctx.jar, form)
51
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
52
+ .then(function (resData) {
53
+ if (resData.error) {
54
+ throw resData;
55
+ }
56
+
57
+ return callback();
58
+ })
59
+ .catch(function (err) {
60
+ log.error("sendTypingIndicator", err);
61
+ if (utils.getType(err) == "Object" && err.error === "Not logged in.") {
62
+ ctx.loggedIn = false;
63
+ }
64
+ return callback(err);
65
+ });
66
+ });
67
+ }
68
+ }
69
+
70
+ return function sendTypingIndicator(threadID, callback, isGroup) {
71
+ if (
72
+ utils.getType(callback) !== "Function" &&
73
+ utils.getType(callback) !== "AsyncFunction"
74
+ ) {
75
+ if (callback) {
76
+ log.warn(
77
+ "sendTypingIndicator",
78
+ "callback is not a function - ignoring."
79
+ );
80
+ }
81
+ callback = () => { };
82
+ }
83
+
84
+ makeTypingIndicator(true, threadID, callback, isGroup);
85
+
86
+ return function end(cb) {
87
+ if (
88
+ utils.getType(cb) !== "Function" &&
89
+ utils.getType(cb) !== "AsyncFunction"
90
+ ) {
91
+ if (cb) {
92
+ log.warn(
93
+ "sendTypingIndicator",
94
+ "callback is not a function - ignoring."
95
+ );
96
+ }
97
+ cb = () => { };
98
+ }
99
+
100
+ makeTypingIndicator(false, threadID, cb, isGroup);
101
+ };
102
+ };
103
+ };
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function(defaultFuncs, api, ctx) {
7
+ return function setMessageReaction(reaction, messageID, callback, forceCustomReaction) {
8
+ var resolveFunc = function(){};
9
+ var rejectFunc = function(){};
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err, friendList) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(friendList);
21
+ };
22
+ }
23
+
24
+ switch (reaction) {
25
+ case "\uD83D\uDE0D": //:heart_eyes:
26
+ case "\uD83D\uDE06": //:laughing:
27
+ case "\uD83D\uDE2E": //:open_mouth:
28
+ case "\uD83D\uDE22": //:cry:
29
+ case "\uD83D\uDE20": //:angry:
30
+ case "\uD83D\uDC4D": //:thumbsup:
31
+ case "\uD83D\uDC4E": //:thumbsdown:
32
+ case "\u2764": //:heart:
33
+ case "\uD83D\uDC97": //:glowingheart:
34
+ case "":
35
+ //valid
36
+ break;
37
+ case ":heart_eyes:":
38
+ case ":love:":
39
+ reaction = "\uD83D\uDE0D";
40
+ break;
41
+ case ":laughing:":
42
+ case ":haha:":
43
+ reaction = "\uD83D\uDE06";
44
+ break;
45
+ case ":open_mouth:":
46
+ case ":wow:":
47
+ reaction = "\uD83D\uDE2E";
48
+ break;
49
+ case ":cry:":
50
+ case ":sad:":
51
+ reaction = "\uD83D\uDE22";
52
+ break;
53
+ case ":angry:":
54
+ reaction = "\uD83D\uDE20";
55
+ break;
56
+ case ":thumbsup:":
57
+ case ":like:":
58
+ reaction = "\uD83D\uDC4D";
59
+ break;
60
+ case ":thumbsdown:":
61
+ case ":dislike:":
62
+ reaction = "\uD83D\uDC4E";
63
+ break;
64
+ case ":heart:":
65
+ reaction = "\u2764";
66
+ break;
67
+ case ":glowingheart:":
68
+ reaction = "\uD83D\uDC97";
69
+ break;
70
+ default:
71
+ if (forceCustomReaction) {
72
+ break;
73
+ }
74
+ return callback({ error: "Reaction is not a valid emoji." });
75
+ }
76
+
77
+ var variables = {
78
+ data: {
79
+ client_mutation_id: ctx.clientMutationId++,
80
+ actor_id: ctx.userID,
81
+ action: reaction == "" ? "REMOVE_REACTION" : "ADD_REACTION",
82
+ message_id: messageID,
83
+ reaction: reaction
84
+ }
85
+ };
86
+
87
+ var qs = {
88
+ doc_id: "1491398900900362",
89
+ variables: JSON.stringify(variables),
90
+ dpr: 1
91
+ };
92
+
93
+ defaultFuncs
94
+ .postFormData(
95
+ "https://www.facebook.com/webgraphql/mutation/",
96
+ ctx.jar,
97
+ {},
98
+ qs
99
+ )
100
+ .then(utils.parseAndCheckLogin(ctx.jar, defaultFuncs))
101
+ .then(function(resData) {
102
+ if (!resData) {
103
+ throw { error: "setReaction returned empty object." };
104
+ }
105
+ if (resData.error) {
106
+ throw resData;
107
+ }
108
+ callback(null);
109
+ })
110
+ .catch(function(err) {
111
+ log.error("setReaction", err);
112
+ return callback(err);
113
+ });
114
+
115
+ return returnPromise;
116
+ };
117
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function(defaultFuncs, api, ctx) {
7
+ return function unsendMessage(postID, type, callback) {
8
+ var resolveFunc = function(){};
9
+ var rejectFunc = function(){};
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err, friendList) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(friendList);
21
+ };
22
+ }
23
+
24
+ var map = {
25
+ like: 1,
26
+ heart: 2,
27
+ wow: 3,
28
+ haha: 4,
29
+ sad: 7,
30
+ angry: 8
31
+ };
32
+ if (typeof type != "number") {
33
+ type = map[type.toLocaleLowerCase()];
34
+ if (!type) {
35
+ type = 1;
36
+ }
37
+ }
38
+ var form = {
39
+ av: ctx.userID,
40
+ fb_api_caller_class: "RelayModern",
41
+ fb_api_req_friendly_name: "UFI2FeedbackReactMutation",
42
+ //This doc_id is valid as of January 17th, 2020
43
+ doc_id: "2580813318646067",
44
+ variables: JSON.stringify({
45
+ input: {
46
+ client_mutation_id: "7",
47
+ actor_id: ctx.userID,
48
+ feedback_reaction: type,
49
+
50
+ },
51
+ useDefaultActor: true
52
+ })
53
+ };
54
+
55
+ defaultFuncs
56
+ .post(
57
+ "https://www.facebook.com/api/graphql/",
58
+ ctx.jar,
59
+ form
60
+ )
61
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
62
+ .then(function(resData) {
63
+ if (resData.error) {
64
+ throw resData;
65
+ }
66
+
67
+ return callback();
68
+ })
69
+ .catch(function(err) {
70
+ log.error("setPostReaction", err);
71
+ return callback(err);
72
+ });
73
+
74
+ return returnPromise;
75
+ };
76
+ };