@dongdev/fca-unofficial 0.0.4 → 0.0.6

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 (76) hide show
  1. package/.travis.yml +6 -6
  2. package/CHANGELOG.md +1 -1
  3. package/DOCS.md +1738 -1738
  4. package/LICENSE-MIT +21 -21
  5. package/README.md +219 -219
  6. package/index.js +307 -571
  7. package/lib/login.js +0 -0
  8. package/package.json +6 -5
  9. package/src/addExternalModule.js +19 -15
  10. package/src/addUserToGroup.js +113 -77
  11. package/src/changeAdminStatus.js +79 -47
  12. package/src/changeArchivedStatus.js +55 -41
  13. package/src/changeAvatar.js +126 -0
  14. package/src/changeBio.js +66 -54
  15. package/src/changeBlockedStatus.js +40 -29
  16. package/src/changeGroupImage.js +127 -101
  17. package/src/changeNickname.js +50 -36
  18. package/src/changeThreadColor.js +65 -61
  19. package/src/changeThreadEmoji.js +55 -41
  20. package/src/createNewGroup.js +86 -70
  21. package/src/createPoll.js +71 -59
  22. package/src/deleteMessage.js +56 -44
  23. package/src/deleteThread.js +56 -42
  24. package/src/forwardAttachment.js +60 -47
  25. package/src/getCurrentUserID.js +7 -7
  26. package/src/getEmojiUrl.js +29 -27
  27. package/src/getFriendsList.js +83 -73
  28. package/src/getMessage.js +796 -0
  29. package/src/getThreadHistory.js +666 -537
  30. package/src/getThreadInfo.js +232 -171
  31. package/src/getThreadList.js +192 -213
  32. package/src/getThreadPictures.js +79 -59
  33. package/src/getUserID.js +66 -61
  34. package/src/getUserInfo.js +74 -66
  35. package/src/handleFriendRequest.js +61 -46
  36. package/src/handleMessageRequest.js +65 -47
  37. package/src/httpGet.js +52 -44
  38. package/src/httpPost.js +52 -43
  39. package/src/httpPostFormData.js +63 -0
  40. package/src/listenMqtt.js +969 -709
  41. package/src/logout.js +62 -55
  42. package/src/markAsDelivered.js +58 -47
  43. package/src/markAsRead.js +80 -70
  44. package/src/markAsReadAll.js +49 -39
  45. package/src/markAsSeen.js +59 -48
  46. package/src/muteThread.js +52 -45
  47. package/src/postFormData.js +46 -0
  48. package/src/refreshFb_dtsg.js +81 -0
  49. package/src/removeUserFromGroup.js +79 -45
  50. package/src/resolvePhotoUrl.js +45 -36
  51. package/src/searchForThread.js +53 -42
  52. package/src/sendMessage.js +328 -328
  53. package/src/sendMessageMqtt.js +316 -0
  54. package/src/sendTypingIndicator.js +103 -70
  55. package/src/setMessageReaction.js +106 -98
  56. package/src/setPostReaction.js +102 -95
  57. package/src/setTitle.js +86 -70
  58. package/src/threadColors.js +131 -41
  59. package/src/unfriend.js +52 -42
  60. package/src/unsendMessage.js +49 -39
  61. package/src/uploadAttachment.js +95 -0
  62. package/utils.js +1501 -1196
  63. package/.gitattributes +0 -2
  64. package/src/Screenshot.js +0 -83
  65. package/src/changeAvt.js +0 -85
  66. package/src/getThreadHistoryDeprecated.js +0 -71
  67. package/src/getThreadInfoDeprecated.js +0 -56
  68. package/src/getThreadListDeprecated.js +0 -46
  69. package/src/shareContact.js +0 -46
  70. package/test/data/shareAttach.js +0 -146
  71. package/test/data/something.mov +0 -0
  72. package/test/data/test.png +0 -0
  73. package/test/data/test.txt +0 -7
  74. package/test/example-config.json +0 -18
  75. package/test/test-page.js +0 -140
  76. package/test/test.js +0 -385
