alicezetion 1.9.1 → 1.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. package/index.js +1 -1
  2. package/package.json +1 -1
  3. package/src/addExternalModule.js +19 -0
  4. package/src/addUserToGroup.js +113 -0
  5. package/src/changeAdminStatus.js +79 -0
  6. package/src/changeArchivedStatus.js +55 -0
  7. package/{leiamnash → src}/changeAvatar.js +2 -3
  8. package/src/changeBio.js +77 -0
  9. package/src/changeBlockedStatus.js +47 -0
  10. package/src/changeGroupImage.js +132 -0
  11. package/src/changeNickname.js +59 -0
  12. package/src/changeThreadColor.js +65 -0
  13. package/src/changeThreadEmoji.js +55 -0
  14. package/{leiamnash → src}/chat.js +29 -4
  15. package/src/createNewGroup.js +86 -0
  16. package/src/createPoll.js +71 -0
  17. package/src/deleteMessage.js +56 -0
  18. package/src/deleteThread.js +56 -0
  19. package/src/edit.js +66 -0
  20. package/src/forwardAttachment.js +60 -0
  21. package/src/getCurrentUserID.js +7 -0
  22. package/src/getEmojiUrl.js +29 -0
  23. package/src/getFriendsList.js +83 -0
  24. package/src/getThreadHistory.js +666 -0
  25. package/src/getThreadInfo.js +232 -0
  26. package/src/getThreadList.js +241 -0
  27. package/src/getThreadPictures.js +79 -0
  28. package/src/getUserID.js +66 -0
  29. package/src/getUserInfo.js +74 -0
  30. package/src/handleFriendRequest.js +61 -0
  31. package/src/handleMessageRequest.js +65 -0
  32. package/src/httpGet.js +57 -0
  33. package/src/httpPost.js +57 -0
  34. package/src/httpPostFormData.js +63 -0
  35. package/src/listenMqtt.js +853 -0
  36. package/src/logout.js +75 -0
  37. package/src/markAsDelivered.js +58 -0
  38. package/src/markAsRead.js +80 -0
  39. package/src/markAsReadAll.js +50 -0
  40. package/src/markAsSeen.js +59 -0
  41. package/src/muteThread.js +52 -0
  42. package/src/react.js +109 -0
  43. package/{leiamnash → src}/refreshFb_dtsg.js +1 -1
  44. package/src/removeUserFromGroup.js +79 -0
  45. package/src/resolvePhotoUrl.js +45 -0
  46. package/src/searchForThread.js +53 -0
  47. package/src/seen.js +50 -0
  48. package/src/sendMessage.js +477 -0
  49. package/src/sendTypingIndicator.js +103 -0
  50. package/src/setMessageReaction.js +121 -0
  51. package/src/setPostReaction.js +109 -0
  52. package/src/setTitle.js +86 -0
  53. package/src/threadColors.js +131 -0
  54. package/src/unfriend.js +52 -0
  55. package/src/unsendMessage.js +49 -0
  56. package/{leiamnash → src}/uploadAttachment.js +1 -2
  57. package/leiamnash/addExternalModule.js +0 -15
  58. package/leiamnash/addUserToGroup.js +0 -77
  59. package/leiamnash/changeAdminStatus.js +0 -47
  60. package/leiamnash/changeArchivedStatus.js +0 -41
  61. package/leiamnash/changeBio.js +0 -64
  62. package/leiamnash/changeBlockedStatus.js +0 -36
  63. package/leiamnash/changeGroupImage.js +0 -105
  64. package/leiamnash/changeNickname.js +0 -43
  65. package/leiamnash/changeThreadColor.js +0 -61
  66. package/leiamnash/changeThreadEmoji.js +0 -41
  67. package/leiamnash/createNewGroup.js +0 -70
  68. package/leiamnash/createPoll.js +0 -59
  69. package/leiamnash/deleteMessage.js +0 -44
  70. package/leiamnash/deleteThread.js +0 -42
  71. package/leiamnash/edit.js +0 -59
  72. package/leiamnash/forwardAttachment.js +0 -47
  73. package/leiamnash/forwardMessage.js +0 -0
  74. package/leiamnash/getCurrentUserID.js +0 -7
  75. package/leiamnash/getEmojiUrl.js +0 -27
  76. package/leiamnash/getFriendsList.js +0 -73
  77. package/leiamnash/getInfoVideo.js +0 -134
  78. package/leiamnash/getThreadHistory.js +0 -537
  79. package/leiamnash/getThreadHistoryDeprecated.js +0 -71
  80. package/leiamnash/getThreadInfo.js +0 -171
  81. package/leiamnash/getThreadInfoDeprecated.js +0 -56
  82. package/leiamnash/getThreadList.js +0 -213
  83. package/leiamnash/getThreadListDeprecated.js +0 -46
  84. package/leiamnash/getThreadPictures.js +0 -59
  85. package/leiamnash/getUserID.js +0 -61
  86. package/leiamnash/getUserInfo.js +0 -66
  87. package/leiamnash/handleFriendRequest.js +0 -46
  88. package/leiamnash/handleMessageRequest.js +0 -47
  89. package/leiamnash/httpGet.js +0 -47
  90. package/leiamnash/httpPost.js +0 -47
  91. package/leiamnash/httpPostFormData.js +0 -42
  92. package/leiamnash/listenMqtt.js +0 -853
  93. package/leiamnash/logout.js +0 -68
  94. package/leiamnash/markAsDelivered.js +0 -47
  95. package/leiamnash/markAsRead.js +0 -70
  96. package/leiamnash/markAsReadAll.js +0 -40
  97. package/leiamnash/markAsSeen.js +0 -48
  98. package/leiamnash/muteThread.js +0 -45
  99. package/leiamnash/react.js +0 -109
  100. package/leiamnash/removeUserFromGroup.js +0 -45
  101. package/leiamnash/resolvePhotoUrl.js +0 -36
  102. package/leiamnash/searchForThread.js +0 -42
  103. package/leiamnash/seen.js +0 -40
  104. package/leiamnash/sendMessage.js +0 -315
  105. package/leiamnash/sendTypingIndicator.js +0 -70
  106. package/leiamnash/setMessageReaction.js +0 -103
  107. package/leiamnash/setPostReaction.js +0 -63
  108. package/leiamnash/setTitle.js +0 -70
  109. package/leiamnash/threadColors.js +0 -41
  110. package/leiamnash/unfriend.js +0 -42
  111. package/leiamnash/unsendMessage.js +0 -39
  112. /package/{leiamnash → src}/getMessage.js +0 -0
