@cexy/hoonfca 1.0.0 → 1.0.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 (98) hide show
  1. package/.travis.yml +6 -0
  2. package/LICENSE-MIT +21 -0
  3. package/index.d.ts +620 -0
  4. package/index.js +745 -433
  5. package/package.json +45 -6
  6. package/src/addExternalModule.js +14 -16
  7. package/src/addUserToGroup.js +45 -30
  8. package/src/changeAdminStatus.js +39 -42
  9. package/src/changeApprovalMode.js +79 -0
  10. package/src/changeArchivedStatus.js +19 -15
  11. package/src/changeBio.js +18 -16
  12. package/src/changeBlockedStatus.js +14 -12
  13. package/src/changeBlockedStatusMqtt.js +38 -17
  14. package/src/changeGroupImage.js +100 -77
  15. package/src/changeNickname.js +12 -11
  16. package/src/changeThreadColor.js +25 -16
  17. package/src/changeThreadEmoji.js +11 -10
  18. package/src/createNewGroup.js +21 -14
  19. package/src/createPoll.js +87 -21
  20. package/src/deleteMessage.js +18 -17
  21. package/src/deleteThread.js +18 -17
  22. package/src/editMessage.js +28 -31
  23. package/src/forwardAttachment.js +22 -19
  24. package/src/forwardMessage.js +63 -0
  25. package/src/getCurrentUserID.js +4 -2
  26. package/src/getEmojiUrl.js +20 -9
  27. package/src/getFriendsList.js +21 -18
  28. package/src/getGroupsList.js +83 -0
  29. package/src/getMarketplace.js +84 -0
  30. package/src/getNotifications.js +86 -0
  31. package/src/getPagesList.js +83 -0
  32. package/src/getStories.js +88 -0
  33. package/src/getThreadHistory.js +277 -126
  34. package/src/getThreadInfo.js +143 -115
  35. package/src/getThreadList.js +216 -143
  36. package/src/getThreadPictures.js +26 -32
  37. package/src/getUserID.js +13 -14
  38. package/src/getUserInfo.js +107 -68
  39. package/src/handleFriendRequest.js +16 -15
  40. package/src/handleMessageRequest.js +15 -15
  41. package/src/httpGet.js +36 -31
  42. package/src/httpPost.js +36 -31
  43. package/src/listenMqtt.js +705 -370
  44. package/src/logout.js +26 -28
  45. package/src/markAsDelivered.js +22 -17
  46. package/src/markAsRead.js +63 -49
  47. package/src/markAsReadAll.js +17 -13
  48. package/src/markAsSeen.js +23 -19
  49. package/src/muteThread.js +17 -14
  50. package/src/pinMessage.js +23 -22
  51. package/src/removeUserFromGroup.js +42 -22
  52. package/src/resolvePhotoUrl.js +15 -17
  53. package/src/searchForThread.js +18 -20
  54. package/src/searchUsers.js +89 -0
  55. package/src/sendComment.js +161 -0
  56. package/src/sendMessage.js +65 -52
  57. package/src/sendTypingIndicator.js +173 -48
  58. package/src/setBio.js +86 -0
  59. package/src/setMessageReaction.js +76 -16
  60. package/src/setPostReaction.js +29 -61
  61. package/src/setTheme.js +313 -0
  62. package/src/setTitle.js +27 -37
  63. package/src/shareContact.js +34 -82
  64. package/src/shareLink.js +56 -99
  65. package/src/threadColors.js +35 -97
  66. package/src/unfriend.js +15 -20
  67. package/src/unsendMessage.js +71 -18
  68. package/utils.js +1000 -472
  69. package/README.md +0 -83
  70. package/replit.nix +0 -3
  71. package/src/changeAvatar.js +0 -89
  72. package/src/changeCover.js +0 -92
  73. package/src/changeName.js +0 -106
  74. package/src/changeUsername.js +0 -80
  75. package/src/createCommentPost.js +0 -196
  76. package/src/createPost.js +0 -285
  77. package/src/data/getThreadInfo.json +0 -1
  78. package/src/follow.js +0 -71
  79. package/src/getAccess.js +0 -130
  80. package/src/getAvatarUser.js +0 -88
  81. package/src/getBotInitialData.js +0 -59
  82. package/src/getCtx.js +0 -5
  83. package/src/getMessage.js +0 -827
  84. package/src/getOptions.js +0 -5
  85. package/src/getRegion.js +0 -7
  86. package/src/getThreadHistoryDeprecated.js +0 -95
  87. package/src/getThreadInfoDeprecated.js +0 -77
  88. package/src/getThreadListDeprecated.js +0 -86
  89. package/src/httpPostFormData.js +0 -58
  90. package/src/listenNotification.js +0 -96
  91. package/src/refreshFb_dtsg.js +0 -75
  92. package/src/searchStickers.js +0 -59
  93. package/src/sendMessageMqtt.js +0 -326
  94. package/src/setMessageReactionMqtt.js +0 -74
  95. package/src/setProfileGuard.js +0 -66
  96. package/src/setStoryReaction.js +0 -97
  97. package/src/stopListenMqtt.js +0 -47
  98. package/src/uploadAttachment.js +0 -98