package/src/changeBio.js CHANGED
@@ -1,65 +1,77 @@
1
1
  "use strict";
2
2
 
3
- var utils = require("../utils");
4
- var log = require("npmlog");
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
5
 
6
6
  module.exports = function (defaultFuncs, api, ctx) {
7
- return function changeBio(bio, publish, callback) {
8
- var resolveFunc = function () { };
9
- var rejectFunc = function () { };
10
- var returnPromise = new Promise(function (resolve, reject) {
11
- resolveFunc = resolve;
12
- rejectFunc = reject;
13
- });
7
+ return function changeBio(bio, publish, 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
14
 
15
- if (!callback) {
16
- if (utils.getType(publish) == "Function" || utils.getType(publish) == "AsyncFunction") callback = publish;
17
- else {
18
- callback = function (err) {
19
- if (err) return rejectFunc(err);
20
- resolveFunc();
21
- };
22
- }
23
- }
15
+ if (!callback) {
16
+ if (utils.getType(publish) == "Function" || utils.getType(publish) == "AsyncFunction") {
17
+ callback = publish;
18
+ } else {
19
+ callback = function (err) {
20
+ if (err) {
21
+ return rejectFunc(err);
22
+ }
23
+ resolveFunc();
24
+ };
25
+ }
26
+ }
24
27
 
25
- if (utils.getType(publish) != "Boolean") publish = false;
26
- if (utils.getType(bio) != "String") {
27
- bio = "";
28
- publish = false;
29
- }
28
+ if (utils.getType(publish) != "Boolean") {
29
+ publish = false;
30
+ }
30
31
 
31
- var form = {
32
- fb_api_caller_class: "RelayModern",
33
- fb_api_req_friendly_name: "ProfileCometSetBioMutation",
34
- // This doc_is is valid as of May 23, 2020
35
- doc_id: "2725043627607610",
36
- variables: JSON.stringify({
37
- input: {
38
- bio: bio,
39
- publish_bio_feed_story: publish,
40
- actor_id: ctx.userID,
41
- client_mutation_id: Math.round(Math.random() * 1024).toString()
42
- },
43
- hasProfileTileViewID: false,
44
- profileTileViewID: null,
45
- scale: 1
46
- }),
47
- av: ctx.userID
48
- };
32
+ if (utils.getType(bio) != "String") {
33
+ bio = "";
34
+ publish = false;
35
+ }
49
36
 
50
- defaultFuncs
51
- .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
52
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
53
- .then(function (resData) {
54
- if (resData.errors) throw resData;
37
+ const form = {
38
+ fb_api_caller_class: "RelayModern",
39
+ fb_api_req_friendly_name: "ProfileCometSetBioMutation",
40
+ // This doc_is is valid as of May 23, 2020
41
+ doc_id: "2725043627607610",
42
+ variables: JSON.stringify({
43
+ input: {
44
+ bio: bio,
45
+ publish_bio_feed_story: publish,
46
+ actor_id: ctx.i_userID || ctx.userID,
47
+ client_mutation_id: Math.round(Math.random() * 1024).toString()
48
+ },
49
+ hasProfileTileViewID: false,
50
+ profileTileViewID: null,
51
+ scale: 1
52
+ }),
53
+ av: ctx.i_userID || ctx.userID
54
+ };
55
55
 
56
- return callback();
57
- })
58
- .catch(function (err) {
59
- log.error("changeBio", err);
60
- return callback(err);
61
- });
56
+ defaultFuncs
57
+ .post(
58
+ "https://www.facebook.com/api/graphql/",
59
+ ctx.jar,
60
+ form
61
+ )
62
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
63
+ .then(function (resData) {
64
+ if (resData.errors) {
65
+ throw resData;
66
+ }
62
67
 
63
- return returnPromise;
64
- };
68
+ return callback();
69
+ })
70
+ .catch(function (err) {
71
+ log.error("changeBio", err);
72
+ return callback(err);
73
+ });
74
+
75
+ return returnPromise;
76
+ };
65
77
  };