package/src/seen.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function markAsReadAll(callback) {
8
+ let resolveFunc = function () { };
9
+ let rejectFunc = function () { };
10
+ const 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
+ const form = {
25
+ folder: 'inbox'
26
+ };
27
+
28
+ defaultFuncs
29
+ .post(
30
+ "https://www.facebook.com/ajax/mercury/mark_folder_as_read.php",
31
+ ctx.jar,
32
+ form
33
+ )
34
+ .then(utils.saveCookies(ctx.jar))
35
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
36
+ .then(function (resData) {
37
+ if (resData.error) {
38
+ throw resData;
39
+ }
40
+
41
+ return callback();
42
+ })
43
+ .catch(function (err) {
44
+ log.error("markAsReadAll", err);
45
+ return callback(err);
46
+ });
47
+
48
+ return returnPromise;
49
+ };
50
+ };
@@ -0,0 +1,477 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
+
6
+ const allowedProperties = {
7
+ attachment: true,
8
+ url: true,
9
+ sticker: true,
10
+ emoji: true,
11
+ emojiSize: true,
12
+ body: true,
13
+ mentions: true,
14
+ location: true
15
+ };
16
+
17
+ function removeSpecialChar(inputString) { // remove char banned by facebook
18
+ if (typeof inputString !== "string")
19
+ return inputString;
20
+ // Convert string to Buffer
21
+ const buffer = Buffer.from(inputString, 'utf8');
22
+
23
+ // Filter buffer start with ef b8 8f
24
+ let filteredBuffer = Buffer.alloc(0);
25
+ for (let i = 0; i < buffer.length; i++) {
26
+ if (buffer[i] === 0xEF && buffer[i + 1] === 0xB8 && buffer[i + 2] === 0x8F) {
27
+ i += 2; // Skip 3 bytes of buffer starting with ef b8 8f
28
+ } else {
29
+ filteredBuffer = Buffer.concat([filteredBuffer, buffer.slice(i, i + 1)]);
30
+ }
31
+ }
32
+
33
+ // Convert filtered buffer to string
34
+ const convertedString = filteredBuffer.toString('utf8');
35
+
36
+ return convertedString;
37
+ }
38
+
39
+ module.exports = function (defaultFuncs, api, ctx) {
40
+ function uploadAttachment(attachments, callback) {
41
+ const uploads = [];
42
+
43
+ // create an array of promises
44
+ for (let i = 0; i < attachments.length; i++) {
45
+ if (!utils.isReadableStream(attachments[i])) {
46
+ throw {
47
+ error:
48
+ "Attachment should be a readable stream and not " +
49
+ utils.getType(attachments[i]) +
50
+ "."
51
+ };
52
+ }
53
+
54
+ const form = {
55
+ upload_1024: attachments[i],
56
+ voice_clip: "true"
57
+ };
58
+
59
+ uploads.push(
60
+ defaultFuncs
61
+ .postFormData(
62
+ "https://upload.facebook.com/ajax/mercury/upload.php",
63
+ ctx.jar,
64
+ form,
65
+ {}
66
+ )
67
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
68
+ .then(function (resData) {
69
+ if (resData.error) {
70
+ throw resData;
71
+ }
72
+
73
+ // We have to return the data unformatted unless we want to change it
74
+ // back in sendMessage.
75
+ return resData.payload.metadata[0];
76
+ })
77
+ );
78
+ }
79
+
80
+ // resolve all promises
81
+ Promise
82
+ .all(uploads)
83
+ .then(function (resData) {
84
+ callback(null, resData);
85
+ })
86
+ .catch(function (err) {
87
+ log.error("uploadAttachment", err);
88
+ return callback(err);
89
+ });
90
+ }
91
+
92
+ function getUrl(url, callback) {
93
+ const form = {
94
+ image_height: 960,
95
+ image_width: 960,
96
+ uri: url
97
+ };
98
+
99
+ defaultFuncs
100
+ .post(
101
+ "https://www.facebook.com/message_share_attachment/fromURI/",
102
+ ctx.jar,
103
+ form
104
+ )
105
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
106
+ .then(function (resData) {
107
+ if (resData.error) {
108
+ return callback(resData);
109
+ }
110
+
111
+ if (!resData.payload) {
112
+ return callback({ error: "Invalid url" });
113
+ }
114
+
115
+ callback(null, resData.payload.share_data.share_params);
116
+ })
117
+ .catch(function (err) {
118
+ log.error("getUrl", err);
119
+ return callback(err);
120
+ });
121
+ }
122
+
123
+ function sendContent(form, threadID, isSingleUser, messageAndOTID, callback) {
124
+ // There are three cases here:
125
+ // 1. threadID is of type array, where we're starting a new group chat with users
126
+ // specified in the array.
127
+ // 2. User is sending a message to a specific user.
128
+ // 3. No additional form params and the message goes to an existing group chat.
129
+ if (utils.getType(threadID) === "Array") {
130
+ for (let i = 0; i < threadID.length; i++) {
131
+ form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
132
+ }
133
+ form["specific_to_list[" + threadID.length + "]"] = "fbid:" + (ctx.i_userID || ctx.userID);
134
+ form["client_thread_id"] = "root:" + messageAndOTID;
135
+ log.info("sendMessage", "Sending message to multiple users: " + threadID);
136
+ } else {
137
+ // This means that threadID is the id of a user, and the chat
138
+ // is a single person chat
139
+ if (isSingleUser) {
140
+ form["specific_to_list[0]"] = "fbid:" + threadID;
141
+ form["specific_to_list[1]"] = "fbid:" + (ctx.i_userID || ctx.userID);
142
+ form["other_user_fbid"] = threadID;
143
+ } else {
144
+ form["thread_fbid"] = threadID;
145
+ }
146
+ }
147
+
148
+ if (ctx.globalOptions.pageID) {
149
+ form["author"] = "fbid:" + ctx.globalOptions.pageID;
150
+ form["specific_to_list[1]"] = "fbid:" + ctx.globalOptions.pageID;
151
+ form["creator_info[creatorID]"] = ctx.i_userID || ctx.userID;
152
+ form["creator_info[creatorType]"] = "direct_admin";
153
+ form["creator_info[labelType]"] = "sent_message";
154
+ form["creator_info[pageID]"] = ctx.globalOptions.pageID;
155
+ form["request_user_id"] = ctx.globalOptions.pageID;
156
+ form["creator_info[profileURI]"] =
157
+ "https://www.facebook.com/profile.php?id=" + (ctx.i_userID || ctx.userID);
158
+ }
159
+
160
+ defaultFuncs
161
+ .post("https://www.facebook.com/messaging/send/", ctx.jar, form)
162
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
163
+ .then(function (resData) {
164
+ if (!resData) {
165
+ return callback({ error: "Send message failed." });
166
+ }
167
+
168
+ if (resData.error) {
169
+ if (resData.error === 1545012) {
170
+ log.warn(
171
+ "sendMessage",
172
+ "Got error 1545012. This might mean that you're not part of the conversation " +
173
+ threadID
174
+ );
175
+ }
176
+ else {
177
+ log.error("sendMessage", resData);
178
+ }
179
+ return callback(resData);
180
+ }
181
+
182
+ const messageInfo = resData.payload.actions.reduce(function (p, v) {
183
+ return (
184
+ {
185
+ threadID: v.thread_fbid,
186
+ messageID: v.message_id,
187
+ timestamp: v.timestamp
188
+ } || p
189
+ );
190
+ }, null);
191
+
192
+ return callback(null, messageInfo);
193
+ })
194
+ .catch(function (err) {
195
+ log.error("sendMessage", err);
196
+ if (utils.getType(err) == "Object" && err.error === "Not logged in.") {
197
+ ctx.loggedIn = false;
198
+ }
199
+ return callback(err);
200
+ });
201
+ }
202
+
203
+ function send(form, threadID, messageAndOTID, callback, isGroup) {
204
+ // We're doing a query to this to check if the given id is the id of
205
+ // a user or of a group chat. The form will be different depending
206
+ // on that.
207
+ if (utils.getType(threadID) === "Array") {
208
+ sendContent(form, threadID, false, messageAndOTID, callback);
209
+ } else {
210
+ if (utils.getType(isGroup) != "Boolean") {
211
+ // Removed the use of api.getUserInfo() in the old version to reduce account lockout
212
+ sendContent(form, threadID, threadID.toString().length < 16, messageAndOTID, callback);
213
+ } else {
214
+ sendContent(form, threadID, !isGroup, messageAndOTID, callback);
215
+ }
216
+ }
217
+ }
218
+
219
+ function handleUrl(msg, form, callback, cb) {
220
+ if (msg.url) {
221
+ form["shareable_attachment[share_type]"] = "100";
222
+ getUrl(msg.url, function (err, params) {
223
+ if (err) {
224
+ return callback(err);
225
+ }
226
+
227
+ form["shareable_attachment[share_params]"] = params;
228
+ cb();
229
+ });
230
+ } else {
231
+ cb();
232
+ }
233
+ }
234
+
235
+ function handleLocation(msg, form, callback, cb) {
236
+ if (msg.location) {
237
+ if (msg.location.latitude == null || msg.location.longitude == null) {
238
+ return callback({ error: "location property needs both latitude and longitude" });
239
+ }
240
+
241
+ form["location_attachment[coordinates][latitude]"] = msg.location.latitude;
242
+ form["location_attachment[coordinates][longitude]"] = msg.location.longitude;
243
+ form["location_attachment[is_current_location]"] = !!msg.location.current;
244
+ }
245
+
246
+ cb();
247
+ }
248
+
249
+ function handleSticker(msg, form, callback, cb) {
250
+ if (msg.sticker) {
251
+ form["sticker_id"] = msg.sticker;
252
+ }
253
+ cb();
254
+ }
255
+
256
+ function handleEmoji(msg, form, callback, cb) {
257
+ if (msg.emojiSize != null && msg.emoji == null) {
258
+ return callback({ error: "emoji property is empty" });
259
+ }
260
+ if (msg.emoji) {
261
+ if (msg.emojiSize == null) {
262
+ msg.emojiSize = "medium";
263
+ }
264
+ if (
265
+ msg.emojiSize != "small" &&
266
+ msg.emojiSize != "medium" &&
267
+ msg.emojiSize != "large"
268
+ ) {
269
+ return callback({ error: "emojiSize property is invalid" });
270
+ }
271
+ if (form["body"] != null && form["body"] != "") {
272
+ return callback({ error: "body is not empty" });
273
+ }
274
+ form["body"] = msg.emoji;
275
+ form["tags[0]"] = "hot_emoji_size:" + msg.emojiSize;
276
+ }
277
+ cb();
278
+ }
279
+
280
+ function handleAttachment(msg, form, callback, cb) {
281
+ if (msg.attachment) {
282
+ form["image_ids"] = [];
283
+ form["gif_ids"] = [];
284
+ form["file_ids"] = [];
285
+ form["video_ids"] = [];
286
+ form["audio_ids"] = [];
287
+
288
+ if (utils.getType(msg.attachment) !== "Array") {
289
+ msg.attachment = [msg.attachment];
290
+ }
291
+
292
+ uploadAttachment(msg.attachment, function (err, files) {
293
+ if (err) {
294
+ return callback(err);
295
+ }
296
+
297
+ files.forEach(function (file) {
298
+ const key = Object.keys(file);
299
+ const type = key[0]; // image_id, file_id, etc
300
+ form["" + type + "s"].push(file[type]); // push the id
301
+ });
302
+ cb();
303
+ });
304
+ } else {
305
+ cb();
306
+ }
307
+ }
308
+
309
+ function handleMention(msg, form, callback, cb) {
310
+ if (msg.mentions) {
311
+ for (let i = 0; i < msg.mentions.length; i++) {
312
+ const mention = msg.mentions[i];
313
+
314
+ const tag = mention.tag;
315
+ if (typeof tag !== "string") {
316
+ return callback({ error: "Mention tags must be strings." });
317
+ }
318
+
319
+ const offset = msg.body.indexOf(tag, mention.fromIndex || 0);
320
+
321
+ if (offset < 0) {
322
+ log.warn(
323
+ "handleMention",
324
+ 'Mention for "' + tag + '" not found in message string.'
325
+ );
326
+ }
327
+
328
+ if (mention.id == null) {
329
+ log.warn("handleMention", "Mention id should be non-null.");
330
+ }
331
+
332
+ const id = mention.id || 0;
333
+ form["profile_xmd[" + i + "][offset]"] = offset;
334
+ form["profile_xmd[" + i + "][length]"] = tag.length;
335
+ form["profile_xmd[" + i + "][id]"] = id;
336
+ form["profile_xmd[" + i + "][type]"] = "p";
337
+ }
338
+ }
339
+ cb();
340
+ }
341
+
342
+ return function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
343
+ typeof isGroup == "undefined" ? isGroup = null : "";
344
+ if (
345
+ !callback &&
346
+ (utils.getType(threadID) === "Function" ||
347
+ utils.getType(threadID) === "AsyncFunction")
348
+ ) {
349
+ return threadID({ error: "Pass a threadID as a second argument." });
350
+ }
351
+ if (
352
+ !replyToMessage &&
353
+ utils.getType(callback) === "String"
354
+ ) {
355
+ replyToMessage = callback;
356
+ callback = function () { };
357
+ }
358
+
359
+ let resolveFunc = function () { };
360
+ let rejectFunc = function () { };
361
+ const returnPromise = new Promise(function (resolve, reject) {
362
+ resolveFunc = resolve;
363
+ rejectFunc = reject;
364
+ });
365
+
366
+ if (!callback) {
367
+ callback = function (err, friendList) {
368
+ if (err) {
369
+ return rejectFunc(err);
370
+ }
371
+ resolveFunc(friendList);
372
+ };
373
+ }
374
+
375
+ const msgType = utils.getType(msg);
376
+ const threadIDType = utils.getType(threadID);
377
+ const messageIDType = utils.getType(replyToMessage);
378
+
379
+ if (msgType !== "String" && msgType !== "Object") {
380
+ return callback({
381
+ error:
382
+ "Message should be of type string or object and not " + msgType + "."
383
+ });
384
+ }
385
+
386
+ // Changing this to accomodate an array of users
387
+ if (
388
+ threadIDType !== "Array" &&
389
+ threadIDType !== "Number" &&
390
+ threadIDType !== "String"
391
+ ) {
392
+ return callback({
393
+ error:
394
+ "ThreadID should be of type number, string, or array and not " +
395
+ threadIDType +
396
+ "."
397
+ });
398
+ }
399
+
400
+ if (replyToMessage && messageIDType !== 'String') {
401
+ return callback({
402
+ error:
403
+ "MessageID should be of type string and not " +
404
+ threadIDType +
405
+ "."
406
+ });
407
+ }
408
+
409
+ if (msgType === "String") {
410
+ msg = { body: msg };
411
+ }
412
+
413
+ if (utils.getType(msg.body) === "String") {
414
+ msg.body = removeSpecialChar(msg.body);
415
+ }
416
+
417
+ const disallowedProperties = Object.keys(msg).filter(
418
+ prop => !allowedProperties[prop]
419
+ );
420
+ if (disallowedProperties.length > 0) {
421
+ return callback({
422
+ error: "Dissallowed props: `" + disallowedProperties.join(", ") + "`"
423
+ });
424
+ }
425
+
426
+ const messageAndOTID = utils.generateOfflineThreadingID();
427
+
428
+ const form = {
429
+ client: "mercury",
430
+ action_type: "ma-type:user-generated-message",
431
+ author: "fbid:" + (ctx.i_userID || ctx.userID),
432
+ timestamp: Date.now(),
433
+ timestamp_absolute: "Today",
434
+ timestamp_relative: utils.generateTimestampRelative(),
435
+ timestamp_time_passed: "0",
436
+ is_unread: false,
437
+ is_cleared: false,
438
+ is_forward: false,
439
+ is_filtered_content: false,
440
+ is_filtered_content_bh: false,
441
+ is_filtered_content_account: false,
442
+ is_filtered_content_quasar: false,
443
+ is_filtered_content_invalid_app: false,
444
+ is_spoof_warning: false,
445
+ source: "source:chat:web",
446
+ "source_tags[0]": "source:chat",
447
+ body: msg.body ? msg.body.toString() : "",
448
+ html_body: false,
449
+ ui_push_phase: "V3",
450
+ status: "0",
451
+ offline_threading_id: messageAndOTID,
452
+ message_id: messageAndOTID,
453
+ threading_id: utils.generateThreadingID(ctx.clientID),
454
+ "ephemeral_ttl_mode:": "0",
455
+ manual_retry_cnt: "0",
456
+ has_attachment: !!(msg.attachment || msg.url || msg.sticker),
457
+ signatureID: utils.getSignatureID(),
458
+ replied_to_message_id: replyToMessage
459
+ };
460
+
461
+ handleLocation(msg, form, callback, () =>
462
+ handleSticker(msg, form, callback, () =>
463
+ handleAttachment(msg, form, callback, () =>
464
+ handleUrl(msg, form, callback, () =>
465
+ handleEmoji(msg, form, callback, () =>
466
+ handleMention(msg, form, callback, () =>
467
+ send(form, threadID, messageAndOTID, callback, isGroup)
468
+ )
469
+ )
470
+ )
471
+ )
472
+ )
473
+ );
474
+
475
+ return returnPromise;
476
+ };
477
+ };
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ function makeTypingIndicator(typ, threadID, callback, isGroup) {
8
+ const 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
+ };