@dongdev/fca-unofficial 1.0.20 → 2.0.0

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 (128) hide show
  1. package/.gitattributes +1 -0
  2. package/CHANGELOG.md +30 -30
  3. package/DOCS.md +727 -592
  4. package/README.md +94 -97
  5. package/func/logger.js +112 -0
  6. package/html.html +474 -0
  7. package/index.js +1 -379
  8. package/module/config.js +26 -0
  9. package/module/login.js +45 -0
  10. package/module/loginHelper.js +634 -0
  11. package/module/options.js +49 -0
  12. package/package.json +6 -39
  13. package/src/api/action/addExternalModule.js +25 -0
  14. package/src/api/action/changeAvatar.js +136 -0
  15. package/src/api/action/changeBio.js +76 -0
  16. package/src/api/action/getCurrentUserID.js +7 -0
  17. package/src/api/action/handleFriendRequest.js +57 -0
  18. package/src/api/action/logout.js +75 -0
  19. package/src/{refreshFb_dtsg.js → api/action/refreshFb_dtsg.js} +8 -8
  20. package/src/api/action/setPostReaction.js +107 -0
  21. package/src/api/action/unfriend.js +55 -0
  22. package/src/api/http/httpGet.js +65 -0
  23. package/src/api/http/httpPost.js +65 -0
  24. package/src/{postFormData.js → api/http/postFormData.js} +10 -10
  25. package/src/api/messaging/addUserToGroup.js +69 -0
  26. package/src/api/messaging/changeAdminStatus.js +103 -0
  27. package/src/api/messaging/changeArchivedStatus.js +55 -0
  28. package/src/api/messaging/changeBlockedStatus.js +49 -0
  29. package/src/api/messaging/changeGroupImage.js +135 -0
  30. package/src/api/messaging/changeNickname.js +59 -0
  31. package/src/api/messaging/changeThreadColor.js +65 -0
  32. package/src/api/messaging/createNewGroup.js +88 -0
  33. package/src/api/messaging/createPoll.js +70 -0
  34. package/src/api/messaging/deleteMessage.js +56 -0
  35. package/src/api/messaging/deleteThread.js +56 -0
  36. package/src/api/messaging/forwardAttachment.js +60 -0
  37. package/src/api/messaging/getEmojiUrl.js +29 -0
  38. package/src/api/messaging/getFriendsList.js +83 -0
  39. package/src/api/messaging/getMessage.js +834 -0
  40. package/src/api/messaging/getThreadHistory.js +681 -0
  41. package/src/api/messaging/handleMessageRequest.js +65 -0
  42. package/src/api/messaging/markAsDelivered.js +57 -0
  43. package/src/api/messaging/markAsRead.js +88 -0
  44. package/src/api/messaging/markAsReadAll.js +50 -0
  45. package/src/api/messaging/markAsSeen.js +61 -0
  46. package/src/api/messaging/muteThread.js +51 -0
  47. package/src/api/messaging/removeUserFromGroup.js +79 -0
  48. package/src/api/messaging/resolvePhotoUrl.js +44 -0
  49. package/src/api/messaging/searchForThread.js +53 -0
  50. package/src/api/messaging/sendMessage.js +306 -0
  51. package/src/api/messaging/sendMessageMqtt.js +321 -0
  52. package/src/api/messaging/sendTypingIndicator.js +110 -0
  53. package/src/{setMessageReaction.js → api/messaging/setMessageReaction.js} +20 -20
  54. package/src/api/messaging/setTitle.js +90 -0
  55. package/src/api/messaging/shareContact.js +51 -0
  56. package/src/api/messaging/threadColors.js +131 -0
  57. package/src/api/messaging/unsendMessage.js +44 -0
  58. package/src/api/messaging/uploadAttachment.js +93 -0
  59. package/src/api/socket/detail/buildStream.js +100 -0
  60. package/src/{listenMqtt.js → api/socket/listenMqtt.js} +122 -206
  61. package/src/api/threads/changeThreadEmoji.js +55 -0
  62. package/src/api/threads/getThreadInfo.js +572 -0
  63. package/src/{getThreadList.js → api/threads/getThreadList.js} +110 -54
  64. package/src/api/threads/getThreadPictures.js +79 -0
  65. package/src/api/users/getUserID.js +66 -0
  66. package/src/api/users/getUserInfo.js +88 -0
  67. package/src/core/sendReqMqtt.js +63 -0
  68. package/{lib → src}/database/models/index.js +12 -10
  69. package/{lib → src}/database/models/thread.js +5 -5
  70. package/{lib → src}/database/threadData.js +19 -14
  71. package/src/utils/client.js +159 -0
  72. package/src/utils/constants.js +13 -0
  73. package/src/utils/format.js +60 -0
  74. package/src/utils/headers.js +41 -0
  75. package/src/utils/index.js +1497 -0
  76. package/src/utils/request.js +147 -0
  77. package/lib/logger.js +0 -96
  78. package/src/addExternalModule.js +0 -19
  79. package/src/addUserToGroup.js +0 -113
  80. package/src/changeAdminStatus.js +0 -79
  81. package/src/changeArchivedStatus.js +0 -55
  82. package/src/changeAvatar.js +0 -126
  83. package/src/changeBio.js +0 -77
  84. package/src/changeBlockedStatus.js +0 -47
  85. package/src/changeGroupImage.js +0 -132
  86. package/src/changeNickname.js +0 -59
  87. package/src/changeThreadColor.js +0 -65
  88. package/src/changeThreadEmoji.js +0 -55
  89. package/src/createNewGroup.js +0 -86
  90. package/src/createPoll.js +0 -71
  91. package/src/deleteMessage.js +0 -56
  92. package/src/deleteThread.js +0 -56
  93. package/src/forwardAttachment.js +0 -60
  94. package/src/getCurrentUserID.js +0 -7
  95. package/src/getEmojiUrl.js +0 -29
  96. package/src/getFriendsList.js +0 -83
  97. package/src/getMessage.js +0 -796
  98. package/src/getThreadHistory.js +0 -666
  99. package/src/getThreadInfo.js +0 -535
  100. package/src/getThreadPictures.js +0 -79
  101. package/src/getUserID.js +0 -66
  102. package/src/getUserInfo.js +0 -80
  103. package/src/handleFriendRequest.js +0 -61
  104. package/src/handleMessageRequest.js +0 -65
  105. package/src/httpGet.js +0 -57
  106. package/src/httpPost.js +0 -57
  107. package/src/httpPostFormData.js +0 -63
  108. package/src/logout.js +0 -75
  109. package/src/markAsDelivered.js +0 -58
  110. package/src/markAsRead.js +0 -80
  111. package/src/markAsReadAll.js +0 -50
  112. package/src/markAsSeen.js +0 -59
  113. package/src/muteThread.js +0 -52
  114. package/src/removeUserFromGroup.js +0 -79
  115. package/src/resolvePhotoUrl.js +0 -45
  116. package/src/searchForThread.js +0 -53
  117. package/src/sendMessage.js +0 -328
  118. package/src/sendMessageMqtt.js +0 -316
  119. package/src/sendTypingIndicator.js +0 -103
  120. package/src/setPostReaction.js +0 -109
  121. package/src/setTitle.js +0 -86
  122. package/src/shareContact.js +0 -49
  123. package/src/threadColors.js +0 -131
  124. package/src/unfriend.js +0 -52
  125. package/src/unsendMessage.js +0 -49
  126. package/src/uploadAttachment.js +0 -95
  127. package/utils.js +0 -1387
  128. /package/{lib → func}/login.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dongdev/fca-unofficial",