@@ -1,36 +1,47 @@
1
1
  "use strict";
2
2
 
3
- var utils = require("../utils");
4
- var log = require("npmlog");
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
5
 
6
6
  module.exports = function (defaultFuncs, api, ctx) {
7
- return function changeBlockedStatus(userID, block, callback) {
8
- var resolveFunc = function () { };
9
- var rejectFunc = function () { };
10
- var returnPromise = new Promise(function (resolve, reject) {
11
- resolveFunc = resolve;
12
- rejectFunc = reject;
13
- });
7
+ return function changeBlockedStatus(userID, block, 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
14
 
15
- if (!callback) {
16
- callback = function (err) {
17
- if (err) return rejectFunc(err);
18
- resolveFunc();
19
- };
20
- }
15
+ if (!callback) {
16
+ callback = function (err) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc();
21
+ };
22
+ }
21
23
 
22
- defaultFuncs
23
- .post(`https://www.facebook.com/messaging/${block ? "" : "un"}block_messages/`, ctx.jar, { fbid: userID })
24
- .then(utils.saveCookies(ctx.jar))
25
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
26
- .then(function (resData) {
27
- if (resData.error) throw resData;
28
- return callback();
29
- })
30
- .catch(function (err) {
31
- log.error("changeBlockedStatus", err);
32
- return callback(err);
33
- });
34
- return returnPromise;
35
- };
24
+ defaultFuncs
25
+ .post(
26
+ `https://www.facebook.com/messaging/${block ? "" : "un"}block_messages/`,
27
+ ctx.jar,
28
+ {
29
+ fbid: userID
30
+ }
31
+ )
32
+ .then(utils.saveCookies(ctx.jar))
33
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
34
+ .then(function (resData) {
35
+ if (resData.error) {
36
+ throw resData;
37
+ }
38
+
39
+ return callback();
40
+ })
41
+ .catch(function (err) {
42
+ log.error("changeBlockedStatus", err);
43
+ return callback(err);
44
+ });
45
+ return returnPromise;
46
+ };
36
47
  };
@@ -1,106 +1,132 @@
1
1
  "use strict";
2
2
 
3
- var utils = require("../utils");
4
- var log = require("npmlog");
5
- var bluebird = require("bluebird");
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
6
5
 
