@dongdev/fca-unofficial 2.0.6 → 2.0.8

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 (74) hide show
  1. package/CHANGELOG.md +6 -1
  2. package/func/checkUpdate.js +9 -9
  3. package/func/logger.js +40 -104
  4. package/module/login.js +4 -4
  5. package/module/loginHelper.js +3 -3
  6. package/module/options.js +5 -9
  7. package/package.json +6 -6
  8. package/src/api/action/addExternalModule.js +5 -5
  9. package/src/api/action/changeAvatar.js +11 -10
  10. package/src/api/action/changeBio.js +7 -8
  11. package/src/api/action/getCurrentUserID.js +1 -1
  12. package/src/api/action/handleFriendRequest.js +5 -5
  13. package/src/api/action/logout.js +9 -8
  14. package/src/api/action/refreshFb_dtsg.js +17 -12
  15. package/src/api/action/setPostReaction.js +10 -11
  16. package/src/api/action/unfriend.js +3 -4
  17. package/src/api/http/httpGet.js +7 -8
  18. package/src/api/http/httpPost.js +7 -8
  19. package/src/api/http/postFormData.js +6 -5
  20. package/src/api/messaging/addUserToGroup.js +0 -1
  21. package/src/api/messaging/changeAdminStatus.js +108 -89
  22. package/src/api/messaging/changeArchivedStatus.js +6 -6
  23. package/src/api/messaging/changeBlockedStatus.js +3 -4
  24. package/src/api/messaging/changeGroupImage.js +72 -117
  25. package/src/api/messaging/changeNickname.js +59 -48
  26. package/src/api/messaging/changeThreadColor.js +61 -47
  27. package/src/api/messaging/changeThreadEmoji.js +106 -0
  28. package/src/api/messaging/createNewGroup.js +5 -5
  29. package/src/api/messaging/createPoll.js +36 -63
  30. package/src/api/messaging/deleteMessage.js +4 -4
  31. package/src/api/messaging/deleteThread.js +4 -4
  32. package/src/api/messaging/forwardAttachment.js +38 -47
  33. package/src/api/messaging/getFriendsList.js +5 -6
  34. package/src/api/messaging/getMessage.js +4 -9
  35. package/src/api/messaging/handleMessageRequest.js +5 -5
  36. package/src/api/messaging/markAsDelivered.js +5 -5
  37. package/src/api/messaging/markAsRead.js +7 -7
  38. package/src/api/messaging/markAsReadAll.js +3 -4
  39. package/src/api/messaging/markAsSeen.js +7 -7
  40. package/src/api/messaging/muteThread.js +3 -4
  41. package/src/api/messaging/removeUserFromGroup.js +82 -56
  42. package/src/api/messaging/resolvePhotoUrl.js +2 -3
  43. package/src/api/messaging/searchForThread.js +2 -3
  44. package/src/api/messaging/sendMessage.js +171 -101
  45. package/src/api/messaging/sendMessageMqtt.js +14 -12
  46. package/src/api/messaging/sendTypingIndicator.js +11 -11
  47. package/src/api/messaging/setMessageReaction.js +68 -82
  48. package/src/api/messaging/setTitle.js +77 -48
  49. package/src/api/messaging/shareContact.js +2 -4
  50. package/src/api/messaging/threadColors.js +0 -3
  51. package/src/api/messaging/unsendMessage.js +74 -37
  52. package/src/api/messaging/uploadAttachment.js +11 -9
  53. package/src/api/socket/core/connectMqtt.js +180 -0
  54. package/src/api/socket/core/getSeqID.js +25 -0
  55. package/src/api/socket/core/getTaskResponseData.js +22 -0
  56. package/src/api/socket/core/markDelivery.js +12 -0
  57. package/src/api/socket/core/parseDelta.js +351 -0
  58. package/src/api/socket/detail/buildStream.js +176 -68
  59. package/src/api/socket/detail/constants.js +24 -0
  60. package/src/api/socket/listenMqtt.js +80 -1005
  61. package/src/api/{messaging → threads}/getThreadHistory.js +5 -22
  62. package/src/api/threads/getThreadInfo.js +35 -248
  63. package/src/api/threads/getThreadList.js +20 -20
  64. package/src/api/threads/getThreadPictures.js +3 -4
  65. package/src/api/users/getUserID.js +5 -6
  66. package/src/api/users/getUserInfo.js +305 -73
  67. package/src/api/users/getUserInfoV2.js +134 -0
  68. package/src/database/models/user.js +32 -0
  69. package/src/database/userData.js +89 -0
  70. package/src/utils/constants.js +12 -2
  71. package/src/utils/format.js +1051 -0
  72. package/src/utils/request.js +75 -7
  73. package/src/api/threads/changeThreadEmoji.js +0 -55
  74. package/src/utils/index.js +0 -1497