@@ -1,326 +0,0 @@
1
- "use strict";
2
-
3
- var utils = require("../utils");
4
-
5
- module.exports = function (defaultFuncs, api, ctx) {
6
- function uploadAttachment(attachments, callback) {
7
- callback = callback || function () {};
8
- var uploads = [];
9
-
10
- // create an array of promises
11
- for (var i = 0; i < attachments.length; i++) {
12
- if (!utils.isReadableStream(attachments[i])) {
13
- throw {
14
- error:
15
- "Attachment should be a readable stream and not " +
16
- utils.getType(attachments[i]) +
17
- ".",
18
- };
19
- }
20
-
21
- var form = {
22
- upload_1024: attachments[i],
23
- voice_clip: "true",
24
- };
25
-
26
- uploads.push(
27
- defaultFuncs
28
- .postFormData(
29
- "https://upload.facebook.com/ajax/mercury/upload.php",
30
- ctx.jar,
31
- form,
32
- {},
33
- )
34
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
35
- .then(function (resData) {
36
- if (resData.error) {
37
- throw resData;
38
- }
39
-
40
- // We have to return the data unformatted unless we want to change it
41
- // back in sendMessage.
42
- return resData.payload.metadata[0];
43
- }),
44
- );
45
- }
46
-
47
- // resolve all promises
48
- Promise.all(uploads)
49
- .then(function (resData) {
50
- callback(null, resData);
51
- })
52
- .catch(function (err) {
53
- utils.error("uploadAttachment", err);
54
- return callback(err);
55
- });
56
- }
57
-
58
- let variance = 0;
59
- const epoch_id = () =>
60
- Math.floor(Date.now() * (4194304 + (variance = (variance + 0.1) % 5)));
61
- const emojiSizes = {
62
- small: 1,
63
- medium: 2,
64
- large: 3,
65
- };
66
-
67
- function handleEmoji(msg, form, callback, cb) {
68
- if (msg.emojiSize != null && msg.emoji == null) {
69
- return callback({ error: "emoji property is empty" });
70
- }
71
- if (msg.emoji) {
72
- if (!msg.emojiSize) {
73
- msg.emojiSize = "small";
74
- }
75
- if (
76
- msg.emojiSize !== "small" &&
77
- msg.emojiSize !== "medium" &&
78
- msg.emojiSize !== "large" &&
79
- (isNaN(msg.emojiSize) || msg.emojiSize < 1 || msg.emojiSize > 3)
80
- ) {
81
- return callback({ error: "emojiSize property is invalid" });
82
- }
83
-
84
- form.payload.tasks[0].payload.send_type = 1;
85
- form.payload.tasks[0].payload.text = msg.emoji;
86
- form.payload.tasks[0].payload.hot_emoji_size = !isNaN(msg.emojiSize)
87
- ? Number(msg.emojiSize)
88
- : emojiSizes[msg.emojiSize];
89
- }
90
- cb();
91
- }
92
-
93
- function handleSticker(msg, form, callback, cb) {
94
- if (msg.sticker) {
95
- form.payload.tasks[0].payload.send_type = 2;
96
- form.payload.tasks[0].payload.sticker_id = msg.sticker;
97
- }
98
- cb();
99
- }
100
-
101
- function handleAttachment(msg, form, callback, cb) {
102
- if (msg.attachment) {
103
- form.payload.tasks[0].payload.send_type = 3;
104
- form.payload.tasks[0].payload.attachment_fbids = [];
105
- if (form.payload.tasks[0].payload.text == "") {
106
- form.payload.tasks[0].payload.text = null;
107
- }
108
- if (utils.getType(msg.attachment) !== "Array") {
109
- msg.attachment = [msg.attachment];
110
- }
111
-
112
- uploadAttachment(msg.attachment, function (err, files) {
113
- if (err) {
114
- return callback(err);
115
- }
116
-
117
- files.forEach(function (file) {
118
- var key = Object.keys(file);
119
- var type = key[0]; // image_id, file_id, etc
120
- form.payload.tasks[0].payload.attachment_fbids.push(file[type]); // push the id
121
- });
122
- cb();
123
- });
124
- } else {
125
- cb();
126
- }
127
- }
128
-
129
- function handleMention(msg, form, callback, cb) {
130
- if (msg.mentions) {
131
- form.payload.tasks[0].payload.send_type = 1;
132
-
133
- const arrayIds = [];
134
- const arrayOffsets = [];
135
- const arrayLengths = [];
136
- const mention_types = [];
137
- const bodyText = msg.body ? msg.body.toString() : "";
138
-
139
- for (let i = 0; i < msg.mentions.length; i++) {
140
- const mention = msg.mentions[i];
141
-
142
- const tag = mention.tag;
143
- if (typeof tag !== "string") {
144
- return callback({ error: "Mention tags must be strings." });
145
- }
146
-
147
- const offset = bodyText.indexOf(tag, mention.fromIndex || 0);
148
-
149
- if (offset < 0) {
150
- utils.warn(
151
- "handleMention",
152
- 'Mention for "' + tag + '" not found in message string.',
153
- );
154
- }
155
-
156
- if (mention.id == null) {
157
- utils.warn("handleMention", "Mention id should be non-null.");
158
- }
159
-
160
- const id = mention.id || 0;
161
- arrayIds.push(id);
162
- arrayOffsets.push(offset);
163
- arrayLengths.push(tag.length);
164
- mention_types.push("p");
165
- }
166
-
167
- form.payload.tasks[0].payload.mention_data = {
168
- mention_ids: arrayIds.join(","),
169
- mention_offsets: arrayOffsets.join(","),
170
- mention_lengths: arrayLengths.join(","),
171
- mention_types: mention_types.join(","),
172
- };
173
- }
174
- cb();
175
- }
176
-
177
- function handleLocation(msg, form, callback, cb) {
178
- if (msg.location) {
179
- if (msg.location.latitude == null || msg.location.longitude == null) {
180
- return callback({
181
- error: "location property needs both latitude and longitude",
182
- });
183
- }
184
-
185
- form.payload.tasks[0].payload.send_type = 1;
186
- form.payload.tasks[0].payload.location_data = {
187
- coordinates: {
188
- latitude: msg.location.latitude,
189
- longitude: msg.location.longitude,
190
- },
191
- is_current_location: !!msg.location.current,
192
- is_live_location: !!msg.location.live,
193
- };
194
- }
195
-
196
- cb();
197
- }
198
-
199
- function send(form, threadID, callback, replyToMessage) {
200
- if (replyToMessage) {
201
- form.payload.tasks[0].payload.reply_metadata = {
202
- reply_source_id: replyToMessage.toString(),
203
- reply_source_type: 1,
204
- reply_type: 0,
205
- };
206
- }
207
- const mqttClient = ctx.mqttClient;
208
- if (!mqttClient) {
209
- return callback({ error: "MQTT Client is not initialized." });
210
- }
211
-
212
- form.payload.tasks.forEach((task) => {
213
- task.payload = JSON.stringify(task.payload);
214
- });
215
- form.payload = JSON.stringify(form.payload);
216
-
217
- return mqttClient.publish(
218
- "/ls_req",
219
- JSON.stringify(form),
220
- { qos: 1, retain: false },
221
- function (err, data) {
222
- if (err) {
223
- utils.error("Error publishing message: ", err);
224
- return callback(err);
225
- } else {
226
- return callback(null, data);
227
- }
228
- },
229
- );
230
- }
231
-
232
- return function sendMessageMqtt(msg, threadID, callback, replyToMessage) {
233
- if (
234
- !callback &&
235
- (utils.getType(threadID) === "Function" ||
236
- utils.getType(threadID) === "AsyncFunction")
237
- ) {
238
- return threadID({ error: "Pass a threadID as a second argument." });
239
- }
240
- if (!replyToMessage && utils.getType(callback) === "String") {
241
- replyToMessage = callback;
242
- callback = function () {};
243
- }
244
-
245
- if (!callback) {
246
- callback = function (err, data) {};
247
- }
248
-
249
- var msgType = utils.getType(msg);
250
- var threadIDType = utils.getType(threadID);
251
-
252
- if (msgType !== "String" && msgType !== "Object") {
253
- return callback({
254
- error:
255
- "Message should be of type string or object and not " + msgType + ".",
256
- });
257
- }
258
-
259
- if (!threadID) {
260
- return callback({ error: "ThreadID is required." });
261
- }
262
-
263
- if (msgType === "String") {
264
- msg = { body: msg };
265
- }
266
-
267
- const timestamp = Date.now();
268
- const epoch = timestamp << 22;
269
- const otid = epoch + Math.floor(Math.random() * 4194304);
270
-
271
- const form = {
272
- app_id: "2220391788200892",
273
- payload: {
274
- tasks: [
275
- {
276
- label: "46",
277
- payload: {
278
- thread_id: threadID.toString(),
279
- otid: otid.toString(),
280
- source: 0,
281
- send_type: 1,
282
- sync_group: 1,
283
- text:
284
- msg.body != null && msg.body !== undefined
285
- ? msg.body.toString()
286
- : "",
287
- initiating_source: 1,
288
- skip_url_preview_gen: 0,
289
- },
290
- queue_name: threadID.toString(),
291
- task_id: 0,
292
- failure_count: null,
293
- },
294
- {
295
- label: "21",
296
- payload: {
297
- thread_id: threadID.toString(),
298
- last_read_watermark_ts: Date.now(),
299
- sync_group: 1,
300
- },
301
- queue_name: threadID.toString(),
302
- task_id: 1,
303
- failure_count: null,
304
- },
305
- ],
306
- epoch_id: epoch_id(),
307
- version_id: "6120284488008082",
308
- data_trace_id: null,
309
- },
310
- request_id: 1,
311
- type: 3,
312
- };
313
-
314
- handleEmoji(msg, form, callback, function () {
315
- handleLocation(msg, form, callback, function () {
316
- handleMention(msg, form, callback, function () {
317
- handleSticker(msg, form, callback, function () {
318
- handleAttachment(msg, form, callback, function () {
319
- send(form, threadID, callback, replyToMessage);
320
- });
321
- });
322
- });
323
- });
324
- });
325
- };
326
- };
@@ -1,74 +0,0 @@
1
- 'use strict';
2
-
3
- const utils = require('../utils');
4
-
5
- module.exports = function (defaultFuncs, api, ctx) {
6
- return function setMessageReactionMqtt(reaction, messageID, threadID, callback) {
7
- // safe callback check
8
- if (typeof callback !== 'function') {
9
- callback = function () {};
10
- }
11
-
12
- if (!ctx.mqttClient) {
13
- return callback({ error: 'Not connected to MQTT' });
14
- }
15
-
16
- if (!messageID || !threadID) {
17
- return callback({ error: 'messageID and threadID are required.' });
18
- }
19
-
20
- ctx.wsReqNumber += 1;
21
- ctx.wsTaskNumber += 1;
22
-
23
- const taskPayload = {
24
- thread_key: threadID.toString(),
25
- timestamp_ms: Date.now(),
26
- message_id: messageID.toString(),
27
- reaction: reaction || "", // reaction খালি হলে রিমুভ হবে
28
- actor_id: ctx.userID.toString(),
29
- reaction_style: null,
30
- sync_group: 1,
31
- send_attribution: Math.random() < 0.5 ? 65537 : 524289
32
- };
33
-
34
- const task = {
35
- failure_count: null,
36
- label: '29',
37
- payload: JSON.stringify(taskPayload),
38
- queue_name: JSON.stringify(['reaction', messageID.toString()]),
39
- task_id: ctx.wsTaskNumber,
40
- };
41
-
42
- const content = {
43
- app_id: '2220391788200892',
44
- payload: JSON.stringify({
45
- data_trace_id: null,
46
- epoch_id: parseInt(utils.generateOfflineThreadingID()),
47
- tasks: [task],
48
- version_id: '7158486590867448',
49
- }),
50
- request_id: ctx.wsReqNumber,
51
- type: 3,
52
- };
53
-
54
- if (ctx.reqCallbacks) {
55
- ctx.reqCallbacks[ctx.wsReqNumber] = callback;
56
- }
57
-
58
- ctx.mqttClient.publish(
59
- '/ls_req',
60
- JSON.stringify(content),
61
- { qos: 1, retain: false },
62
- function (err, data) {
63
- if (err) {
64
- utils.error("setMessageReactionMqtt", err);
65
- return callback(err);
66
- }
67
- // যদি reqCallbacks রেজিস্টার্ড না থাকে, তবে পাবলিশের সাথে সাথে কলব্যাক ফায়ার করবে
68
- if (!ctx.reqCallbacks) {
69
- callback(null, data);
70
- }
71
- }
72
- );
73
- };
74
- };
@@ -1,66 +0,0 @@
1
- "use strict";
2
-
3
- const utils = require("../utils");
4
-
5
- module.exports = (defaultFuncs, api, ctx) => {
6
- return (guard, callback) => {
7
- let resolveFunc = function () {};
8
- let rejectFunc = function () {};
9
- const returnPromise = new Promise(function (resolve, reject) {
10
- resolveFunc = resolve;
11
- rejectFunc = reject;
12
- });
13
-
14
- if (!callback) {
15
- callback = function (err, data) {
16
- if (err) {
17
- return rejectFunc(err);
18
- }
19
- resolveFunc(data);
20
- };
21
- }
22
-
23
- if (utils.getType(guard) !== "Boolean") {
24
- return callback({
25
- error: "Please pass a boolean as a second argument.",
26
- });
27
- }
28
-
29
- const uid = ctx.userID;
30
- const form = {
31
- av: uid,
32
- variables: JSON.stringify({
33
- input: {
34
- is_shielded: guard ? true : false,
35
- actor_id: uid,
36
- client_mutation_id: "1"
37
- },
38
- scale: 1
39
- }),
40
- doc_id: "1477043292367183",
41
- fb_api_req_friendly_name: "IsShieldedSetMutation",
42
- fb_api_caller_class: "IsShieldedSetMutation"
43
- };
44
-
45
- defaultFuncs
46
- .post("https://www.facebook.com/api/graphql", ctx.jar, form)
47
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
48
- .then(function(resData) {
49
- if (!resData) {
50
- throw { error: "setProfileGuard returned empty response." };
51
- }
52
- if (resData.err || resData.errors || resData.error) {
53
- throw {
54
- error: resData.err || resData.errors || resData.error
55
- };
56
- }
57
- return callback(null, resData);
58
- })
59
- .catch(err => {
60
- utils.error("setProfileGuard", err);
61
- return callback(err);
62
- });
63
-
64
- return returnPromise;
65
- };
66
- };
@@ -1,97 +0,0 @@
1
- 'use strict';
2
-
3
- const utils = require('../utils.js');
4
-
5
- module.exports = function(defaultFuncs, api, ctx) {
6
- return function setStoryReaction(storyID, react, callback) {
7
- var cb;
8
- var returnPromise = new Promise(function(resolve, reject) {
9
- cb = error => error ? reject(error) : resolve();
10
- });
11
-
12
- if (typeof react == 'function') {
13
- callback = react;
14
- react = 1;
15
- }
16
- if (typeof callback == 'function') {
17
- cb = callback;
18
- }
19
-
20
- if (!storyID) {
21
- return cb({ error: 'setStoryReaction: storyID is required.' });
22
- }
23
-
24
- // সাপোর্ট করা রিঅ্যাকশন ও তাদের টেক্সট ফরম্যাট ম্যাপিং
25
- var map = {
26
- 1: '👍',
27
- 2: '❤️',
28
- 3: '🤗',
29
- 4: '😆',
30
- 5: '😮',
31
- 6: '😢',
32
- 7: '😡'
33
- };
34
-
35
- var aliasMap = {
36
- 'like': 1, 'thumbsup': 1, '👍': 1,
37
- 'heart': 2, 'love': 2, '❤️': 2,
38
- 'care': 3, 'hug': 3, '🤗': 3,
39
- 'haha': 4, 'laugh': 4, '😆': 4,
40
- 'wow': 5, 'shock': 5, '😮': 5,
41
- 'sad': 6, 'cry': 6, '😢': 6,
42
- 'angry': 7, 'rage': 7, '😡': 7
43
- };
44
-
45
- // রিঅ্যাকশন ইনপুট পার্স করা
46
- var targetReact = 1;
47
- if (react !== undefined && react !== null) {
48
- var reactStr = String(react).toLowerCase().trim();
49
- if (aliasMap[reactStr] !== undefined) {
50
- targetReact = aliasMap[reactStr];
51
- } else {
52
- var reactNum = Number(react);
53
- if (!isNaN(reactNum) && map[reactNum] !== undefined) {
54
- targetReact = reactNum;
55
- }
56
- }
57
- }
58
-
59
- var form = {
60
- fb_api_req_friendly_name: 'useStoriesSendReplyMutation',
61
- variables: JSON.stringify({
62
- input: {
63
- attribution_id_v2: `StoriesCometSuspenseRoot.react,comet.stories.viewer,unexpected,${Date.now()},538296,,;CometHomeRoot.react,comet.home,via_cold_start,${Date.now()},850302,4748854339,`,
64
- lightweight_reaction_actions: {
65
- offsets: [0],
66
- reaction: map[targetReact]
67
- },
68
- message: map[targetReact],
69
- story_id: storyID.toString(),
70
- story_reply_type: "LIGHT_WEIGHT",
71
- actor_id: ctx.userID,
72
- client_mutation_id: String(parseInt(Math.random() * 16))
73
- }
74
- }),
75
- doc_id: '4826141330837571'
76
- };
77
-
78
- defaultFuncs
79
- .post('https://www.facebook.com/api/graphql/', ctx.jar, form)
80
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
81
- .then(function(res) {
82
- if (!res) {
83
- throw { error: "setStoryReaction returned empty response." };
84
- }
85
- if (res.errors) {
86
- throw res;
87
- }
88
- return cb();
89
- })
90
- .catch(function(err) {
91
- utils.error('setStoryReaction', err);
92
- return cb(err);
93
- });
94
-
95
- return returnPromise;
96
- }
97
- }
@@ -1,47 +0,0 @@
1
- "use strict";
2
-
3
- var utils = require("../utils");
4
-
5
- module.exports = function (defaultFuncs, api, ctx) {
6
- return function stopListenMqtt(callback) {
7
- var resolveFunc = function () {};
8
- var rejectFunc = function () {};
9
- const returnPromise = new Promise(function (resolve, reject) {
10
- resolveFunc = resolve;
11
- rejectFunc = reject;
12
- });
13
-
14
- if (!callback) {
15
- callback = function (err, data) {
16
- if (err) {
17
- return rejectFunc(err);
18
- }
19
- resolveFunc(data);
20
- };
21
- }
22
-
23
- if (!ctx.mqttClient) {
24
- return callback(new Error("Not connected to MQTT"));
25
- }
26
-
27
- utils.log("stopListenMqtt", "Stopping...");
28
-
29
- try {
30
- ctx.mqttClient.unsubscribe("/webrtc");
31
- ctx.mqttClient.unsubscribe("/rtc_multi");
32
- ctx.mqttClient.unsubscribe("/onevc");
33
- ctx.mqttClient.publish("/browser_close", "{}");
34
-
35
- ctx.mqttClient.end(false, function (...data) {
36
- utils.log("stopListenMqtt", "Stopped");
37
- ctx.mqttClient = null;
38
- return callback(null, data);
39
- });
40
- } catch (err) {
41
- utils.error("stopListenMqtt", err);
42
- return callback(err);
43
- }
44
-
45
- return returnPromise;
46
- };
47
- };
@@ -1,98 +0,0 @@
1
- "use strict";
2
-
3
- const utils = require("../utils");
4
- // @NethWs3Dev
5
-
6
- module.exports = function (defaultFuncs, api, ctx) {
7
- function upload(attachments, callback) {
8
- callback = callback || function () {};
9
- const uploads = [];
10
-
11
- // create an array of promises
12
- for (let i = 0; i < attachments.length; i++) {
13
- if (!utils.isReadableStream(attachments[i])) {
14
- // Use a standard microtask delay or immediate callback instead of throwing synchronously
15
- const errorMsg = "Attachment should be a readable stream and not " + utils.getType(attachments[i]) + ".";
16
- return callback({ error: errorMsg });
17
- }
18
-
19
- const form = {
20
- upload_1024: attachments[i],
21
- voice_clip: "true",
22
- };
23
-
24
- uploads.push(
25
- defaultFuncs
26
- .postFormData(
27
- "https://upload.facebook.com/ajax/mercury/upload.php",
28
- ctx.jar,
29
- form,
30
- {},
31
- )
32
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
33
- .then(function (resData) {
34
- if (!resData) {
35
- throw { error: "Upload returned empty response." };
36
- }
37
- if (resData.error) {
38
- throw resData;
39
- }
40
-
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
- Promise.all(uploads)
50
- .then(function (resData) {
51
- callback(null, resData);
52
- })
53
- .catch(function (err) {
54
- utils.error("uploadAttachment", err);
55
- return callback(err);
56
- });
57
- }
58
-
59
- return function uploadAttachment(attachments, callback) {
60
- let resolveFunc = function () {};
61
- let rejectFunc = function () {};
62
- const returnPromise = new Promise(function (resolve, reject) {
63
- resolveFunc = resolve;
64
- rejectFunc = reject;
65
- });
66
-
67
- if (!callback) {
68
- callback = function (err, info) {
69
- if (err) {
70
- return rejectFunc(err);
71
- }
72
- resolveFunc(info);
73
- };
74
- }
75
-
76
- // safe input checking
77
- const isStream = utils.isReadableStream(attachments);
78
- const isArray = utils.getType(attachments) === "Array";
79
-
80
- if (!attachments || (!isStream && !isArray) || (isArray && attachments.length === 0)) {
81
- return callback({ error: "Please pass an attachment or an array of attachments." });
82
- }
83
-
84
- let normalizedAttachments = attachments;
85
- if (!isArray) {
86
- normalizedAttachments = [attachments];
87
- }
88
-
89
- upload(normalizedAttachments, (err, info) => {
90
- if (err) {
91
- return callback(err);
92
- }
93
- callback(null, info);
94
- });
95
-
96
- return returnPromise;
97
- };
98
- };