7
6
  module.exports = function (defaultFuncs, api, ctx) {
8
- function handleUpload(image, callback) {
9
- var uploads = [];
10
-
11
- var form = {
12
- images_only: "true",
13
- "attachment[]": image
14
- };
15
-
16
- uploads.push(
17
- defaultFuncs
18
- .postFormData("https://upload.facebook.com/ajax/mercury/upload.php", ctx.jar, form, {})
19
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
20
- .then(function (resData) {
21
- if (resData.error) throw resData;
22
-
23
- return resData.payload.metadata[0];
24
- })
25
- );
26
-
27
- // resolve all promises
28
- bluebird
29
- .all(uploads)
30
- .then(resData => callback(null, resData))
31
- .catch(function (err) {
32
- log.error("handleUpload", err);
33
- return callback(err);
34
- });
35
- }
36
-
37
- return function changeGroupImage(image, threadID, callback) {
38
- if (!callback && (utils.getType(threadID) === "Function" || utils.getType(threadID) === "AsyncFunction")) throw { error: "please pass a threadID as a second argument." };
39
-
40
- var resolveFunc = function () { };
41
- var rejectFunc = function () { };
42
- var returnPromise = new Promise(function (resolve, reject) {
43
- resolveFunc = resolve;
44
- rejectFunc = reject;
45
- });
46
-
47
- if (!callback) {
48
- callback = function (err) {
49
- if (err) return rejectFunc(err);
50
- resolveFunc();
51
- };
52
- }
53
-
54
- var messageAndOTID = utils.generateOfflineThreadingID();
55
- var form = {
56
- client: "mercury",
57
- action_type: "ma-type:log-message",
58
- author: "fbid:" + ctx.userID,
59
- author_email: "",
60
- ephemeral_ttl_mode: "0",
61
- is_filtered_content: false,
62
- is_filtered_content_account: false,
63
- is_filtered_content_bh: false,
64
- is_filtered_content_invalid_app: false,
65
- is_filtered_content_quasar: false,
66
- is_forward: false,
67
- is_spoof_warning: false,
68
- is_unread: false,
69
- log_message_type: "log:thread-image",
70
- manual_retry_cnt: "0",
71
- message_id: messageAndOTID,
72
- offline_threading_id: messageAndOTID,
73
- source: "source:chat:web",
74
- "source_tags[0]": "source:chat",
75
- status: "0",
76
- thread_fbid: threadID,
77
- thread_id: "",
78
- timestamp: Date.now(),
79
- timestamp_absolute: "Today",
80
- timestamp_relative: utils.generateTimestampRelative(),
81
- timestamp_time_passed: "0"
82
- };
83
-
84
- handleUpload(image, function (err, payload) {
85
- if (err) return callback(err);
86
-
87
- form["thread_image_id"] = payload[0]["image_id"];
88
- form["thread_id"] = threadID;
89
-
90
- defaultFuncs
91
- .post("https://www.facebook.com/messaging/set_thread_image/", ctx.jar, form)
92
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
93
- .then(function (resData) {
94
- // check for errors here
95
- if (resData.error) throw resData;
96
- return callback();
97
- })
98
- .catch(function (err) {
99
- log.error("changeGroupImage", err);
100
- return callback(err);
101
- });
102
- });
103
-
104
- return returnPromise;
105
- };
7
+ function handleUpload(image, callback) {
8
+ const uploads = [];
9
+
10
+ const form = {
11
+ images_only: "true",
12
+ "attachment[]": image
13
+ };
14
+
15
+ uploads.push(
16
+ defaultFuncs
17
+ .postFormData(
18
+ "https://upload.facebook.com/ajax/mercury/upload.php",
19
+ ctx.jar,
20
+ form,
21
+ {}
22
+ )
23
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
24
+ .then(function (resData) {
25
+ if (resData.error) {
26
+ throw resData;
27
+ }
28
+
29
+ return resData.payload.metadata[0];
30
+ })
31
+ );
32
+
33
+ // resolve all promises
34
+ Promise
35
+ .all(uploads)
36
+ .then(function (resData) {
37
+ callback(null, resData);
38
+ })
39
+ .catch(function (err) {
40
+ log.error("handleUpload", err);
41
+ return callback(err);
42
+ });
43
+ }
44
+
45
+ return function changeGroupImage(image, threadID, callback) {
46
+ if (
47
+ !callback &&
48
+ (utils.getType(threadID) === "Function" ||
49
+ utils.getType(threadID) === "AsyncFunction")
50
+ ) {
51
+ throw { error: "please pass a threadID as a second argument." };
52
+ }
53
+
54
+ if (!utils.isReadableStream(image)) {
55
+ throw { error: "please pass a readable stream as a first argument." };
56
+ }
57
+
58
+ let resolveFunc = function () { };
59
+ let rejectFunc = function () { };
60
+ const returnPromise = new Promise(function (resolve, reject) {
61
+ resolveFunc = resolve;
62
+ rejectFunc = reject;
63
+ });
64
+
65
+ if (!callback) {
66
+ callback = function (err) {
67
+ if (err) {
68
+ return rejectFunc(err);
69
+ }
70
+ resolveFunc();
71
+ };
72
+ }
73
+
74
+ const messageAndOTID = utils.generateOfflineThreadingID();
75
+ const form = {
76
+ client: "mercury",
77
+ action_type: "ma-type:log-message",
78
+ author: "fbid:" + (ctx.i_userID || ctx.userID),
79
+ author_email: "",
80
+ ephemeral_ttl_mode: "0",
81
+ is_filtered_content: false,
82
+ is_filtered_content_account: false,
83
+ is_filtered_content_bh: false,
84
+ is_filtered_content_invalid_app: false,
85
+ is_filtered_content_quasar: false,
86
+ is_forward: false,
87
+ is_spoof_warning: false,
88
+ is_unread: false,
89
+ log_message_type: "log:thread-image",
90
+ manual_retry_cnt: "0",
91
+ message_id: messageAndOTID,
92
+ offline_threading_id: messageAndOTID,
93
+ source: "source:chat:web",
94
+ "source_tags[0]": "source:chat",
95
+ status: "0",
96
+ thread_fbid: threadID,
97
+ thread_id: "",
98
+ timestamp: Date.now(),
99
+ timestamp_absolute: "Today",
100
+ timestamp_relative: utils.generateTimestampRelative(),
101
+ timestamp_time_passed: "0"
102
+ };
103
+
104
+ handleUpload(image, function (err, payload) {
105
+ if (err) {
106
+ return callback(err);
107
+ }
108
+
109
+ form["thread_image_id"] = payload[0]["image_id"];
110
+ form["thread_id"] = threadID;
111
+
112
+ defaultFuncs
113
+ .post("https://www.facebook.com/messaging/set_thread_image/", ctx.jar, form)
114
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
115
+ .then(function (resData) {
116
+ // check for errors here
117
+
118
+ if (resData.error) {
119
+ throw resData;
120
+ }
121
+
122
+ return callback();
123
+ })
124
+ .catch(function (err) {
125
+ log.error("changeGroupImage", err);
126
+ return callback(err);
127
+ });
128
+ });
129
+
130
+ return returnPromise;
131
+ };
106
132
  };