@@ -1,7 +1,9 @@
1
- const utils = require("../../utils");
1
+
2
2
  var log = require("npmlog");
3
3
  var bluebird = require("bluebird");
4
-
4
+ const { parseAndCheckLogin } = require("../../utils/client");
5
+ const { getType } = require("../../utils/format");
6
+ const { isReadableStream } = require("../../utils/constants");
5
7
  module.exports = function(defaultFuncs, api, ctx) {
6
8
  function uploadAttachment(attachments, callback) {
7
9
  callback = callback || function() {};
@@ -9,11 +11,11 @@ module.exports = function(defaultFuncs, api, ctx) {
9
11
 
10
12
  // create an array of promises
11
13
  for (var i = 0; i < attachments.length; i++) {
12
- if (!utils.isReadableStream(attachments[i])) {
14
+ if (!isReadableStream(attachments[i])) {
13
15
  throw {
14
16
  error:
15
17
  "Attachment should be a readable stream and not " +
16
- utils.getType(attachments[i]) +
18
+ getType(attachments[i]) +
17
19
  "."
18
20
  };
19
21
  }
@@ -31,7 +33,7 @@ module.exports = function(defaultFuncs, api, ctx) {
31
33
  form,
32
34
  {}
33
35
  )
34
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
36
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
35
37
  .then(function(resData) {
36
38
  if (resData.error) {
37
39
  throw resData;
@@ -105,7 +107,7 @@ module.exports = function(defaultFuncs, api, ctx) {
105
107
  form.payload.tasks[0].payload.attachment_fbids = [];
106
108
  if (form.payload.tasks[0].payload.text == "")
107
109
  form.payload.tasks[0].payload.text = null;
108
- if (utils.getType(msg.attachment) !== "Array") {
110
+ if (getType(msg.attachment) !== "Array") {
109
111
  msg.attachment = [msg.attachment];
110
112
  }
111
113
 
@@ -228,12 +230,12 @@ module.exports = function(defaultFuncs, api, ctx) {
228
230
  return function sendMessageMqtt(msg, threadID, callback, replyToMessage) {
229
231
  if (
230
232
  !callback &&
231
- (utils.getType(threadID) === "Function" ||
232
- utils.getType(threadID) === "AsyncFunction")
233
+ (getType(threadID) === "Function" ||
234
+ getType(threadID) === "AsyncFunction")
233
235
  ) {
234
236
  return threadID({ error: "Pass a threadID as a second argument." });
235
237
  }
236
- if (!replyToMessage && utils.getType(callback) === "String") {
238
+ if (!replyToMessage && getType(callback) === "String") {
237
239
  replyToMessage = callback;
238
240
  callback = function() {};
239
241
  }
@@ -242,9 +244,9 @@ module.exports = function(defaultFuncs, api, ctx) {
242
244
  callback = function(err, friendList) {};
243
245
  }
244
246
 
245
- var msgType = utils.getType(msg);
246
- var threadIDType = utils.getType(threadID);
247
- var messageIDType = utils.getType(replyToMessage);
247
+ var msgType = getType(msg);
248
+ var threadIDType = getType(threadID);
249
+ var messageIDType = getType(replyToMessage);
248
250
 
249
251
  if (msgType !== "String" && msgType !== "Object") {
250
252
  return callback({
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { getType } = require("../../utils/format");
5
+ const { parseAndCheckLogin } = require("../../utils/client");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  function makeTypingIndicator(typ, threadID, callback, isGroup) {
8
8
  const form = {
@@ -14,13 +14,13 @@ module.exports = function(defaultFuncs, api, ctx) {
14
14
 
15
15
  // Check if thread is a single person chat or a group chat
16
16
  // More info on this is in api.sendMessage
17
- if (utils.getType(isGroup) == "Boolean") {
17
+ if (getType(isGroup) == "Boolean") {
18
18
  if (!isGroup) {
19
19
  form.to = threadID;
20
20
  }
21
21
  defaultFuncs
22
22
  .post("https://www.facebook.com/ajax/messaging/typ.php", ctx.jar, form)
23
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
23
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
24
24
  .then(function(resData) {
25
25
  if (resData.error) {
26
26
  throw resData;
@@ -30,7 +30,7 @@ module.exports = function(defaultFuncs, api, ctx) {
30
30
  })
31
31
  .catch(function(err) {
32
32
  log.error("sendTypingIndicator", err);
33
- if (utils.getType(err) == "Object" && err.error === "Not logged in") {
33
+ if (getType(err) == "Object" && err.error === "Not logged in") {
34
34
  ctx.loggedIn = false;
35
35
  }
36
36
  return callback(err);
@@ -52,7 +52,7 @@ module.exports = function(defaultFuncs, api, ctx) {
52
52
  ctx.jar,
53
53
  form
54
54
  )
55
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
55
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
56
56
  .then(function(resData) {
57
57
  if (resData.error) {
58
58
  throw resData;
@@ -63,7 +63,7 @@ module.exports = function(defaultFuncs, api, ctx) {
63
63
  .catch(function(err) {
64
64
  log.error("sendTypingIndicator", err);
65
65
  if (
66
- utils.getType(err) == "Object" &&
66
+ getType(err) == "Object" &&
67
67
  err.error === "Not logged in."
68
68
  ) {
69
69
  ctx.loggedIn = false;
@@ -76,8 +76,8 @@ module.exports = function(defaultFuncs, api, ctx) {
76
76
 
77
77
  return function sendTypingIndicator(threadID, callback, isGroup) {
78
78
  if (
79
- utils.getType(callback) !== "Function" &&
80
- utils.getType(callback) !== "AsyncFunction"
79
+ getType(callback) !== "Function" &&
80
+ getType(callback) !== "AsyncFunction"
81
81
  ) {
82
82
  if (callback) {
83
83
  log.warn(
@@ -92,8 +92,8 @@ module.exports = function(defaultFuncs, api, ctx) {
92
92
 
93
93
  return function end(cb) {
94
94
  if (
95
- utils.getType(cb) !== "Function" &&
96
- utils.getType(cb) !== "AsyncFunction"
95
+ getType(cb) !== "Function" &&
96
+ getType(cb) !== "AsyncFunction"
97
97
  ) {
98
98
  if (cb) {
99
99
  log.warn(
@@ -1,119 +1,105 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
- var log = require("npmlog");
5
- const { generateOfflineThreadingID } = require("../../utils");
3
+ const log = require("npmlog");
4
+ const { generateOfflineThreadingID, getCurrentTimestamp } = require("../../utils/format");
5
+ const { parseAndCheckLogin } = require("../../utils/client");
6
6
 
7
- module.exports = function(defaultFuncs, api, ctx) {
8
- function setMessageReactionNoMqtt(reaction, messageID, callback) {
9
- var resolveFunc = function() {};
10
- var rejectFunc = function() {};
11
- var returnPromise = new Promise(function(resolve, reject) {
7
+ module.exports = function (defaultFuncs, api, ctx) {
8
+ function setMessageReactionNoMqtt(reaction, messageID, threadID, callback) {
9
+ let resolveFunc = function () { };
10
+ let rejectFunc = function () { };
11
+ const returnPromise = new Promise(function (resolve, reject) {
12
12
  resolveFunc = resolve;
13
13
  rejectFunc = reject;
14
14
  });
15
15
  if (!callback) {
16
- callback = function(err, friendList) {
17
- if (err) {
18
- return rejectFunc(err);
19
- }
20
- resolveFunc(friendList);
16
+ callback = function (err) {
17
+ if (err) return rejectFunc(err);
18
+ resolveFunc();
21
19
  };
22
20
  }
23
- var variables = {
21
+ const variables = {
24
22
  data: {
25
23
  client_mutation_id: ctx.clientMutationId++,
26
24
  actor_id: ctx.userID,
27
- action: reaction == "" ? "REMOVE_REACTION" : "ADD_REACTION",
25
+ action: reaction === "" ? "REMOVE_REACTION" : "ADD_REACTION",
28
26
  message_id: messageID,
29
27
  reaction: reaction
30
28
  }
31
29
  };
32
- var qs = {
30
+ const qs = {
33
31
  doc_id: "1491398900900362",
34
32
  variables: JSON.stringify(variables),
35
33
  dpr: 1
36
34
  };
37
35
  defaultFuncs
38
- .postFormData(
39
- "https://www.facebook.com/webgraphql/mutation/",
40
- ctx.jar,
41
- {},
42
- qs
43
- )
44
- .then(utils.parseAndCheckLogin(ctx.jar, defaultFuncs))
45
- .then(function(resData) {
46
- if (!resData) {
47
- throw { error: "setReaction returned empty object." };
48
- }
49
- if (resData.error) {
50
- throw resData;
51
- }
36
+ .postFormData("https://www.facebook.com/webgraphql/mutation/", ctx.jar, {}, qs)
37
+ .then(parseAndCheckLogin(ctx.jar, defaultFuncs))
38
+ .then(function (resData) {
39
+ if (!resData) throw { error: "setReaction returned empty object." };
40
+ if (resData.error) throw resData;
52
41
  callback(null);
53
42
  })
54
- .catch(function(err) {
43
+ .catch(function (err) {
55
44
  log.error("setReaction", err);
56
45
  return callback(err);
57
46
  });
58
-
59
47
  return returnPromise;
60
48
  }
61
49
 
62
50
  function setMessageReactionMqtt(reaction, messageID, threadID, callback) {
63
- if (!ctx.mqttClient) {
64
- throw new Error("Not connected to MQTT");
65
- }
66
- ctx.wsReqNumber += 1;
67
- let taskNumber = ++ctx.wsTaskNumber;
68
- const taskPayload = {
69
- thread_key: threadID,
70
- timestamp_ms: getCurrentTimestamp(),
71
- message_id: messageID,
72
- reaction: reaction,
73
- actor_id: ctx.userID,
74
- reaction_style: null,
75
- sync_group: 1,
76
- send_attribution: Math.random() < 0.5 ? 65537 : 524289
77
- };
78
- const task = {
79
- failure_count: null,
80
- label: "29",
81
- payload: JSON.stringify(taskPayload),
82
- queue_name: JSON.stringify(["reaction", messageID]),
83
- task_id: taskNumber
84
- };
85
- const content = {
86
- app_id: "2220391788200892",
87
- payload: JSON.stringify({
88
- data_trace_id: null,
89
- epoch_id: parseInt(generateOfflineThreadingID()),
90
- tasks: [task],
91
- version_id: "7158486590867448"
92
- }),
93
- request_id: ctx.wsReqNumber,
94
- type: 3
95
- };
96
- if (typeof callback === "function") {
97
- ctx["tasks"].set(taskNumber, {
98
- type: "set_message_reaction",
99
- callback: callback
100
- });
101
- }
102
- ctx.mqttClient.publish("/ls_req", JSON.stringify(content), {
103
- qos: 1,
104
- retain: false
51
+ if (!ctx.mqttClient) return setMessageReactionNoMqtt(reaction, messageID, callback);
52
+ return new Promise((resolve, reject) => {
53
+ try {
54
+ ctx.wsReqNumber += 1;
55
+ const taskNumber = ++ctx.wsTaskNumber;
56
+ const taskPayload = {
57
+ thread_key: threadID,
58
+ timestamp_ms: getCurrentTimestamp(),
59
+ message_id: messageID,
60
+ reaction: reaction,
61
+ actor_id: ctx.userID,
62
+ reaction_style: null,
63
+ sync_group: 1,
64
+ send_attribution: Math.random() < 0.5 ? 65537 : 524289
65
+ };
66
+ const task = {
67
+ failure_count: null,
68
+ label: "29",
69
+ payload: JSON.stringify(taskPayload),
70
+ queue_name: JSON.stringify(["reaction", messageID]),
71
+ task_id: taskNumber
72
+ };
73
+ const content = {
74
+ app_id: "2220391788200892",
75
+ payload: JSON.stringify({
76
+ data_trace_id: null,
77
+ epoch_id: parseInt(generateOfflineThreadingID()),
78
+ tasks: [task],
79
+ version_id: "7158486590867448"
80
+ }),
81
+ request_id: ctx.wsReqNumber,
82
+ type: 3
83
+ };
84
+ const internalCb = (err) => {
85
+ if (typeof callback === "function") callback(err);
86
+ if (err) return reject(err);
87
+ return resolve();
88
+ };
89
+ ctx.tasks.set(taskNumber, { type: "set_message_reaction", callback: internalCb });
90
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(content), { qos: 1, retain: false });
91
+ if (typeof callback !== "function") resolve();
92
+ } catch (e) {
93
+ if (typeof callback === "function") callback(e);
94
+ reject(e);
95
+ }
105
96
  });
106
97
  }
98
+
107
99
  return function setMessageReaction(reaction, messageID, threadID, callback) {
108
100
  if (ctx.mqttClient) {
109
- try {
110
- setMessageReactionMqtt(reaction, messageID, threadID, callback);
111
- callback();
112
- } catch (e) {
113
- setMessageReactionNoMqtt(reaction, messageID, callback);
114
- }
115
- } else {
116
- setMessageReactionNoMqtt(reaction, messageID, callback);
101
+ return setMessageReactionMqtt(reaction, messageID, threadID, callback);
117
102
  }
103
+ return setMessageReactionNoMqtt(reaction, messageID, threadID, callback);
118
104
  };
119
105
  };
@@ -1,44 +1,34 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
3
+ const { getType, generateOfflineThreadingID, generateTimestampRelative, generateThreadingID, getCurrentTimestamp } = require("../../utils/format");
4
+ const { parseAndCheckLogin } = require("../../utils/client");
4
5
  const log = require("npmlog");
5
6
 
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
- let resolveFunc = function() {};
17
- let rejectFunc = function() {};
18
- const returnPromise = new Promise(function(resolve, reject) {
7
+ module.exports = function (defaultFuncs, api, ctx) {
8
+ function setTitleNoMqtt(newTitle, threadID, callback) {
9
+ if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) throw { error: "please pass a threadID as a second argument." };
10
+ var resolveFunc = function () { };
11
+ var rejectFunc = function () { };
12
+ var returnPromise = new Promise(function (resolve, reject) {
19
13
  resolveFunc = resolve;
20
14
  rejectFunc = reject;
21
15
  });
22
-
23
16
  if (!callback) {
24
- callback = function(err, friendList) {
25
- if (err) {
26
- return rejectFunc(err);
27
- }
28
- resolveFunc(friendList);
17
+ callback = function (err, data) {
18
+ if (err) return rejectFunc(err);
19
+ resolveFunc(data);
29
20
  };
30
21
  }
31
-
32
- const messageAndOTID = utils.generateOfflineThreadingID();
33
- const form = {
22
+ var messageAndOTID = generateOfflineThreadingID();
23
+ var form = {
34
24
  client: "mercury",
35
25
  action_type: "ma-type:log-message",
36
- author: "fbid:" + (ctx.i_userID || ctx.userID),
26
+ author: "fbid:" + ctx.userID,
37
27
  author_email: "",
38
28
  coordinates: "",
39
29
  timestamp: Date.now(),
40
30
  timestamp_absolute: "Today",
41
- timestamp_relative: utils.generateTimestampRelative(),
31
+ timestamp_relative: generateTimestampRelative(),
42
32
  timestamp_time_passed: "0",
43
33
  is_unread: false,
44
34
  is_cleared: false,
@@ -50,41 +40,80 @@ module.exports = function(defaultFuncs, api, ctx) {
50
40
  status: "0",
51
41
  offline_threading_id: messageAndOTID,
52
42
  message_id: messageAndOTID,
53
- threading_id: utils.generateThreadingID(ctx.clientID),
43
+ threading_id: generateThreadingID(ctx.clientID),
54
44
  manual_retry_cnt: "0",
55
45
  thread_fbid: threadID,
56
46
  thread_name: newTitle,
57
47
  thread_id: threadID,
58
48
  log_message_type: "log:thread-name"
59
49
  };
60
-
61
50
  defaultFuncs
62
- .post(
63
- "https://www.facebook.com/messaging/set_thread_name/",
64
- ctx.jar,
65
- form
66
- )
67
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
68
- .then(function(resData) {
69
- if (resData.error && resData.error === 1545012) {
70
- throw { error: "Cannot change chat title: Not member of chat." };
71
- }
72
-
73
- if (resData.error && resData.error === 1545003) {
74
- throw { error: "Cannot set title of single-user chat." };
75
- }
76
-
77
- if (resData.error) {
78
- throw resData;
79
- }
80
-
51
+ .post("https://www.facebook.com/messaging/set_thread_name/", ctx.jar, form)
52
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
53
+ .then(function (resData) {
54
+ if (resData.error && resData.error === 1545012) throw { error: "Cannot change chat title: Not member of chat." };
55
+ if (resData.error && resData.error === 1545003) throw { error: "Cannot set title of single-user chat." };
56
+ if (resData.error) throw resData;
81
57
  return callback();
82
58
  })
83
- .catch(function(err) {
59
+ .catch(function (err) {
84
60
  log.error("setTitle", err);
85
61
  return callback(err);
86
62
  });
87
-
88
63
  return returnPromise;
89
64
  };
65
+ function setTitleMqtt(newTitle, threadID, callback) {
66
+ if (!ctx.mqttClient) {
67
+ throw new Error("Not connected to MQTT");
68
+ }
69
+ var resolveFunc = function () { };
70
+ var rejectFunc = function () { };
71
+ var returnPromise = new Promise(function (resolve, reject) {
72
+ resolveFunc = resolve;
73
+ rejectFunc = reject;
74
+ });
75
+ if (!callback) {
76
+ callback = function (err, data) {
77
+ if (err) return rejectFunc(err);
78
+ resolveFunc(data);
79
+ data
80
+ };
81
+ }
82
+ let count_req = 0
83
+ var form = JSON.stringify({
84
+ "app_id": "2220391788200892",
85
+ "payload": JSON.stringify({
86
+ epoch_id: generateOfflineThreadingID(),
87
+ tasks: [
88
+ {
89
+ failure_count: null,
90
+ label: '32',
91
+ payload: JSON.stringify({
92
+ "thread_key": threadID,
93
+ "thread_name": newTitle,
94
+ "sync_group": 1
95
+ }),
96
+ queue_name: threadID,
97
+ task_id: Math.random() * 1001 << 0
98
+ }
99
+ ],
100
+ version_id: '8798795233522156'
101
+ }),
102
+ "request_id": ++count_req,
103
+ "type": 3
104
+ });
105
+ mqttClient.publish('/ls_req', form);
106
+ return returnPromise;
107
+ };
108
+ return function setTitle(newTitle, threadID, callback) {
109
+ if (ctx.mqttClient) {
110
+ try {
111
+ setTitleMqtt(newTitle, threadID, callback);
112
+ } catch (e) {
113
+ setTitleNoMqtt(newTitle, threadID, callback);
114
+ }
115
+ } else {
116
+ setTitleNoMqtt(newTitle, threadID, callback);
117
+ }
118
+ };
90
119
  };
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
- var log = require("npmlog");
5
-
3
+ const { generateOfflineThreadingID } = require("../../utils/format");
6
4
  module.exports = function(defaultFuncs, api, ctx) {
7
5
  return function shareContact(text, senderID, threadID, callback) {
8
6
  if (!text) {
@@ -39,7 +37,7 @@ module.exports = function(defaultFuncs, api, ctx) {
39
37
  failure_count: null
40
38
  }
41
39
  ],
42
- epoch_id: utils.generateOfflineThreadingID(),
40
+ epoch_id: generateOfflineThreadingID(),
43
41
  version_id: "7214102258676893"
44
42
  }),
45
43
  request_id: ++count_req,
@@ -33,9 +33,6 @@ module.exports = function(_defaultFuncs, _api, _ctx) {
33
33
  MediumSlateBlue: "234137870477637", //BrightPurple
34
34
  DeepSkyBlue: "2442142322678320", //AquaBlue
35
35
  BrilliantRose: "169463077092846", //HotPink
36
- //i've tried my best, everything else can't be mapped. (or is it?) -UIRI 2020
37
- //#endregion
38
-
39
36
  DefaultBlue: "196241301102133",
40
37
  HotPink: "169463077092846",
41
38
  AquaBlue: "2442142322678320",
@@ -1,44 +1,81 @@
1
1
  "use strict";
2
- const utils = require("../../utils");
3
- const log = require("npmlog");
4
2
 
5
- module.exports = function(defaultFuncs, api, ctx) {
6
- return function unsendMessage(messageID, callback) {
7
- let resolveFunc = function() {};
8
- let rejectFunc = function() {};
9
- const returnPromise = new Promise(function(resolve, reject) {
10
- resolveFunc = resolve;
11
- rejectFunc = reject;
12
- });
3
+ const { generateOfflineThreadingID } = require("../../utils/format.js");
4
+ const log = require("npmlog");
13
5
 
14
- if (!callback) {
15
- callback = function(err, friendList) {
16
- if (err) {
17
- return rejectFunc(err);
18
- }
19
- resolveFunc(friendList);
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function unsendMessage(messageID, threadID, callback) {
8
+ return new Promise((resolve, reject) => {
9
+ if (!ctx.mqttClient) {
10
+ const err = new Error("Not connected to MQTT");
11
+ callback?.(err);
12
+ return reject(err);
13
+ }
14
+ const reqID = ++ctx.wsReqNumber;
15
+ const taskID = ++ctx.wsTaskNumber;
16
+ const taskPayload = {
17
+ message_id: messageID,
18
+ thread_key: threadID,
19
+ sync_group: 1,
20
20
  };
21
- }
22
-
23
- const form = {
24
- message_id: messageID
25
- };
26
-
27
- defaultFuncs
28
- .post("https://www.facebook.com/messaging/unsend_message/", ctx.jar, form)
29
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
30
- .then(function(resData) {
31
- if (resData.error) {
32
- throw resData;
21
+ const task = {
22
+ failure_count: null,
23
+ label: "33",
24
+ payload: JSON.stringify(taskPayload),
25
+ queue_name: "unsend_message",
26
+ task_id: taskID,
27
+ };
28
+ const content = {
29
+ app_id: "2220391788200892",
30
+ payload: JSON.stringify({
31
+ tasks: [task],
32
+ epoch_id: parseInt(generateOfflineThreadingID()),
33
+ version_id: "25393437286970779",
34
+ }),
35
+ request_id: reqID,
36
+ type: 3,
37
+ };
38
+ try {
39
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(content), {
40
+ qos: 1,
41
+ retain: false
42
+ });
43
+ } catch (err) {
44
+ log.error("unsendMessage (MQTT publish failed)", err);
45
+ callback?.(err);
46
+ return reject(err);
47
+ }
48
+ const handleRes = (topic, message) => {
49
+ if (topic !== "/ls_resp") return;
50
+ let jsonMsg;
51
+ try {
52
+ jsonMsg = JSON.parse(message.toString());
53
+ jsonMsg.payload = JSON.parse(jsonMsg.payload);
54
+ } catch (err) {
55
+ return;
33
56
  }
34
-
35
- return callback();
36
- })
37
- .catch(function(err) {
38
- log.error("unsendMessage", err);
39
- return callback(err);
40
- });
41
-
42
- return returnPromise;
57
+ if (jsonMsg.request_id !== reqID) return;
58
+ ctx.mqttClient.removeListener("message", handleRes);
59
+ try {
60
+ const msgID = jsonMsg.payload.step?.[1]?.[2]?.[2]?.[1]?.[2];
61
+ const msgReplace = jsonMsg.payload.step?.[1]?.[2]?.[2]?.[1]?.[4];
62
+ if (msgID && msgReplace) {
63
+ const bodies = {
64
+ body: msgReplace,
65
+ messageID: msgID
66
+ };
67
+ callback?.(null, bodies);
68
+ return resolve(bodies);
69
+ } else {
70
+ callback?.(null, { success: true });
71
+ return resolve({ success: true });
72
+ }
73
+ } catch (err) {
74
+ callback?.(null, { success: true });
75
+ return resolve({ success: true });
76
+ }
77
+ };
78
+ ctx.mqttClient.on("message", handleRes);
79
+ });
43
80
  };
44
81
  };