@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,9 +1,8 @@
1
-
2
1
  "use strict";
3
2
 
4
- const utils = require("../../utils");
5
3
  const log = require("npmlog");
6
-
4
+ const { parseAndCheckLogin } = require("../../utils/client");
5
+ const { getType } = require("../../utils/format");
7
6
  function formatData(resData) {
8
7
  return {
9
8
  viewer_feedback_reaction_info:
@@ -25,8 +24,8 @@ module.exports = function(defaultFuncs, api, ctx) {
25
24
 
26
25
  if (!callback) {
27
26
  if (
28
- utils.getType(type) === "Function" ||
29
- utils.getType(type) === "AsyncFunction"
27
+ getType(type) === "Function" ||
28
+ getType(type) === "AsyncFunction"
30
29
  ) {
31
30
  callback = type;
32
31
  type = 0;
@@ -51,11 +50,11 @@ module.exports = function(defaultFuncs, api, ctx) {
51
50
  angry: 8
52
51
  };
53
52
 
54
- if (utils.getType(type) !== "Number" && utils.getType(type) === "String") {
53
+ if (getType(type) !== "Number" && getType(type) === "String") {
55
54
  type = map[type.toLowerCase()];
56
55
  }
57
56
 
58
- if (utils.getType(type) !== "Number" && utils.getType(type) !== "String") {
57
+ if (getType(type) !== "Number" && getType(type) !== "String") {
59
58
  throw {
60
59
  error: "setPostReaction: Invalid reaction type"
61
60
  };
@@ -68,14 +67,14 @@ module.exports = function(defaultFuncs, api, ctx) {
68
67
  }
69
68
 
70
69
  const form = {
71
- av: ctx.i_userID || ctx.userID,
70
+ av: ctx.userID,
72
71
  fb_api_caller_class: "RelayModern",
73
72
  fb_api_req_friendly_name: "CometUFIFeedbackReactMutation",
74
73
  doc_id: "4769042373179384",
75
74
  variables: JSON.stringify({
76
75
  input: {
77
- actor_id: ctx.i_userID || ctx.userID,
78
- feedback_id: new Buffer("feedback:" + postID).toString("base64"),
76
+ actor_id: ctx.userID,
77
+ feedback_id: Buffer.from("feedback:" + postID).toString("base64"),
79
78
  feedback_reaction: type,
80
79
  feedback_source: "OBJECT",
81
80
  is_tracking_encrypted: true,
@@ -90,7 +89,7 @@ module.exports = function(defaultFuncs, api, ctx) {
90
89
 
91
90
  defaultFuncs
92
91
  .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
93
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
92
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
94
93
  .then(function(resData) {
95
94
  if (resData.errors) {
96
95
  throw resData;
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin } = require("../../utils/client");
6
5
  module.exports = function(defaultFuncs, api, ctx) {
7
6
  return function unfriend(userID, callback) {
8
7
  let resolveFunc = function() {};
@@ -27,7 +26,7 @@ module.exports = function(defaultFuncs, api, ctx) {
27
26
  floc: "friends_tab",
28
27
  "nctr[_mod]":
29
28
  "pagelet_timeline_app_collection_" +
30
- (ctx.i_userID || ctx.userID) +
29
+ ctx.userID +
31
30
  ":2356318349:2"
32
31
  };
33
32
 
@@ -37,7 +36,7 @@ module.exports = function(defaultFuncs, api, ctx) {
37
36
  ctx.jar,
38
37
  form
39
38
  )
40
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
39
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
41
40
  .then(function(resData) {
42
41
  if (resData.error) {
43
42
  throw resData;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { get } = require("../../utils/request");
5
+ const { getType } = require("../../utils/format");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function httpGet(url, form, customHeader, callback, notAPI) {
8
8
  let resolveFunc = function() {};
@@ -14,16 +14,16 @@ module.exports = function(defaultFuncs, api, ctx) {
14
14
  });
15
15
 
16
16
  if (
17
- utils.getType(form) == "Function" ||
18
- utils.getType(form) == "AsyncFunction"
17
+ getType(form) == "Function" ||
18
+ getType(form) == "AsyncFunction"
19
19
  ) {
20
20
  callback = form;
21
21
  form = {};
22
22
  }
23
23
 
24
24
  if (
25
- utils.getType(customHeader) == "Function" ||
26
- utils.getType(customHeader) == "AsyncFunction"
25
+ getType(customHeader) == "Function" ||
26
+ getType(customHeader) == "AsyncFunction"
27
27
  ) {
28
28
  callback = customHeader;
29
29
  customHeader = {};
@@ -39,8 +39,7 @@ module.exports = function(defaultFuncs, api, ctx) {
39
39
  };
40
40
 
41
41
  if (notAPI) {
42
- utils
43
- .get(url, ctx.jar, form, ctx.globalOptions, ctx, customHeader)
42
+ get(url, ctx.jar, form, ctx.globalOptions, ctx, customHeader)
44
43
  .then(function(resData) {
45
44
  callback(null, resData.data.toString());
46
45
  })
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { post } = require("../../utils/request");
5
+ const { getType } = require("../../utils/format");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function httpPost(url, form, customHeader, callback, notAPI) {
8
8
  let resolveFunc = function() {};
@@ -14,16 +14,16 @@ module.exports = function(defaultFuncs, api, ctx) {
14
14
  });
15
15
 
16
16
  if (
17
- utils.getType(form) == "Function" ||
18
- utils.getType(form) == "AsyncFunction"
17
+ getType(form) == "Function" ||
18
+ getType(form) == "AsyncFunction"
19
19
  ) {
20
20
  callback = form;
21
21
  form = {};
22
22
  }
23
23
 
24
24
  if (
25
- utils.getType(customHeader) == "Function" ||
26
- utils.getType(customHeader) == "AsyncFunction"
25
+ getType(customHeader) == "Function" ||
26
+ getType(customHeader) == "AsyncFunction"
27
27
  ) {
28
28
  callback = customHeader;
29
29
  customHeader = {};
@@ -39,8 +39,7 @@ module.exports = function(defaultFuncs, api, ctx) {
39
39
  };
40
40
 
41
41
  if (notAPI) {
42
- utils
43
- .post(url, ctx.jar, form, ctx.globalOptions, ctx, customHeader)
42
+ post(url, ctx.jar, form, ctx.globalOptions, ctx, customHeader)
44
43
  .then(function(resData) {
45
44
  callback(null, resData.data.toString());
46
45
  })
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  var 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
  return function postFormData(url, form, callback) {
8
8
  var resolveFunc = function() {};
@@ -15,8 +15,8 @@ module.exports = function(defaultFuncs, api, ctx) {
15
15
 
16
16
  if (
17
17
  !callback &&
18
- (utils.getType(form) == "Function" ||
19
- utils.getType(form) == "AsyncFunction")
18
+ (getType(form) == "Function" ||
19
+ getType(form) == "AsyncFunction")
20
20
  ) {
21
21
  callback = form;
22
22
  form = {};
@@ -33,8 +33,9 @@ module.exports = function(defaultFuncs, api, ctx) {
33
33
 
34
34
  defaultFuncs
35
35
  .postFormData(url, ctx.jar, form, {})
36
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
36
37
  .then(function(resData) {
37
- callback(null, resData.data.toString());
38
+ callback(null, resData);
38
39
  })
39
40
  .catch(function(err) {
40
41
  log.error("postFormData", err);
@@ -15,7 +15,6 @@ module.exports = function (defaultFuncs, api, ctx) {
15
15
  return reject(err);
16
16
  }
17
17
  if (getType(userID) !== "Array") userID = [userID];
18
-
19
18
  const reqID = ++ctx.wsReqNumber;
20
19
  const taskID = ++ctx.wsTaskNumber;
21
20
 
@@ -1,103 +1,122 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
- const log = require("npmlog");
3
+ const { generateOfflineThreadingID, getType } = require("../../utils/format");
5
4
 
6
- module.exports = function(defaultFuncs, api, ctx) {
7
- return function changeAdminStatus(threadID, adminIDs, adminStatus, callback) {
8
- if (utils.getType(threadID) !== "String") {
9
- throw new utils.CustomError({
10
- error: "changeAdminStatus: threadID must be a string"
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ function changeAdminStatusNoMqtt(threadID, adminID, adminStatus) {
7
+ if (getType(threadID) !== "String") throw { error: "changeAdminStatus: threadID must be a string" };
8
+ if (getType(adminID) !== "String" && getType(adminID) !== "Array") throw { error: "changeAdminStatus: adminID must be a string or an array" };
9
+ if (getType(adminStatus) !== "Boolean") throw { error: "changeAdminStatus: adminStatus must be true or false" };
10
+ let wsContent = {
11
+ request_id: 1,
12
+ type: 3,
13
+ payload: {
14
+ version_id: '3816854585040595',
15
+ tasks: [],
16
+ epoch_id: generateOfflineThreadingID(),
17
+ data_trace_id: null
18
+ },
19
+ app_id: '772021112871879'
20
+ }
21
+ if (getType(adminID) === "Array") {
22
+ for (let i = 0; i < adminID.length; i++) {
23
+ wsContent.payload.tasks.push({
24
+ label: '25',
25
+ payload: JSON.stringify({ thread_key: threadID, contact_id: adminID[i], is_admin: adminStatus }),
26
+ queue_name: 'admin_status',
27
+ task_id: i + 1,
28
+ failure_count: null
29
+ });
30
+ }
31
+ } else {
32
+ wsContent.payload.tasks.push({
33
+ label: '25',
34
+ payload: JSON.stringify({ thread_key: threadID, contact_id: adminID, is_admin: adminStatus }),
35
+ queue_name: 'admin_status',
36
+ task_id: 1,
37
+ failure_count: null
11
38
  });
12
39
  }
13
-
14
- if (utils.getType(adminIDs) === "String") {
15
- adminIDs = [adminIDs];
40
+ wsContent.payload = JSON.stringify(wsContent.payload);
41
+ return new Promise((resolve, reject) => ctx.mqttClient && ctx.mqttClient.publish('/ls_req', JSON.stringify(wsContent), {}, (err, _packet) => err ? reject(err) : resolve()));
42
+ };
43
+ function changeAdminStatusMqtt(threadID, adminID, adminStatus) {
44
+ if (!ctx.mqttClient) {
45
+ throw new Error("Not connected to MQTT");
16
46
  }
17
-
18
- if (utils.getType(adminIDs) !== "Array") {
19
- throw new utils.CustomError({
20
- error: "changeAdminStatus: adminIDs must be an array or string"
21
- });
47
+ if (getType(threadID) !== "String") {
48
+ throw { error: "changeAdminStatus: threadID must be a string" };
22
49
  }
23
-
24
- if (utils.getType(adminStatus) !== "Boolean") {
25
- throw new utils.CustomError({
26
- error: "changeAdminStatus: adminStatus must be a string"
27
- });
50
+ if (getType(adminID) !== "String" && getType(adminID) !== "Array") {
51
+ throw { error: "changeAdminStatus: adminID must be a string or an array" };
28
52
  }
29
-
30
- let resolveFunc = function() {};
31
- let rejectFunc = function() {};
32
- const returnPromise = new Promise(function(resolve, reject) {
33
- resolveFunc = resolve;
34
- rejectFunc = reject;
35
- });
36
-
37
- if (!callback) {
38
- callback = function(err) {
39
- if (err) {
40
- return rejectFunc(err);
41
- }
42
- resolveFunc();
43
- };
53
+ if (getType(adminStatus) !== "Boolean") {
54
+ throw { error: "changeAdminStatus: adminStatus must be true or false" };
44
55
  }
45
-
46
- if (
47
- utils.getType(callback) !== "Function" &&
48
- utils.getType(callback) !== "AsyncFunction"
49
- ) {
50
- throw new utils.CustomError({
51
- error: "changeAdminStatus: callback is not a function"
56
+ const tasks = [];
57
+ const isAdmin = adminStatus ? 1 : 0;
58
+ const epochID = generateOfflineThreadingID();
59
+ if (getType(adminID) === "Array") {
60
+ adminID.forEach((id, index) => {
61
+ tasks.push({
62
+ failure_count: null,
63
+ label: "25",
64
+ payload: JSON.stringify({
65
+ thread_key: threadID,
66
+ contact_id: id,
67
+ is_admin: isAdmin
68
+ }),
69
+ queue_name: "admin_status",
70
+ task_id: index + 1
71
+ });
72
+ });
73
+ } else {
74
+ tasks.push({
75
+ failure_count: null,
76
+ label: "25",
77
+ payload: JSON.stringify({
78
+ thread_key: threadID,
79
+ contact_id: adminID,
80
+ is_admin: isAdmin
81
+ }),
82
+ queue_name: "admin_status",
83
+ task_id: 1
52
84
  });
53
85
  }
54
-
55
- const form = {
56
- thread_fbid: threadID
57
- };
58
-
59
- let i = 0;
60
- for (const u of adminIDs) {
61
- form[`admin_ids[${i++}]`] = u;
62
- }
63
- form["add"] = adminStatus;
64
-
65
- defaultFuncs
66
- .post(
67
- "https://www.facebook.com/messaging/save_admins/?dpr=1",
68
- ctx.jar,
69
- form
70
- )
71
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
72
- .then(function(resData) {
73
- if (resData.error) {
74
- switch (resData.error) {
75
- case 1976004:
76
- throw new utils.CustomError({
77
- error: "Cannot alter admin status: you are not an admin.",
78
- rawResponse: resData
79
- });
80
- case 1357031:
81
- throw new utils.CustomError({
82
- error:
83
- "Cannot alter admin status: this thread is not a group chat.",
84
- rawResponse: resData
85
- });
86
- default:
87
- throw new utils.CustomError({
88
- error: "Cannot alter admin status: unknown error.",
89
- rawResponse: resData
90
- });
86
+ let count_req = 0
87
+ const form = JSON.stringify({
88
+ app_id: "2220391788200892",
89
+ payload: JSON.stringify({
90
+ epoch_id: epochID,
91
+ tasks: tasks,
92
+ version_id: "8798795233522156"
93
+ }),
94
+ request_id: ++count_req,
95
+ type: 3
96
+ });
97
+ return new Promise((resolve, reject) => {
98
+ if (ctx.mqttClient) {
99
+ ctx.mqttClient.publish("/ls_req", form, {}, (err, _packet) => {
100
+ if (err) {
101
+ reject(err);
102
+ } else {
103
+ resolve();
91
104
  }
92
- }
93
-
94
- callback();
95
- })
96
- .catch(function(err) {
97
- log.error("changeAdminStatus", err);
98
- return callback(err);
99
- });
100
-
101
- return returnPromise;
105
+ });
106
+ } else {
107
+ reject(new Error("MQTT client is not available"));
108
+ }
109
+ });
110
+ };
111
+ return function changeAdminStatus(threadID, adminID, adminStatus) {
112
+ if (ctx.mqttClient) {
113
+ try {
114
+ changeAdminStatusMqtt(threadID, adminID, adminStatus);
115
+ } catch (e) {
116
+ changeAdminStatusNoMqtt(threadID, adminID, adminStatus);
117
+ }
118
+ } else {
119
+ changeAdminStatusNoMqtt(threadID, adminID, adminStatus);
120
+ }
102
121
  };
103
122
  };
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { formatID } = require("../../utils/format");
5
+ const { parseAndCheckLogin } = require("../../utils/client");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function changeArchivedStatus(threadOrThreads, archive, callback) {
8
8
  let resolveFunc = function() {};
@@ -23,12 +23,12 @@ module.exports = function(defaultFuncs, api, ctx) {
23
23
 
24
24
  const form = {};
25
25
 
26
- if (utils.getType(threadOrThreads) === "Array") {
26
+ if (Array.isArray(threadOrThreads)) {
27
27
  for (let i = 0; i < threadOrThreads.length; i++) {
28
- form["ids[" + threadOrThreads[i] + "]"] = archive;
28
+ form["ids[" + formatID(threadOrThreads[i]) + "]"] = archive;
29
29
  }
30
30
  } else {
31
- form["ids[" + threadOrThreads + "]"] = archive;
31
+ form["ids[" + formatID(threadOrThreads) + "]"] = archive;
32
32
  }
33
33
 
34
34
  defaultFuncs
@@ -37,7 +37,7 @@ module.exports = function(defaultFuncs, api, ctx) {
37
37
  ctx.jar,
38
38
  form
39
39
  )
40
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
40
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
41
41
  .then(function(resData) {
42
42
  if (resData.error) {
43
43
  throw resData;
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin, saveCookies } = require("../../utils/client");
6
5
  module.exports = function(defaultFuncs, api, ctx) {
7
6
  return function changeBlockedStatus(userID, block, callback) {
8
7
  let resolveFunc = function() {};
@@ -31,8 +30,8 @@ module.exports = function(defaultFuncs, api, ctx) {
31
30
  fbid: userID
32
31
  }
33
32
  )
34
- .then(utils.saveCookies(ctx.jar))
35
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
33
+ .then(saveCookies(ctx.jar))
34
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
36
35
  .then(function(resData) {
37
36
  if (resData.error) {
38
37
  throw resData;