3
- "version": "1.0.20",
3
+ "version": "2.0.0",
4
4
  "description": "A Facebook chat API without XMPP, will not be deprecated after April 30th, 2015.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -10,7 +10,8 @@
10
10
  "author": "Avery, David, Maude, Benjamin, UIRI, DongDev",
11
11
  "license": "MIT",
12
12
  "dependencies": {
13
- "axios": "^1.8.4",
13
+ "axios": "^1.12.2",
14
+ "axios-cookiejar-support": "^6.0.4",
14
15
  "bluebird": "^3.7.2",
15
16
  "chalk": "^4.1.2",
16
17
  "cheerio": "^1.0.0-rc.10",
@@ -28,12 +29,12 @@
28
29
  "devDependencies": {
29
30
  "eslint": "^7.5.0",
30
31
  "mocha": "^10.2.0",
31
- "prettier": "^1.11.1"
32
+ "prettier": "^3.3.3"
32
33
  },
33
34
  "scripts": {
34
35
  "test": "mocha",
35
- "lint": "eslint **/*.js",
36
- "prettier": "prettier utils.js src/* --write"
36
+ "lint": "eslint . --ext .js,.cjs,.mjs,.ts,.tsx",
37
+ "prettier": "prettier \"**/*.{js,cjs,mjs,ts,tsx,json,md,css,scss,html,yml,yaml}\" --ignore-unknown --write"
37
38
  },
38
39
  "keywords": [
39
40
  "facebook",
@@ -45,40 +46,6 @@
45
46
  "engines": {
46
47
  "node": ">=10.x"
47
48
  },
48
- "eslintConfig": {
49
- "env": {
50
- "es6": true,
51
- "es2017": true,
52
- "node": true
53
- },
54
- "extends": "eslint:recommended",
55
- "parserOptions": {
56
- "sourceType": "module"
57
- },
58
- "rules": {
59
- "linebreak-style": [
60
- "error",
61
- "unix"
62
- ],
63
- "semi": [
64
- "error",
65
- "always"
66
- ],
67
- "no-unused-vars": [
68
- 1,
69
- {
70
- "argsIgnorePattern": "^_",
71
- "varsIgnorePattern": "^_"
72
- }
73
- ],
74
- "no-empty": [
75
- "error",
76
- {
77
- "allowEmptyCatch": true
78
- }
79
- ]
80
- }
81
- },
82
49
  "types": "index.d.ts",
83
50
  "homepage": "https://github.com/DongDev-VN/fca-unofficial#readme",
84
51
  "bugs": {
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ const utils = require("../../utils");
4
+
5
+ module.exports = function(defaultFuncs, api, ctx) {
6
+ return function addExternalModule(moduleObj) {
7
+ if (utils.getType(moduleObj) == "Object") {
8
+ for (const apiName in moduleObj) {
9
+ if (utils.getType(moduleObj[apiName]) == "Function") {
10
+ api[apiName] = moduleObj[apiName](defaultFuncs, api, ctx);
11
+ } else {
12
+ throw new Error(
13
+ `Item "${apiName}" in moduleObj must be a function, not ${utils.getType(
14
+ moduleObj[apiName]
15
+ )}!`
16
+ );
17
+ }
18
+ }
19
+ } else {
20
+ throw new Error(
21
+ `moduleObj must be an object, not ${utils.getType(moduleObj)}!`
22
+ );
23
+ }
24
+ };
25
+ };
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+
3
+ const utils = require("../../utils");
4
+ const log = require("npmlog");
5
+
6
+ module.exports = function(defaultFuncs, api, ctx) {
7
+ function handleUpload(image, callback) {
8
+ const uploads = [];
9
+
10
+ const form = {
11
+ profile_id: ctx.i_userID || ctx.userID,
12
+ photo_source: 57,
13
+ av: ctx.i_userID || ctx.userID,
14
+ file: image
15
+ };
16
+
17
+ uploads.push(
18
+ defaultFuncs
19
+ .postFormData(
20
+ "https://www.facebook.com/profile/picture/upload/",
21
+ ctx.jar,
22
+ form,
23
+ {}
24
+ )
25
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
26
+ .then(function(resData) {
27
+ if (resData.error) {
28
+ throw resData;
29
+ }
30
+ return resData;
31
+ })
32
+ );
33
+
34
+ // resolve all promises
35
+ Promise.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 changeAvatar(
46
+ image,
47
+ caption = "",
48
+ timestamp = null,
49
+ callback
50
+ ) {
51
+ let resolveFunc = function() {};
52
+ let rejectFunc = function() {};
53
+ const returnPromise = new Promise(function(resolve, reject) {
54
+ resolveFunc = resolve;
55
+ rejectFunc = reject;
56
+ });
57
+
58
+ if (!timestamp && utils.getType(caption) === "Number") {
59
+ timestamp = caption;
60
+ caption = "";
61
+ }
62
+
63
+ if (
64
+ !timestamp &&
65
+ !callback &&
66
+ (utils.getType(caption) == "Function" ||
67
+ utils.getType(caption) == "AsyncFunction")
68
+ ) {
69
+ callback = caption;
70
+ caption = "";
71
+ timestamp = null;
72
+ }
73
+
74
+ if (!callback)
75
+ callback = function(err, data) {
76
+ if (err) {
77
+ return rejectFunc(err);
78
+ }
79
+ resolveFunc(data);
80
+ };
81
+
82
+ if (!utils.isReadableStream(image))
83
+ return callback("Image is not a readable stream");
84
+
85
+ handleUpload(image, function(err, payload) {
86
+ if (err) {
87
+ return callback(err);
88
+ }
89
+
90
+ const form = {
91
+ av: ctx.i_userID || ctx.userID,
92
+ fb_api_req_friendly_name: "ProfileCometProfilePictureSetMutation",
93
+ fb_api_caller_class: "RelayModern",
94
+ doc_id: "5066134240065849",
95
+ variables: JSON.stringify({
96
+ input: {
97
+ caption,
98
+ existing_photo_id: payload[0].payload.fbid,
99
+ expiration_time: timestamp,
100
+ profile_id: ctx.i_userID || ctx.userID,
101
+ profile_pic_method: "EXISTING",
102
+ profile_pic_source: "TIMELINE",
103
+ scaled_crop_rect: {
104
+ height: 1,
105
+ width: 1,
106
+ x: 0,
107
+ y: 0
108
+ },
109
+ skip_cropping: true,
110
+ actor_id: ctx.i_userID || ctx.userID,
111
+ client_mutation_id: Math.round(Math.random() * 19).toString()
112
+ },
113
+ isPage: false,
114
+ isProfile: true,
115
+ scale: 3
116
+ })
117
+ };
118
+
119
+ defaultFuncs
120
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
121
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
122
+ .then(function(resData) {
123
+ if (resData.errors) {
124
+ throw resData;
125
+ }
126
+ return callback(null, resData[0].data.profile_picture_set);
127
+ })
128
+ .catch(function(err) {
129
+ log.error("changeAvatar", err);
130
+ return callback(err);
131
+ });
132
+ });
133
+
134
+ return returnPromise;
135
+ };
136
+ };
@@ -0,0 +1,76 @@
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 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
+
15
+ if (!callback) {
16
+ if (
17
+ utils.getType(publish) == "Function" ||
18
+ utils.getType(publish) == "AsyncFunction"
19
+ ) {
20
+ callback = publish;
21
+ } else {
22
+ callback = function(err) {
23
+ if (err) {
24
+ return rejectFunc(err);
25
+ }
26
+ resolveFunc();
27
+ };
28
+ }
29
+ }
30
+
31
+ if (utils.getType(publish) != "Boolean") {
32
+ publish = false;
33
+ }
34
+
35
+ if (utils.getType(bio) != "String") {
36
+ bio = "";
37
+ publish = false;
38
+ }
39
+
40
+ const form = {
41
+ fb_api_caller_class: "RelayModern",
42
+ fb_api_req_friendly_name: "ProfileCometSetBioMutation",
43
+ // This doc_is is valid as of May 23, 2020
44
+ doc_id: "2725043627607610",
45
+ variables: JSON.stringify({
46
+ input: {
47
+ bio: bio,
48
+ publish_bio_feed_story: publish,
49
+ actor_id: ctx.i_userID || ctx.userID,
50
+ client_mutation_id: Math.round(Math.random() * 1024).toString()
51
+ },
52
+ hasProfileTileViewID: false,
53
+ profileTileViewID: null,
54
+ scale: 1
55
+ }),
56
+ av: ctx.i_userID || ctx.userID
57
+ };
58
+
59
+ defaultFuncs
60
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
61
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
62
+ .then(function(resData) {
63
+ if (resData.errors) {
64
+ throw resData;
65
+ }
66
+
67
+ return callback();
68
+ })
69
+ .catch(function(err) {
70
+ log.error("changeBio", err);
71
+ return callback(err);
72
+ });
73
+
74
+ return returnPromise;
75
+ };
76
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ module.exports = function(defaultFuncs, api, ctx) {
4
+ return function getCurrentUserID() {
5
+ return ctx.i_userID || ctx.userID;
6
+ };
7
+ };
@@ -0,0 +1,57 @@
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 handleFriendRequest(userID, accept, callback) {
8
+ if (utils.getType(accept) !== "Boolean") {
9
+ throw {
10
+ error: "Please pass a boolean as a second argument."
11
+ };
12
+ }
13
+
14
+ let resolveFunc = function() {};
15
+ let rejectFunc = function() {};
16
+ const returnPromise = new Promise(function(resolve, reject) {
17
+ resolveFunc = resolve;
18
+ rejectFunc = reject;
19
+ });
20
+
21
+ if (!callback) {
22
+ callback = function(err, friendList) {
23
+ if (err) {
24
+ return rejectFunc(err);
25
+ }
26
+ resolveFunc(friendList);
27
+ };
28
+ }
29
+
30
+ const form = {
31
+ viewer_id: ctx.i_userID || ctx.userID,
32
+ "frefs[0]": "jwl",
33
+ floc: "friend_center_requests",
34
+ ref: "/reqs.php",
35
+ action: accept ? "confirm" : "reject"
36
+ };
37
+
38
+ defaultFuncs
39
+ .post("https://www.facebook.com/requests/friends/ajax/", ctx.jar, form)
40
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
41
+ .then(function(resData) {
42
+ if (resData.payload.err) {
43
+ throw {
44
+ err: resData.payload.err
45
+ };
46
+ }
47
+
48
+ return callback();
49
+ })
50
+ .catch(function(err) {
51
+ log.error("handleFriendRequest", err);
52
+ return callback(err);
53
+ });
54
+
55
+ return returnPromise;
56
+ };
57
+ };
@@ -0,0 +1,75 @@
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 logout(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
+ pmid: "0"
26
+ };
27
+
28
+ defaultFuncs
29
+ .post(
30
+ "https://www.facebook.com/bluebar/modern_settings_menu/?help_type=364455653583099&show_contextual_help=1",
31
+ ctx.jar,
32
+ form
33
+ )
34
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
35
+ .then(function(resData) {
36
+ const elem = resData.jsmods.instances[0][2][0].filter(function(v) {
37
+ return v.value === "logout";
38
+ })[0];
39
+
40
+ const html = resData.jsmods.markup.filter(function(v) {
41
+ return v[0] === elem.markup.__m;
42
+ })[0][1].__html;
43
+
44
+ const form = {
45
+ fb_dtsg: utils.getFrom(html, '"fb_dtsg" value="', '"'),
46
+ ref: utils.getFrom(html, '"ref" value="', '"'),
47
+ h: utils.getFrom(html, '"h" value="', '"')
48
+ };
49
+
50
+ return defaultFuncs
51
+ .post("https://www.facebook.com/logout.php", ctx.jar, form)
52
+ .then(utils.saveCookies(ctx.jar));
53
+ })
54
+ .then(function(res) {
55
+ if (!res.headers) {
56
+ throw { error: "An error occurred when logging out." };
57
+ }
58
+
59
+ return defaultFuncs
60
+ .get(res.headers.location, ctx.jar)
61
+ .then(utils.saveCookies(ctx.jar));
62
+ })
63
+ .then(function() {
64
+ ctx.loggedIn = false;
65
+ log.info("logout", "Logged out successfully.");
66
+ callback();
67
+ })
68
+ .catch(function(err) {
69
+ log.error("logout", err);
70
+ return callback(err);
71
+ });
72
+
73
+ return returnPromise;
74
+ };
75
+ };
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../utils");
3
+ const utils = require("../../utils");
4
4
  const log = require("npmlog");
