@vangbanlanhat/fca-unofficial 1.4.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 (115) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/workflows/nodejs.yml +26 -0
  3. package/.github/workflows/npmpublish.yml +30 -0
  4. package/.travis.yml +6 -0
  5. package/CHANGELOG.md +2 -0
  6. package/DOCS.md +1932 -0
  7. package/LICENSE-MIT +21 -0
  8. package/README.md +198 -0
  9. package/jest.config.js +10 -0
  10. package/package.json +86 -0
  11. package/pnpm-workspace.yaml +3 -0
  12. package/src/actions/addExternalModule.js +34 -0
  13. package/src/actions/addUserToGroup.js +113 -0
  14. package/src/actions/changeAdminStatus.js +79 -0
  15. package/src/actions/changeArchivedStatus.js +55 -0
  16. package/src/actions/changeBio.js +77 -0
  17. package/src/actions/changeBlockedStatus.js +47 -0
  18. package/src/actions/changeGroupImage.js +129 -0
  19. package/src/actions/changeNickname.js +59 -0
  20. package/src/actions/changeThreadColor.js +71 -0
  21. package/src/actions/changeThreadEmoji.js +55 -0
  22. package/src/actions/createNewGroup.js +86 -0
  23. package/src/actions/createPoll.js +71 -0
  24. package/src/actions/deleteMessage.js +56 -0
  25. package/src/actions/deleteThread.js +56 -0
  26. package/src/actions/editMessage.js +81 -0
  27. package/src/actions/forwardAttachment.js +60 -0
  28. package/src/actions/getAvatarUser.js +77 -0
  29. package/src/actions/getCurrentUserID.js +11 -0
  30. package/src/actions/getEmojiUrl.js +37 -0
  31. package/src/actions/getFriendsList.js +84 -0
  32. package/src/actions/getMessage.js +833 -0
  33. package/src/actions/getRegion.js +11 -0
  34. package/src/actions/getThreadHistory.js +702 -0
  35. package/src/actions/getThreadHistoryDeprecated.js +93 -0
  36. package/src/actions/getThreadInfo.js +265 -0
  37. package/src/actions/getThreadInfoDeprecated.js +80 -0
  38. package/src/actions/getThreadList.js +274 -0
  39. package/src/actions/getThreadListDeprecated.js +91 -0
  40. package/src/actions/getThreadPictures.js +79 -0
  41. package/src/actions/getUserID.js +66 -0
  42. package/src/actions/getUserInfo.js +92 -0
  43. package/src/actions/handleFriendRequest.js +61 -0
  44. package/src/actions/handleMessageRequest.js +65 -0
  45. package/src/actions/httpGet.js +70 -0
  46. package/src/actions/httpPost.js +70 -0
  47. package/src/actions/index.js +69 -0
  48. package/src/actions/listenMqtt.js +818 -0
  49. package/src/actions/logout.js +136 -0
  50. package/src/actions/markAsDelivered.js +58 -0
  51. package/src/actions/markAsRead.js +92 -0
  52. package/src/actions/markAsReadAll.js +50 -0
  53. package/src/actions/markAsSeen.js +59 -0
  54. package/src/actions/muteThread.js +52 -0
  55. package/src/actions/pinMessage.js +86 -0
  56. package/src/actions/refreshFb_dtsg.js +89 -0
  57. package/src/actions/removeUserFromGroup.js +79 -0
  58. package/src/actions/resolvePhotoUrl.js +45 -0
  59. package/src/actions/searchForThread.js +53 -0
  60. package/src/actions/searchStickers.js +53 -0
  61. package/src/actions/sendMessage.js +490 -0
  62. package/src/actions/sendMessageMqtt.js +235 -0
  63. package/src/actions/sendTypingIndicator.js +59 -0
  64. package/src/actions/setMessageReaction.js +140 -0
  65. package/src/actions/setMessageReactionMqtt.js +72 -0
  66. package/src/actions/setPostReaction.js +76 -0
  67. package/src/actions/setTitle.js +86 -0
  68. package/src/actions/stopListenMqtt.js +63 -0
  69. package/src/actions/threadColors.js +57 -0
  70. package/src/actions/unfriend.js +52 -0
  71. package/src/actions/unsendMessage.js +61 -0
  72. package/src/index.js +659 -0
  73. package/src/service/uploadAttachment.js +318 -0
  74. package/src/utils/base-parts/auth.js +286 -0
  75. package/src/utils/base-parts/formatters.js +751 -0
  76. package/src/utils/base-parts/identity.js +169 -0
  77. package/src/utils/base-parts/network.js +159 -0
  78. package/src/utils/base-parts/parsing.js +53 -0
  79. package/src/utils/base-parts/type.js +9 -0
  80. package/src/utils/base.js +18 -0
  81. package/src/utils/defaults.js +10 -0
  82. package/src/utils/format-attachments.js +7 -0
  83. package/src/utils/format-core.js +8 -0
  84. package/src/utils/format-events.js +11 -0
  85. package/src/utils/format-messages.js +10 -0
  86. package/src/utils/format-presence.js +9 -0
  87. package/src/utils/format-threads.js +8 -0
  88. package/src/utils/formatters.js +18 -0
  89. package/src/utils/identity.js +12 -0
  90. package/src/utils/index.js +15 -0
  91. package/src/utils/network.js +12 -0
  92. package/src/utils/parsing.js +11 -0
  93. package/src/utils.js +3 -0
  94. package/test/config.env.example +30 -0
  95. package/test/data/shareAttach.js +146 -0
  96. package/test/data/something.mov +0 -0
  97. package/test/data/test.png +0 -0
  98. package/test/data/test.txt +7 -0
  99. package/test/example-appstate.txt +11 -0
  100. package/test/integration/actions.appstate.integration.test.js +233 -0
  101. package/test/integration/api.integration.test.js +387 -0
  102. package/test/integration/env-test-config.js +46 -0
  103. package/test/integration/login.appstate.integration.test.js +47 -0
  104. package/test/integration/page.integration.test.js +139 -0
  105. package/test/jest.setup.js +54 -0
  106. package/test/unit/actions/actions.basic.test.js +116 -0
  107. package/test/unit/actions/actions.registry.test.js +36 -0
  108. package/test/unit/index/index.test.js +109 -0
  109. package/test/unit/utils/base-parts/auth.test.js +92 -0
  110. package/test/unit/utils/base-parts/formatters.test.js +53 -0
  111. package/test/unit/utils/base-parts/identity.test.js +43 -0
  112. package/test/unit/utils/base-parts/parsing.test.js +38 -0
  113. package/test/unit/utils/base-parts/type.test.js +23 -0
  114. package/test/unit/utils/base.test.js +35 -0
  115. package/vangbanlanhat-fca-unofficial-1.4.2.tgz +0 -0
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+ var createUploadAttachment = require("../service/uploadAttachment");
6
+
7
+ module.exports = function (defaultFuncs, _api, ctx) {
8
+ var mqttVariance = 0;
9
+
10
+ var uploadAttachment = createUploadAttachment(defaultFuncs, ctx, log);
11
+
12
+ function mqttEpochID() {
13
+ mqttVariance = (mqttVariance + 0.1) % 5;
14
+ return Math.floor(Date.now() * (4194304 + mqttVariance));
15
+ }
16
+
17
+ return function sendMessageMqtt(msg, threadID, callback, replyToMessage) {
18
+ if (!ctx.mqttClient || !ctx.mqttClient.connected) {
19
+ return callback({ error: "MQTT client is not connected. Call listenMqtt first." });
20
+ }
21
+
22
+ var emojiSizes = { small: 1, medium: 2, large: 3 };
23
+ var threadIDString = threadID.toString();
24
+ var timestamp = Date.now();
25
+ var epoch = timestamp << 22;
26
+ var otid = epoch + Math.floor(Math.random() * 4194304);
27
+
28
+ var form = {
29
+ app_id: "2220391788200892",
30
+ payload: {
31
+ tasks: [
32
+ {
33
+ label: "46",
34
+ payload: {
35
+ thread_id: threadIDString,
36
+ otid: otid.toString(),
37
+ source: 0,
38
+ send_type: 1,
39
+ sync_group: 1,
40
+ text: msg.body != null ? msg.body.toString() : "",
41
+ initiating_source: 1,
42
+ skip_url_preview_gen: 0
43
+ },
44
+ queue_name: threadIDString,
45
+ task_id: 0,
46
+ failure_count: null
47
+ },
48
+ {
49
+ label: "21",
50
+ payload: {
51
+ thread_id: threadIDString,
52
+ last_read_watermark_ts: Date.now(),
53
+ sync_group: 1
54
+ },
55
+ queue_name: threadIDString,
56
+ task_id: 1,
57
+ failure_count: null
58
+ }
59
+ ],
60
+ epoch_id: mqttEpochID(),
61
+ version_id: "6120284488008082",
62
+ data_trace_id: null
63
+ },
64
+ request_id: 1,
65
+ type: 3
66
+ };
67
+
68
+ if (msg.emoji) {
69
+ var emojiSize = msg.emojiSize || "small";
70
+ form.payload.tasks[0].payload.send_type = 1;
71
+ form.payload.tasks[0].payload.text = msg.emoji;
72
+ form.payload.tasks[0].payload.hot_emoji_size = !isNaN(emojiSize)
73
+ ? emojiSize
74
+ : emojiSizes[emojiSize];
75
+ }
76
+
77
+ if (msg.location) {
78
+ form.payload.tasks[0].payload.send_type = 1;
79
+ form.payload.tasks[0].payload.location_data = {
80
+ coordinates: {
81
+ latitude: msg.location.latitude,
82
+ longitude: msg.location.longitude
83
+ },
84
+ is_current_location: !!msg.location.current,
85
+ is_live_location: !!msg.location.live
86
+ };
87
+ }
88
+
89
+ if (msg.mentions && msg.body) {
90
+ var mentionIds = [];
91
+ var mentionOffsets = [];
92
+ var mentionLengths = [];
93
+ var mentionTypes = [];
94
+
95
+ for (var i = 0; i < msg.mentions.length; i++) {
96
+ var mention = msg.mentions[i];
97
+ var tag = mention.tag;
98
+ if (typeof tag !== "string") {
99
+ return callback({ error: "Mention tags must be strings." });
100
+ }
101
+
102
+ var offset = msg.body.indexOf(tag, mention.fromIndex || 0);
103
+ if (offset < 0) {
104
+ log.warn("sendMessage", 'Mention for "' + tag + '" not found in message string.');
105
+ }
106
+
107
+ mentionIds.push(mention.id || 0);
108
+ mentionOffsets.push(offset);
109
+ mentionLengths.push(tag.length);
110
+ mentionTypes.push("p");
111
+ }
112
+
113
+ form.payload.tasks[0].payload.send_type = 1;
114
+ form.payload.tasks[0].payload.mention_data = {
115
+ mention_ids: mentionIds.join(","),
116
+ mention_offsets: mentionOffsets.join(","),
117
+ mention_lengths: mentionLengths.join(","),
118
+ mention_types: mentionTypes.join(",")
119
+ };
120
+ }
121
+
122
+ if (msg.sticker) {
123
+ form.payload.tasks[0].payload.send_type = 2;
124
+ form.payload.tasks[0].payload.sticker_id = msg.sticker;
125
+ }
126
+
127
+ function publish() {
128
+ if (replyToMessage) {
129
+ form.payload.tasks[0].payload.reply_metadata = {
130
+ reply_source_id: replyToMessage,
131
+ reply_source_type: 1,
132
+ reply_type: 0
133
+ };
134
+ }
135
+
136
+ form.payload.tasks.forEach(function (task) {
137
+ task.payload = JSON.stringify(task.payload);
138
+ });
139
+ form.payload = JSON.stringify(form.payload);
140
+
141
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(form), {}, function (err, data) {
142
+ if (err) {
143
+ log.error("sendMessageMqtt", err);
144
+ return callback(err);
145
+ }
146
+ callback(null, data);
147
+ });
148
+ }
149
+
150
+ if (!msg.attachment) {
151
+ return publish();
152
+ }
153
+
154
+ var baseSendTask = form.payload.tasks[0];
155
+ var readTask = form.payload.tasks[1];
156
+ var hasText = !!(baseSendTask.payload.text && String(baseSendTask.payload.text).trim());
157
+
158
+ if (hasText) {
159
+ var attachmentTask = {
160
+ label: "46",
161
+ payload: {
162
+ thread_id: threadIDString,
163
+ otid: (otid + 1).toString(),
164
+ source: 0,
165
+ send_type: 3,
166
+ sync_group: 1,
167
+ text: null,
168
+ initiating_source: 1,
169
+ skip_url_preview_gen: 0,
170
+ attachment_fbids: []
171
+ },
172
+ queue_name: threadIDString,
173
+ task_id: 1,
174
+ failure_count: null
175
+ };
176
+
177
+ baseSendTask.payload.send_type = 1;
178
+ baseSendTask.task_id = 0;
179
+ readTask.task_id = 2;
180
+ form.payload.tasks = [baseSendTask, attachmentTask, readTask];
181
+ } else {
182
+ baseSendTask.payload.send_type = 3;
183
+ baseSendTask.payload.attachment_fbids = [];
184
+ if (!baseSendTask.payload.text) {
185
+ baseSendTask.payload.text = null;
186
+ }
187
+ }
188
+
189
+ if (utils.getType(msg.attachment) !== "Array") {
190
+ msg.attachment = [msg.attachment];
191
+ }
192
+
193
+ uploadAttachment(msg.attachment, function (err, files) {
194
+ if (err) {
195
+ return callback(err);
196
+ }
197
+
198
+ var attachmentPayload = hasText
199
+ ? form.payload.tasks[1].payload
200
+ : form.payload.tasks[0].payload;
201
+
202
+ files.forEach(function (file) {
203
+ if (!file || typeof file !== "object") {
204
+ return;
205
+ }
206
+
207
+ var type = ["image_id", "gif_id", "file_id", "video_id", "audio_id"].find(
208
+ function (candidate) {
209
+ return file[candidate] != null;
210
+ }
211
+ );
212
+
213
+ if (!type) {
214
+ var key = Object.keys(file);
215
+ if (!key.length) {
216
+ return;
217
+ }
218
+ type = key[0];
219
+ }
220
+
221
+ if (file[type] == null) {
222
+ return;
223
+ }
224
+
225
+ attachmentPayload.attachment_fbids.push(file[type]);
226
+ });
227
+
228
+ if (!attachmentPayload.attachment_fbids.length) {
229
+ return callback({ error: "Attachment upload failed: no attachment id returned." });
230
+ }
231
+
232
+ publish();
233
+ });
234
+ };
235
+ };
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ module.exports = function (_defaultFuncs, _api, ctx) {
4
+ function publishTypingPacket(wsContent) {
5
+ return new Promise(function (resolve, reject) {
6
+ ctx.mqttClient.publish(
7
+ "/ls_req",
8
+ JSON.stringify(wsContent),
9
+ {},
10
+ function (err, packet) {
11
+ if (err) return reject(err);
12
+ resolve(packet);
13
+ }
14
+ );
15
+ });
16
+ }
17
+
18
+ return async function sendTypingIndicatorMqtt(sendTyping, threadID, callback, isGroup) {
19
+ var done = typeof callback === "function" ? callback : function () {};
20
+
21
+ try {
22
+ if (!ctx.mqttClient || !ctx.mqttClient.connected) {
23
+ throw new Error("MQTT client is not connected. Call listenMqtt first.");
24
+ }
25
+
26
+ if (!threadID) {
27
+ throw new Error("sendTypingIndicatorMqtt requires threadID");
28
+ }
29
+
30
+ var isGroupThread =
31
+ typeof isGroup === "boolean"
32
+ ? isGroup
33
+ : String(threadID).length >= 16;
34
+
35
+ var wsContent = {
36
+ app_id: 2220391788200892,
37
+ payload: JSON.stringify({
38
+ label: 3,
39
+ payload: JSON.stringify({
40
+ thread_key: String(threadID),
41
+ is_group_thread: +isGroupThread,
42
+ is_typing: +!!sendTyping,
43
+ attribution: 0
44
+ }),
45
+ version: 5849951561777440
46
+ }),
47
+ request_id: 1,
48
+ type: 4
49
+ };
50
+
51
+ var packet = await publishTypingPacket(wsContent);
52
+ done(null, packet);
53
+ return packet;
54
+ } catch (err) {
55
+ done(err);
56
+ throw err;
57
+ }
58
+ };
59
+ };
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+
7
+ module.exports = function(defaultFuncs, api, ctx) {
8
+ return function setMessageReaction(reaction, messageID, callback, forceCustomReaction) {
9
+ var resolveFunc = function(){};
10
+ var rejectFunc = function(){};
11
+ var returnPromise = new Promise(function (resolve, reject) {
12
+ resolveFunc = resolve;
13
+ rejectFunc = reject;
14
+ });
15
+
16
+ var threadID = null;
17
+
18
+ if (utils.getType(callback) === "String" || utils.getType(callback) === "Number") {
19
+ threadID = callback.toString();
20
+ callback = null;
21
+ }
22
+
23
+ if (utils.getType(forceCustomReaction) === "String" || utils.getType(forceCustomReaction) === "Number") {
24
+ threadID = forceCustomReaction.toString();
25
+ forceCustomReaction = false;
26
+ }
27
+
28
+ if (utils.getType(forceCustomReaction) === "Object") {
29
+ threadID = forceCustomReaction.threadID || forceCustomReaction.threadId || threadID;
30
+ forceCustomReaction = !!forceCustomReaction.forceCustomReaction;
31
+ }
32
+
33
+ if (!callback) {
34
+ callback = function (err, friendList) {
35
+ if (err) {
36
+ return rejectFunc(err);
37
+ }
38
+ resolveFunc(friendList);
39
+ };
40
+ }
41
+
42
+ switch (reaction) {
43
+ case "\uD83D\uDE0D": //:heart_eyes:
44
+ case "\uD83D\uDE06": //:laughing:
45
+ case "\uD83D\uDE2E": //:open_mouth:
46
+ case "\uD83D\uDE22": //:cry:
47
+ case "\uD83D\uDE20": //:angry:
48
+ case "\uD83D\uDC4D": //:thumbsup:
49
+ case "\uD83D\uDC4E": //:thumbsdown:
50
+ case "\u2764": //:heart:
51
+ case "\uD83D\uDC97": //:glowingheart:
52
+ case "":
53
+ //valid
54
+ break;
55
+ case ":heart_eyes:":
56
+ case ":love:":
57
+ reaction = "\uD83D\uDE0D";
58
+ break;
59
+ case ":laughing:":
60
+ case ":haha:":
61
+ reaction = "\uD83D\uDE06";
62
+ break;
63
+ case ":open_mouth:":
64
+ case ":wow:":
65
+ reaction = "\uD83D\uDE2E";
66
+ break;
67
+ case ":cry:":
68
+ case ":sad:":
69
+ reaction = "\uD83D\uDE22";
70
+ break;
71
+ case ":angry:":
72
+ reaction = "\uD83D\uDE20";
73
+ break;
74
+ case ":thumbsup:":
75
+ case ":like:":
76
+ reaction = "\uD83D\uDC4D";
77
+ break;
78
+ case ":thumbsdown:":
79
+ case ":dislike:":
80
+ reaction = "\uD83D\uDC4E";
81
+ break;
82
+ case ":heart:":
83
+ reaction = "\u2764";
84
+ break;
85
+ case ":glowingheart:":
86
+ reaction = "\uD83D\uDC97";
87
+ break;
88
+ default:
89
+ if (forceCustomReaction) {
90
+ break;
91
+ }
92
+ return callback({ error: "Reaction is not a valid emoji." });
93
+ }
94
+
95
+ if (ctx.mqttClient && threadID && !ctx.globalOptions.pageID) {
96
+ api.setMessageReactionMqtt(reaction, messageID, threadID, callback);
97
+ return returnPromise;
98
+ }
99
+
100
+ var variables = {
101
+ data: {
102
+ client_mutation_id: ctx.clientMutationId++,
103
+ actor_id: ctx.userID,
104
+ action: reaction == "" ? "REMOVE_REACTION" : "ADD_REACTION",
105
+ message_id: messageID,
106
+ reaction: reaction
107
+ }
108
+ };
109
+
110
+ var qs = {
111
+ doc_id: "1491398900900362",
112
+ variables: JSON.stringify(variables),
113
+ dpr: 1
114
+ };
115
+
116
+ defaultFuncs
117
+ .postFormData(
118
+ "https://www.facebook.com/webgraphql/mutation/",
119
+ ctx.jar,
120
+ {},
121
+ qs
122
+ )
123
+ .then(utils.parseAndCheckLogin(ctx.jar, defaultFuncs))
124
+ .then(function(resData) {
125
+ if (!resData) {
126
+ throw { error: "setReaction returned empty object." };
127
+ }
128
+ if (resData.error) {
129
+ throw resData;
130
+ }
131
+ callback(null);
132
+ })
133
+ .catch(function(err) {
134
+ log.error("setReaction", err);
135
+ return callback(err);
136
+ });
137
+
138
+ return returnPromise;
139
+ };
140
+ };
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+
5
+ module.exports = function (_defaultFuncs, _api, ctx) {
6
+ return function setMessageReactionMqtt(reaction, messageID, threadID, callback) {
7
+ if (!ctx.mqttClient) {
8
+ return callback(new Error("Not connected to MQTT"));
9
+ }
10
+
11
+ var reqID = ctx.wsReqNumber + 1;
12
+ ctx.wsReqNumber += 1;
13
+ ctx.wsTaskNumber += 1;
14
+
15
+ var taskPayload = {
16
+ thread_key: threadID,
17
+ timestamp_ms: Date.now(),
18
+ message_id: messageID,
19
+ reaction: reaction,
20
+ actor_id: ctx.userID,
21
+ reaction_style: null,
22
+ sync_group: 1,
23
+ send_attribution: Math.random() < 0.5 ? 65537 : 524289
24
+ };
25
+
26
+ var task = {
27
+ failure_count: null,
28
+ label: "29",
29
+ payload: JSON.stringify(taskPayload),
30
+ queue_name: JSON.stringify(["reaction", messageID]),
31
+ task_id: ctx.wsTaskNumber
32
+ };
33
+
34
+ var content = {
35
+ app_id: "2220391788200892",
36
+ payload: JSON.stringify({
37
+ data_trace_id: null,
38
+ epoch_id: parseInt(utils.generateOfflineThreadingID(), 10),
39
+ tasks: [task],
40
+ version_id: "7158486590867448"
41
+ }),
42
+ request_id: ctx.wsReqNumber,
43
+ type: 3
44
+ };
45
+
46
+ var mqttClient = ctx.mqttClient;
47
+ var timeout = setTimeout(function () {
48
+ mqttClient.removeListener("message", handleRes);
49
+ callback(new Error("setMessageReactionMqtt response timeout"));
50
+ }, 10000);
51
+
52
+ function handleRes(topic, message) {
53
+ if (topic !== "/ls_resp") return;
54
+
55
+ var jsonMsg;
56
+ try {
57
+ jsonMsg = JSON.parse(message.toString());
58
+ } catch (_) {
59
+ return;
60
+ }
61
+
62
+ if (jsonMsg.request_id !== reqID) return;
63
+
64
+ clearTimeout(timeout);
65
+ mqttClient.removeListener("message", handleRes);
66
+ callback(null, jsonMsg);
67
+ }
68
+
69
+ mqttClient.on("message", handleRes);
70
+ mqttClient.publish("/ls_req", JSON.stringify(content), { qos: 1, retain: false });
71
+ };
72
+ };
@@ -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
+ };
@@ -0,0 +1,86 @@
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 setTitle(newTitle, threadID, callback) {
8
+ if (
9
+ !callback &&
10
+ (utils.getType(threadID) === "Function" ||
11
+ utils.getType(threadID) === "AsyncFunction")
12
+ ) {
13
+ throw { error: "please pass a threadID as a second argument." };
14
+ }
15
+
16
+ var resolveFunc = function(){};
17
+ var rejectFunc = function(){};
18
+ var returnPromise = new Promise(function (resolve, reject) {
19
+ resolveFunc = resolve;
20
+ rejectFunc = reject;
21
+ });
22
+
23
+ if (!callback) {
24
+ callback = function (err, friendList) {
25
+ if (err) {
26
+ return rejectFunc(err);
27
+ }
28
+ resolveFunc(friendList);
29
+ };
30
+ }
31
+
32
+ var messageAndOTID = utils.generateOfflineThreadingID();
33
+ var form = {
34
+ client: "mercury",
35
+ action_type: "ma-type:log-message",
36
+ author: "fbid:" + ctx.userID,
37
+ author_email: "",
38
+ coordinates: "",
39
+ timestamp: Date.now(),
40
+ timestamp_absolute: "Today",
41
+ timestamp_relative: utils.generateTimestampRelative(),
42
+ timestamp_time_passed: "0",
43
+ is_unread: false,
44
+ is_cleared: false,
45
+ is_forward: false,
46
+ is_filtered_content: false,
47
+ is_spoof_warning: false,
48
+ source: "source:chat:web",
49
+ "source_tags[0]": "source:chat",
50
+ status: "0",
51
+ offline_threading_id: messageAndOTID,
52
+ message_id: messageAndOTID,
53
+ threading_id: utils.generateThreadingID(ctx.clientID),
54
+ manual_retry_cnt: "0",
55
+ thread_fbid: threadID,
56
+ thread_name: newTitle,
57
+ thread_id: threadID,
58
+ log_message_type: "log:thread-name"
59
+ };
60
+
61
+ defaultFuncs
62
+ .post("https://www.facebook.com/messaging/set_thread_name/", ctx.jar, form)
63
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
64
+ .then(function(resData) {
65
+ if (resData.error && resData.error === 1545012) {
66
+ throw { error: "Cannot change chat title: Not member of chat." };
67
+ }
68
+
69
+ if (resData.error && resData.error === 1545003) {
70
+ throw { error: "Cannot set title of single-user chat." };
71
+ }
72
+
73
+ if (resData.error) {
74
+ throw resData;
75
+ }
76
+
77
+ return callback();
78
+ })
79
+ .catch(function(err) {
80
+ log.error("setTitle", err);
81
+ return callback(err);
82
+ });
83
+
84
+ return returnPromise;
85
+ };
86
+ };