@@ -1,45 +1,59 @@
1
1
  "use strict";
2
2
 
3
- var utils = require("../utils");
4
- var log = require("npmlog");
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
5
 
6
6
  module.exports = function (defaultFuncs, api, ctx) {
7
- return function changeNickname(nickname, threadID, participantID, callback) {
8
- var resolveFunc = function () { };
9
- var rejectFunc = function () { };
10
- var returnPromise = new Promise(function (resolve, reject) {
11
- resolveFunc = resolve;
12
- rejectFunc = reject;
13
- });
14
- if (!callback) {
15
- callback = function (err) {
16
- if (err) return rejectFunc(err);
17
- resolveFunc();
18
- };
19
- }
7
+ return function changeNickname(nickname, threadID, participantID, 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
+ if (!callback) {
15
+ callback = function (err) {
16
+ if (err) {
17
+ return rejectFunc(err);
18
+ }
19
+ resolveFunc();
20
+ };
21
+ }
20
22
 
21
- var form = {
22
- nickname: nickname,
23
- participant_id: participantID,
24
- thread_or_other_fbid: threadID
25
- };
23
+ const form = {
24
+ nickname: nickname,
25
+ participant_id: participantID,
26
+ thread_or_other_fbid: threadID
27
+ };
26
28
 
27
- defaultFuncs
28
- .post("https://www.facebook.com/messaging/save_thread_nickname/?source=thread_settings&dpr=1", ctx.jar, form)
29
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
30
- .then(function (resData) {
31
- if (resData.error === 1545014) throw { error: "Trying to change nickname of user isn't in thread" };
32
- if (resData.error === 1357031) throw { error: "Trying to change user nickname of a thread that doesn't exist. Have at least one message in the thread before trying to change the user nickname." };
29
+ defaultFuncs
30
+ .post(
31
+ "https://www.facebook.com/messaging/save_thread_nickname/?source=thread_settings&dpr=1",
32
+ ctx.jar,
33
+ form
34
+ )
35
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
36
+ .then(function (resData) {
37
+ if (resData.error === 1545014) {
38
+ throw { error: "Trying to change nickname of user isn't in thread" };
39
+ }
40
+ if (resData.error === 1357031) {
41
+ throw {
42
+ error:
43
+ "Trying to change user nickname of a thread that doesn't exist. Have at least one message in the thread before trying to change the user nickname."
44
+ };
45
+ }
46
+ if (resData.error) {
47
+ throw resData;
48
+ }
33
49
 
34
- if (resData.error) throw resData;
50
+ return callback();
51
+ })
52
+ .catch(function (err) {
53
+ log.error("changeNickname", err);
54
+ return callback(err);
55
+ });
35
56
 
36
- return callback();
37
- })
38
- .catch(function (err) {
39
- log.error("changeNickname", err);
40
- return callback(err);
41
- });
42
-
43
- return returnPromise;
44
- };
57
+ return returnPromise;
58
+ };
45
59
  };