5
5
 
6
- module.exports = function (defaultFuncs, api, ctx) {
6
+ module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function refreshFb_dtsg(obj, callback) {
8
8
  let resolveFunc, rejectFunc;
9
9
  const returnPromise = new Promise((resolve, reject) => {
@@ -29,9 +29,9 @@ module.exports = function (defaultFuncs, api, ctx) {
29
29
  if (Object.keys(obj).length === 0) {
30
30
  utils
31
31
  .get("https://www.facebook.com/", ctx.jar, null, ctx.globalOptions, {
32
- noRef: true,
32
+ noRef: true
33
33
  })
34
- .then((resData) => {
34
+ .then(resData => {
35
35
  const fb_dtsg = utils.getFrom(
36
36
  resData.body,
37
37
  '["DTSGInitData",[],{"token":"',
@@ -47,10 +47,10 @@ module.exports = function (defaultFuncs, api, ctx) {
47
47
  ctx.jazoest = jazoest;
48
48
  callback(null, {
49
49
  data: { fb_dtsg, jazoest },
50
- message: "Refreshed fb_dtsg and jazoest",
50
+ message: "Refreshed fb_dtsg and jazoest"
51
51
  });
52
52
  })
53
- .catch((err) => {
53
+ .catch(err => {
54
54
  log.error("refreshFb_dtsg", err);
55
55
  callback(err);
56
56
  });
@@ -58,9 +58,9 @@ module.exports = function (defaultFuncs, api, ctx) {
58
58
  Object.assign(ctx, obj);
59
59
  callback(null, {
60
60
  data: obj,
61
- message: "Refreshed " + Object.keys(obj).join(", "),
61
+ message: "Refreshed " + Object.keys(obj).join(", ")
62
62
  });
63
63
  }
64
64
  return returnPromise;
65
65
  };
66
- };
66
+ };
@@ -0,0 +1,107 @@
1
+
2
+ "use strict";
3
+
4
+ const utils = require("../../utils");
5
+ const log = require("npmlog");
6
+
7
+ function formatData(resData) {
8
+ return {
9
+ viewer_feedback_reaction_info:
10
+ resData.feedback_react.feedback.viewer_feedback_reaction_info,
11
+ supported_reactions: resData.feedback_react.feedback.supported_reactions,
12
+ top_reactions: resData.feedback_react.feedback.top_reactions.edges,
13
+ reaction_count: resData.feedback_react.feedback.reaction_count
14
+ };
15
+ }
16
+
17
+ module.exports = function(defaultFuncs, api, ctx) {
18
+ return function setPostReaction(postID, type, callback) {
19
+ let resolveFunc = function() {};
20
+ let rejectFunc = function() {};
21
+ const returnPromise = new Promise(function(resolve, reject) {
22
+ resolveFunc = resolve;
23
+ rejectFunc = reject;
24
+ });
25
+
26
+ if (!callback) {
27
+ if (
28
+ utils.getType(type) === "Function" ||
29
+ utils.getType(type) === "AsyncFunction"
30
+ ) {
31
+ callback = type;
32
+ type = 0;
33
+ } else {
34
+ callback = function(err, data) {
35
+ if (err) {
36
+ return rejectFunc(err);
37
+ }
38
+ resolveFunc(data);
39
+ };
40
+ }
41
+ }
42
+
43
+ const map = {
44
+ unlike: 0,
45
+ like: 1,
46
+ heart: 2,
47
+ love: 16,
48
+ haha: 4,
49
+ wow: 3,
50
+ sad: 7,
51
+ angry: 8
52
+ };
53
+
54
+ if (utils.getType(type) !== "Number" && utils.getType(type) === "String") {
55
+ type = map[type.toLowerCase()];
56
+ }
57
+
58
+ if (utils.getType(type) !== "Number" && utils.getType(type) !== "String") {
59
+ throw {
60
+ error: "setPostReaction: Invalid reaction type"
61
+ };
62
+ }
63
+
64
+ if (type != 0 && !type) {
65
+ throw {
66
+ error: "setPostReaction: Invalid reaction type"
67
+ };
68
+ }
69
+
70
+ const form = {
71
+ av: ctx.i_userID || ctx.userID,
72
+ fb_api_caller_class: "RelayModern",
73
+ fb_api_req_friendly_name: "CometUFIFeedbackReactMutation",
74
+ doc_id: "4769042373179384",
75
+ variables: JSON.stringify({
76
+ input: {
77
+ actor_id: ctx.i_userID || ctx.userID,
78
+ feedback_id: new Buffer("feedback:" + postID).toString("base64"),
79
+ feedback_reaction: type,
80
+ feedback_source: "OBJECT",
81
+ is_tracking_encrypted: true,
82
+ tracking: [],
83
+ session_id: "f7dd50dd-db6e-4598-8cd9-561d5002b423",
84
+ client_mutation_id: Math.round(Math.random() * 19).toString()
85
+ },
86
+ useDefaultActor: false,
87
+ scale: 3
88
+ })
89
+ };
90
+
91
+ defaultFuncs
92
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
93
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
94
+ .then(function(resData) {
95
+ if (resData.errors) {
96
+ throw resData;
97
+ }
98
+ return callback(null, formatData(resData.data));
99
+ })
100
+ .catch(function(err) {
101
+ log.error("setPostReaction", err);
102
+ return callback(err);
103
+ });
104
+
105
+ return returnPromise;
106
+ };
107
+ };
@@ -0,0 +1,55 @@
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 unfriend(userID, 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
+ uid: userID,
26
+ unref: "bd_friends_tab",
27
+ floc: "friends_tab",
28
+ "nctr[_mod]":
29
+ "pagelet_timeline_app_collection_" +
30
+ (ctx.i_userID || ctx.userID) +
31
+ ":2356318349:2"
32
+ };
33
+
34
+ defaultFuncs
35
+ .post(
36
+ "https://www.facebook.com/ajax/profile/removefriendconfirm.php",
37
+ ctx.jar,
38
+ form
39
+ )
40
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
41
+ .then(function(resData) {
42
+ if (resData.error) {
43
+ throw resData;
44
+ }
45
+
46
+ return callback(null, true);
47
+ })
48
+ .catch(function(err) {
49
+ log.error("unfriend", err);
50
+ return callback(err);
51
+ });
52
+
53
+ return returnPromise;
54
+ };
55
+ };