stfca 1.0.11 → 1.0.12

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stfca",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "description": "Unofficial Facebook Chat API for Node.js with Auto-Update System - Enhanced by ST | Sheikh Tamim",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -0,0 +1,82 @@
1
+ /**
2
+ * ===========================================================
3
+ * 🧑‍💻 Author: Sheikh Tamim (ST | Sheikh Tamim)
4
+ * 🔰 Owner & Developer
5
+ * 🌐 GitHub: https://github.com/sheikhtamimlover
6
+ * 📸 Instagram: https://instagram.com/sheikh.tamim_lover
7
+ * -----------------------------------------------------------
8
+ * 🕊️ Respect the creator & give proper credits if reused.
9
+ * ===========================================================
10
+ */
11
+ "use strict";
12
+
13
+ const utils = require("../utils");
14
+ const log = require("npmlog");
15
+
16
+ module.exports = function (defaultFuncs, api, ctx) {
17
+ /** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Instagram: @sheikh.tamim_lover */
18
+ return function getThreadTheme(themeID, callback) {
19
+ let resolveFunc, rejectFunc;
20
+ const returnPromise = new Promise((resolve, reject) => {
21
+ resolveFunc = resolve;
22
+ rejectFunc = reject;
23
+ });
24
+
25
+ if (!callback) {
26
+ callback = function (err, data) {
27
+ if (err) return rejectFunc(err);
28
+ resolveFunc(data);
29
+ };
30
+ }
31
+
32
+ if (!themeID) {
33
+ return callback({ error: "themeID is required" });
34
+ }
35
+
36
+ const form = {
37
+ av: ctx.userID,
38
+ __user: ctx.userID,
39
+ __a: 1,
40
+ __req: utils.getSignatureID(),
41
+ fb_dtsg: ctx.fb_dtsg,
42
+ jazoest: ctx.ttstamp,
43
+ lsd: ctx.fb_dtsg,
44
+ fb_api_caller_class: "RelayModern",
45
+ fb_api_req_friendly_name: "MWPThreadThemeProviderQuery",
46
+ variables: JSON.stringify({
47
+ id: themeID.toString() // <-- THEME ID instead of threadID
48
+ }),
49
+ server_timestamps: true,
50
+ doc_id: "9734829906576883"
51
+ };
52
+
53
+ defaultFuncs
54
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
55
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
56
+ .then(function (resData) {
57
+ if (resData.errors) throw resData.errors;
58
+
59
+ if (resData.data && resData.data.messenger_thread_theme) {
60
+ const themeData = resData.data.messenger_thread_theme;
61
+ return callback(null, {
62
+ id: themeData.id,
63
+ name: themeData.accessibility_label,
64
+ description: themeData.description,
65
+ colors: themeData.gradient_colors || [themeData.fallback_color],
66
+ backgroundImage: themeData.background_asset
67
+ ? themeData.background_asset.image.uri
68
+ : null
69
+ });
70
+ } else {
71
+ throw new Error("No theme data found");
72
+ }
73
+ })
74
+ .catch(function (err) {
75
+ log.error("getThreadTheme", err);
76
+ return callback(err);
77
+ });
78
+
79
+ return returnPromise;
80
+ };
81
+ };
82
+ /** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Please give credits if reused. */
@@ -0,0 +1,139 @@
1
+ /**
2
+ * ===========================================================
3
+ * 🧑‍💻 Author: Sheikh Tamim (ST | Sheikh Tamim)
4
+ * 🔰 Owner & Developer
5
+ * 🌐 GitHub: https://github.com/sheikhtamimlover
6
+ * 📸 Instagram: https://instagram.com/sheikh.tamim_lover
7
+ * -----------------------------------------------------------
8
+ * 🕊️ Respect the creator & give proper credits if reused.
9
+ * ===========================================================
10
+ */
11
+ "use strict";
12
+
13
+ const utils = require("../utils");
14
+
15
+ module.exports = function (defaultFuncs, api, ctx) {
16
+ /** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Instagram: @sheikh.tamim_lover */
17
+ return function searchFriends(searchQuery, callback) {
18
+ let resolveFunc = function () {};
19
+ let rejectFunc = function () {};
20
+ const returnPromise = new Promise(function (resolve, reject) {
21
+ resolveFunc = resolve;
22
+ rejectFunc = reject;
23
+ });
24
+
25
+ if (!callback) {
26
+ callback = function (err, result) {
27
+ if (err) {
28
+ return rejectFunc(err);
29
+ }
30
+ resolveFunc(result);
31
+ };
32
+ }
33
+
34
+ if (!searchQuery || searchQuery.trim().length === 0) {
35
+ return callback(new Error("Search query cannot be empty"));
36
+ }
37
+
38
+ // Enhanced form data based on captured API
39
+ const form = {
40
+ av: ctx.userID,
41
+ __aaid: 0,
42
+ __user: ctx.userID,
43
+ __a: 1,
44
+ __req: utils.getSignatureID(),
45
+ __hs: "20358.HYP:comet_pkg.2.1...0",
46
+ dpr: 1,
47
+ __ccg: "EXCELLENT",
48
+ __rev: "1027694919",
49
+ __s: utils.getSignatureID(),
50
+ __hsi: "7554748243252799467",
51
+ __comet_req: 15,
52
+ fb_dtsg: ctx.fb_dtsg,
53
+ jazoest: ctx.ttstamp,
54
+ lsd: ctx.fb_dtsg,
55
+ __spin_r: "1027694919",
56
+ __spin_b: "trunk",
57
+ __spin_t: Date.now(),
58
+ fb_api_caller_class: "RelayModern",
59
+ fb_api_req_friendly_name: "ProfileCometAppCollectionSelfFriendsListRendererPaginationQuery",
60
+ variables: JSON.stringify({
61
+ count: 20, // Increased count for better results
62
+ cursor: null,
63
+ scale: 1,
64
+ search: searchQuery.trim(),
65
+ id: "YXBwX2NvbGxlY3Rpb246cGZiaWQwMkJSM3NDeXRjNkJIeVVXem9OeUxNcjNoYnVDclRFZkdCcVlEaXZuSlZYOUNLR2pXVmRyYTQ4U29FalJTVzduMm03NlhDa0xEQXAybVVUenF6RXZraGc3ZHkyaGw="
66
+ }),
67
+ server_timestamps: true,
68
+ doc_id: "31767020089578751"
69
+ };
70
+
71
+ defaultFuncs
72
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
73
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
74
+ .then(function (resData) {
75
+ if (!resData || !resData.data) {
76
+ throw { error: "searchFriends returned empty object." };
77
+ }
78
+ if (resData.error) {
79
+ throw resData;
80
+ }
81
+
82
+ const friendsData = resData.data.node?.pageItems?.edges || [];
83
+ const formattedFriends = friendsData.map(edge => {
84
+ const friend = edge.node;
85
+ const friendUser = friend.node || friend;
86
+
87
+ // Extract mutual friends count from subtitle
88
+ let mutualFriends = 0;
89
+ if (friend.subtitle_text?.text) {
90
+ const mutualMatch = friend.subtitle_text.text.match(/(\d+)\s+mutual\s+friend/i);
91
+ if (mutualMatch) {
92
+ mutualFriends = parseInt(mutualMatch[1]);
93
+ }
94
+ }
95
+
96
+ return {
97
+ userID: friendUser.id || friend.id,
98
+ name: friend.title?.text || friendUser.name || friend.name,
99
+ profilePicture: friend.image?.uri || null,
100
+ profileUrl: friend.url || friendUser.url,
101
+ subtitle: friend.subtitle_text?.text || "",
102
+ mutualFriends: mutualFriends,
103
+ // Additional fields from the captured API
104
+ cursor: edge.cursor,
105
+ friendshipStatus: friendUser.friendship_status || "UNKNOWN",
106
+ gender: friendUser.gender || null,
107
+ shortName: friendUser.short_name || null
108
+ };
109
+ }).filter(friend => friend.userID && friend.name);
110
+
111
+ // Sort by relevance (exact matches first, then by mutual friends)
112
+ formattedFriends.sort((a, b) => {
113
+ const queryLower = searchQuery.toLowerCase();
114
+ const aNameLower = a.name.toLowerCase();
115
+ const bNameLower = b.name.toLowerCase();
116
+
117
+ // Exact matches first
118
+ if (aNameLower === queryLower && bNameLower !== queryLower) return -1;
119
+ if (bNameLower === queryLower && aNameLower !== queryLower) return 1;
120
+
121
+ // Then by starts with
122
+ if (aNameLower.startsWith(queryLower) && !bNameLower.startsWith(queryLower)) return -1;
123
+ if (bNameLower.startsWith(queryLower) && !aNameLower.startsWith(queryLower)) return 1;
124
+
125
+ // Then by mutual friends count
126
+ return b.mutualFriends - a.mutualFriends;
127
+ });
128
+
129
+ callback(null, formattedFriends);
130
+ })
131
+ .catch(function (err) {
132
+ console.error("searchFriends error:", err);
133
+ return callback(err);
134
+ });
135
+
136
+ return returnPromise;
137
+ };
138
+ };
139
+ /** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Please give credits if reused. */
@@ -0,0 +1,113 @@
1
+ /**
2
+ * ===========================================================
3
+ * 🧑‍💻 Author: Sheikh Tamim (ST | Sheikh Tamim)
4
+ * 🔰 Owner & Developer
5
+ * 🌐 GitHub: https://github.com/sheikhtamimlover
6
+ * 📸 Instagram: https://instagram.com/sheikh.tamim_lover
7
+ * -----------------------------------------------------------
8
+ * 🕊️ Respect the creator & give proper credits if reused.
9
+ * ===========================================================
10
+ */
11
+ "use strict";
12
+
13
+ var utils = require("../utils");
14
+ var log = require("npmlog");
15
+
16
+ module.exports = function (defaultFuncs, api, ctx) {
17
+ /** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Instagram: @sheikh.tamim_lover */
18
+ return function sendFriendRequest(userID, callback) {
19
+ var resolveFunc = function () { };
20
+ var rejectFunc = function () { };
21
+ var returnPromise = new Promise(function (resolve, reject) {
22
+ resolveFunc = resolve;
23
+ rejectFunc = reject;
24
+ });
25
+
26
+ if (!callback) {
27
+ callback = function (err, data) {
28
+ if (err) return rejectFunc(err);
29
+ resolveFunc(data);
30
+ };
31
+ }
32
+
33
+ if (!userID) {
34
+ return callback({ error: "User ID is required" });
35
+ }
36
+
37
+ var form = {
38
+ av: ctx.userID,
39
+ __aaid: 0,
40
+ __user: ctx.userID,
41
+ __a: 1,
42
+ __req: utils.getSignatureID(),
43
+ __hs: "20353.HYP:comet_pkg.2.1...0",
44
+ dpr: 1,
45
+ __ccg: "EXCELLENT",
46
+ __rev: "1027405870",
47
+ __s: utils.getSignatureID(),
48
+ __hsi: "7552782279085106329",
49
+ __comet_req: 15,
50
+ fb_dtsg: ctx.fb_dtsg,
51
+ jazoest: ctx.ttstamp,
52
+ lsd: ctx.fb_dtsg,
53
+ __spin_r: "1027405870",
54
+ __spin_b: "trunk",
55
+ __spin_t: Date.now(),
56
+ __crn: "comet.fbweb.CometFriendingRoute",
57
+ fb_api_caller_class: "RelayModern",
58
+ fb_api_req_friendly_name: "FriendingCometFriendRequestSendMutation",
59
+ variables: JSON.stringify({
60
+ input: {
61
+ click_correlation_id: Date.now().toString(),
62
+ click_proof_validation_result: '{"validated":true}',
63
+ friend_requestee_ids: [userID.toString()],
64
+ friending_channel: "FRIENDS_HOME_MAIN",
65
+ warn_ack_for_ids: [],
66
+ actor_id: ctx.userID,
67
+ client_mutation_id: Math.floor(Math.random() * 10).toString()
68
+ },
69
+ scale: 1
70
+ }),
71
+ server_timestamps: true,
72
+ doc_id: "24614631718227645"
73
+ };
74
+
75
+ defaultFuncs
76
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
77
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
78
+ .then(function (resData) {
79
+ if (resData.error) {
80
+ throw resData;
81
+ }
82
+
83
+ if (resData.data && resData.data.friend_request_send) {
84
+ var responseData = resData.data.friend_request_send;
85
+ if (responseData.friend_requestees && responseData.friend_requestees.length > 0) {
86
+ var requestee = responseData.friend_requestees[0];
87
+ var result = {
88
+ userID: requestee.id,
89
+ friendshipStatus: requestee.friendship_status,
90
+ success: requestee.friendship_status === "OUTGOING_REQUEST"
91
+ };
92
+
93
+ if (requestee.profile_action) {
94
+ result.actionTitle = requestee.profile_action.title ? requestee.profile_action.title.text : "";
95
+ }
96
+
97
+ return callback(null, result);
98
+ } else {
99
+ return callback({ error: "No friend request data received" });
100
+ }
101
+ } else {
102
+ return callback({ error: "Invalid response format" });
103
+ }
104
+ })
105
+ .catch(function (err) {
106
+ log.error("sendFriendRequest", err);
107
+ return callback(err);
108
+ });
109
+
110
+ return returnPromise;
111
+ };
112
+ };
113
+ /** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Please give credits if reused. */