@@ -1,61 +1,65 @@
1
- "use strict";
2
-
3
- var utils = require("../utils");
4
- var log = require("npmlog");
5
-
6
- module.exports = function (defaultFuncs, api, ctx) {
7
- return function changeThreadColor(color, threadID, callback) {
8
- var resolveFunc = function () { };
9
- var rejectFunc = function () { };
10
- var returnPromise = new Promise(function (resolve, reject) {
11
- resolveFunc = resolve;
12
- rejectFunc = reject;
13
- });
14
-
15
- if (!callback) {
16
- callback = function (err) {
17
- if (err) return rejectFunc(err);
18
- resolveFunc(err);
19
- };
20
- }
21
-
22
- var validatedColor = color !== null ? color.toLowerCase() : color; // API only accepts lowercase letters in hex string
23
- var colorList = Object.keys(api.threadColors).map(function (name) {
24
- return api.threadColors[name];
25
- });
26
- if (!colorList.includes(validatedColor)) throw { error: "The color you are trying to use is not a valid thread color. Use api.threadColors to find acceptable values." };
27
-
28
- var form = {
29
- dpr: 1,
30
- queries: JSON.stringify({
31
- o0: {
32
- //This doc_id is valid as of January 31, 2020
33
- doc_id: "1727493033983591",
34
- query_params: {
35
- data: {
36
- actor_id: ctx.userID,
37
- client_mutation_id: "0",
38
- source: "SETTINGS",
39
- theme_id: validatedColor,
40
- thread_id: threadID
41
- }
42
- }
43
- }
44
- })
45
- };
46
-
47
- defaultFuncs
48
- .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
49
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
50
- .then(function (resData) {
51
- if (resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
52
- return callback();
53
- })
54
- .catch(function (err) {
55
- log.error("changeThreadColor", err);
56
- return callback(err);
57
- });
58
-
59
- return returnPromise;
60
- };
61
- };
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 changeThreadColor(color, threadID, 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) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(err);
21
+ };
22
+ }
23
+
24
+ if (!isNaN(color)) {
25
+ color = color.toString();
26
+ }
27
+ const validatedColor = color !== null ? color.toLowerCase() : color; // API only accepts lowercase letters in hex string
28
+
29
+ const form = {
30
+ dpr: 1,
31
+ queries: JSON.stringify({
32
+ o0: {
33
+ //This doc_id is valid as of January 31, 2020
34
+ doc_id: "1727493033983591",
35
+ query_params: {
36
+ data: {
37
+ actor_id: ctx.i_userID || ctx.userID,
38
+ client_mutation_id: "0",
39
+ source: "SETTINGS",
40
+ theme_id: validatedColor,
41
+ thread_id: threadID
42
+ }
43
+ }
44
+ }
45
+ })
46
+ };
47
+
48
+ defaultFuncs
49
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
50
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
51
+ .then(function (resData) {
52
+ if (resData[resData.length - 1].error_results > 0) {
53
+ throw new utils.CustomError(resData[0].o0.errors);
54
+ }
55
+
56
+ return callback();
57
+ })
58
+ .catch(function (err) {
59
+ log.error("changeThreadColor", err);
60
+ return callback(err);
61
+ });
62
+
63
+ return returnPromise;
64
+ };
65
+ };