bb-fca 2.0.3 → 2.0.4

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 (33) hide show
  1. package/dist/deltas/apis/users/getUserFriends.js +285 -0
  2. package/dist/deltas/apis/users/getUserFriends.js.map +1 -0
  3. package/dist/deltas/apis/users/searchCity.js +91 -0
  4. package/dist/deltas/apis/users/searchCity.js.map +1 -0
  5. package/dist/deltas/apis/users/searchCompany.js +86 -0
  6. package/dist/deltas/apis/users/searchCompany.js.map +1 -0
  7. package/dist/deltas/apis/users/searchJobTitle.js +85 -0
  8. package/dist/deltas/apis/users/searchJobTitle.js.map +1 -0
  9. package/dist/deltas/apis/users/updateCity.js +98 -0
  10. package/dist/deltas/apis/users/updateCity.js.map +1 -0
  11. package/dist/deltas/apis/users/updateHometown.js +97 -0
  12. package/dist/deltas/apis/users/updateHometown.js.map +1 -0
  13. package/dist/deltas/apis/users/updateWorkExperience.js +131 -0
  14. package/dist/deltas/apis/users/updateWorkExperience.js.map +1 -0
  15. package/dist/index.d.ts +115 -0
  16. package/dist/types/deltas/apis/users/getUserFriends.d.ts +30 -0
  17. package/dist/types/deltas/apis/users/searchCity.d.ts +10 -0
  18. package/dist/types/deltas/apis/users/searchCompany.d.ts +10 -0
  19. package/dist/types/deltas/apis/users/searchJobTitle.d.ts +10 -0
  20. package/dist/types/deltas/apis/users/updateCity.d.ts +10 -0
  21. package/dist/types/deltas/apis/users/updateHometown.d.ts +10 -0
  22. package/dist/types/deltas/apis/users/updateWorkExperience.d.ts +30 -0
  23. package/friend.html +534 -0
  24. package/package.json +1 -1
  25. package/proflie.html +527 -0
  26. package/src/deltas/apis/users/getUserFriends.ts +373 -0
  27. package/src/deltas/apis/users/searchCity.ts +106 -0
  28. package/src/deltas/apis/users/searchCompany.ts +100 -0
  29. package/src/deltas/apis/users/searchJobTitle.ts +99 -0
  30. package/src/deltas/apis/users/updateCity.ts +113 -0
  31. package/src/deltas/apis/users/updateHometown.ts +112 -0
  32. package/src/deltas/apis/users/updateWorkExperience.ts +160 -0
  33. package/src/types/index.d.ts +115 -0
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = getUserFriendsModule;
4
+ const utils = require("../../../utils");
5
+ /**
6
+ * @ChoruOfficial
7
+ * @description A module for fetching a user's friend list via Facebook's GraphQL API.
8
+ * First resolves the user's friends page to extract the dynamic collection ID,
9
+ * then calls ProfileCometAppCollectionNonSelfFriendsListRendererPaginationQuery via /api/graphql/.
10
+ * Supports cursor-based pagination without re-fetching HTML on subsequent pages.
11
+ * @param {Object} defaultFuncs The default functions provided by the API wrapper.
12
+ * @param {Object} api The full API object.
13
+ * @param {Object} ctx The context object containing the user's session state.
14
+ * @returns {Function} An async function that fetches a user's friend list.
15
+ */
16
+ function getUserFriendsModule(defaultFuncs, api, ctx) {
17
+ /**
18
+ * Deep-searches an object/array tree for the first value matching a predicate.
19
+ */
20
+ function deepFind(obj, predicate, visited = new WeakSet()) {
21
+ if (obj === null || obj === undefined)
22
+ return null;
23
+ if (typeof obj === 'object') {
24
+ if (visited.has(obj))
25
+ return null;
26
+ visited.add(obj);
27
+ }
28
+ if (typeof obj === 'object') {
29
+ for (const key in obj) {
30
+ if (!Object.prototype.hasOwnProperty.call(obj, key))
31
+ continue;
32
+ const val = obj[key];
33
+ if (predicate(val, key))
34
+ return val;
35
+ const found = deepFind(val, predicate, visited);
36
+ if (found !== null)
37
+ return found;
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+ /**
43
+ * Deep-searches for all values matching a predicate and collects them.
44
+ */
45
+ function deepFindAll(obj, predicate, results = [], visited = new WeakSet()) {
46
+ if (obj === null || obj === undefined)
47
+ return results;
48
+ if (typeof obj === 'object') {
49
+ if (visited.has(obj))
50
+ return results;
51
+ visited.add(obj);
52
+ }
53
+ if (typeof obj === 'object') {
54
+ for (const key in obj) {
55
+ if (!Object.prototype.hasOwnProperty.call(obj, key))
56
+ continue;
57
+ const val = obj[key];
58
+ if (predicate(val, key))
59
+ results.push(val);
60
+ deepFindAll(val, predicate, results, visited);
61
+ }
62
+ }
63
+ return results;
64
+ }
65
+ /**
66
+ * Extracts the friends collection ID from the embedded JSON data on a user's friends page.
67
+ *
68
+ * The correct ID lives on the same node as `pageItems` (sibling), e.g.:
69
+ * { pageItems: { edges: [...], page_info: {...} }, id: "YXBwX2NvbGxlY3Rpb24..." }
70
+ * Decodes to `app_collection:...`.
71
+ */
72
+ function extractCollectionId(allJsonData) {
73
+ // Strategy 1 (most reliable): find a node that has BOTH `pageItems.page_info`
74
+ // and a sibling `id` field. This is exactly the shape Facebook returns for
75
+ // the friends collection renderer.
76
+ const pageItemsParent = deepFind(allJsonData, (val, _key) => val &&
77
+ typeof val === 'object' &&
78
+ val.pageItems &&
79
+ val.pageItems.page_info &&
80
+ typeof val.id === 'string' &&
81
+ val.id.length > 40);
82
+ if (pageItemsParent?.id) {
83
+ try {
84
+ const decoded = Buffer.from(pageItemsParent.id, 'base64').toString('utf-8');
85
+ if (decoded.startsWith('app_collection:')) {
86
+ return pageItemsParent.id;
87
+ }
88
+ }
89
+ catch {
90
+ /* not base64, fall through */
91
+ }
92
+ // Even if it doesn't decode to app_collection, it's still the
93
+ // best candidate because it sits next to pageItems.
94
+ return pageItemsParent.id;
95
+ }
96
+ // Strategy 2: all_collections → edges → node with tab_key "friends"
97
+ const allCollections = deepFindAll(allJsonData, (_val, key) => key === 'all_collections');
98
+ for (const collection of allCollections) {
99
+ const edges = collection?.edges;
100
+ if (!Array.isArray(edges))
101
+ continue;
102
+ for (const edge of edges) {
103
+ const node = edge?.node;
104
+ if (!node)
105
+ continue;
106
+ if (node.tab_key === 'friends') {
107
+ if (node.id)
108
+ return node.id;
109
+ }
110
+ }
111
+ }
112
+ // Strategy 3: any base64 id that decodes to "app_collection:..."
113
+ const candidates = deepFindAll(allJsonData, (val, key) => key === 'id' && typeof val === 'string' && val.length > 40);
114
+ for (const candidate of candidates) {
115
+ try {
116
+ const decoded = Buffer.from(candidate, 'base64').toString('utf-8');
117
+ if (decoded.startsWith('app_collection:')) {
118
+ return candidate;
119
+ }
120
+ }
121
+ catch {
122
+ // Not valid base64, skip
123
+ }
124
+ }
125
+ return null;
126
+ }
127
+ /**
128
+ * Maps a raw pageItems edge node to a FriendEntry.
129
+ */
130
+ function mapEdgeToFriend(edge) {
131
+ const item = edge.node;
132
+ const actionOwner = item?.actions_renderer?.action?.client_handler?.profile_action
133
+ ?.restrictable_profile_owner || {};
134
+ return {
135
+ id: item?.node?.id || actionOwner?.id || '',
136
+ name: item?.title?.text || '',
137
+ avatarUri: item?.image_v2?.uri || '',
138
+ profileUrl: item?.url || item?.node?.url || '',
139
+ mutualFriendsText: item?.subtitle_text?.text || '',
140
+ friendshipStatus: item?.actions_renderer?.action?.profile_owner?.friendship_status || '',
141
+ gender: actionOwner?.gender || '',
142
+ };
143
+ }
144
+ /**
145
+ * Extracts the initial friends list and page_info directly from the embedded
146
+ * HTML JSON data (the data Facebook ships with the first page load).
147
+ *
148
+ * The cursor pattern in the HTML:
149
+ * ],"page_info":{"end_cursor":"AQHS...","has_next_page":true}
150
+ */
151
+ function extractInitialFriendsData(allJsonData) {
152
+ const pageItemsNode = deepFind(allJsonData, (val, key) => key === 'pageItems' &&
153
+ val &&
154
+ typeof val === 'object' &&
155
+ Array.isArray(val.edges) &&
156
+ val.page_info);
157
+ if (!pageItemsNode)
158
+ return null;
159
+ const edges = pageItemsNode.edges || [];
160
+ const pageInfo = pageItemsNode.page_info || {};
161
+ return {
162
+ friends: edges.map(mapEdgeToFriend),
163
+ endCursor: pageInfo.end_cursor || null,
164
+ hasNextPage: pageInfo.has_next_page || false,
165
+ };
166
+ }
167
+ /**
168
+ * Builds the GraphQL POST form matching the proven working pattern
169
+ * used by changeBio, uploadAvatar, and other GraphQL APIs.
170
+ * `defaultFuncs.post()` auto-injects `__req`, `__rev`, `__a`,
171
+ * `fb_dtsg`, `jazoest`, so we only add the query-specific fields.
172
+ */
173
+ function buildGraphQLForm(variables, ctx) {
174
+ return {
175
+ av: ctx.userID,
176
+ __user: ctx.userID,
177
+ __a: '1',
178
+ fb_dtsg: ctx.fb_dtsg,
179
+ jazoest: ctx.jazoest,
180
+ lsd: ctx.lsd,
181
+ fb_api_caller_class: 'RelayModern',
182
+ fb_api_req_friendly_name: 'ProfileCometAppCollectionNonSelfFriendsListRendererPaginationQuery',
183
+ variables: JSON.stringify(variables),
184
+ server_timestamps: 'true',
185
+ doc_id: '34081659828149039',
186
+ };
187
+ }
188
+ /**
189
+ * Fetches the friend list of a given user with cursor-based pagination.
190
+ *
191
+ * @param {string} userID The Facebook user ID whose friends to fetch.
192
+ * @param {string|null} [cursor=null] Pagination cursor from the previous result's `endCursor`.
193
+ * Pass `null` (or omit) for the first page.
194
+ * @param {number} [count=8] Number of friends to fetch per page.
195
+ * @param {string} [collectionId] The collection ID from a previous result.
196
+ * Pass this to skip the HTML re-fetch on page 2 onward — avoids an extra network round-trip.
197
+ *
198
+ * @returns {Promise<FriendsResult>} Friends list, pagination info, and the `collectionId`
199
+ * to reuse on subsequent calls.
200
+ *
201
+ * @example
202
+ * // Page 1 — fetches HTML, reads friends + cursor from embedded data
203
+ * const page1 = await api.getUserFriends('100005706074199');
204
+ * console.log(page1.friends); // Array of FriendEntry
205
+ * console.log(page1.endCursor); // cursor string for next page
206
+ * console.log(page1.collectionId); // reuse this to skip HTML fetch on page 2+
207
+ *
208
+ * // Page 2+ — pass cursor AND collectionId to skip the HTML round-trip
209
+ * const page2 = await api.getUserFriends(
210
+ * '100005706074199',
211
+ * page1.endCursor,
212
+ * 8,
213
+ * page1.collectionId,
214
+ * );
215
+ */
216
+ return async function getUserFriends(userID, cursor = null, collectionId, count = 8) {
217
+ if (!userID) {
218
+ throw new Error('userID is required.');
219
+ }
220
+ let resolvedCollectionId = collectionId || null;
221
+ // Step 1: Fetch the friends page HTML only when we don't have a collectionId.
222
+ // On page 2+ the caller should pass collectionId from the previous result
223
+ // to skip this round-trip (mirroring real browser behaviour).
224
+ if (!resolvedCollectionId) {
225
+ const friendsPageUrl = `https://www.facebook.com/profile.php?id=${userID}&sk=friends`;
226
+ const allJsonData = await utils.json(friendsPageUrl, ctx.jar, null, ctx.globalOptions, ctx);
227
+ if (!allJsonData || allJsonData.length === 0) {
228
+ throw new Error(`Could not fetch friends page data for user ${userID}.`);
229
+ }
230
+ resolvedCollectionId = extractCollectionId(allJsonData);
231
+ if (!resolvedCollectionId) {
232
+ throw new Error(`Could not extract friends collection ID for user ${userID}. ` +
233
+ `The user may have their friends list set to private.`);
234
+ }
235
+ // First page: try to read friends + page_info directly from the HTML data.
236
+ // The HTML ships with the initial batch and the cursor for the next page,
237
+ // matching: ],"page_info":{"end_cursor":"AQHS...","has_next_page":true}
238
+ if (cursor === null) {
239
+ const initialData = extractInitialFriendsData(allJsonData);
240
+ if (initialData) {
241
+ return { ...initialData, collectionId: resolvedCollectionId };
242
+ }
243
+ // Fallthrough: HTML extraction failed — use GraphQL with null cursor
244
+ }
245
+ }
246
+ // Step 2: GraphQL pagination request (page 2+ or first-page fallback).
247
+ // Variables match the real browser request exactly.
248
+ const variables = {
249
+ count,
250
+ cursor,
251
+ scale: 1,
252
+ search: null,
253
+ id: resolvedCollectionId,
254
+ __relay_internal__pv__FBProfile_enable_perf_improv_gkrelayprovider: true,
255
+ };
256
+ const form = buildGraphQLForm(variables, ctx);
257
+ const res = await utils.post('https://www.facebook.com/api/graphql/', ctx.jar, form, ctx.globalOptions, ctx);
258
+ let data;
259
+ if (typeof res.body === 'object' && res.body !== null) {
260
+ data = res.body;
261
+ }
262
+ else {
263
+ const body = typeof res.body === 'string' ? res.body : String(res.body);
264
+ try {
265
+ data = JSON.parse(body);
266
+ }
267
+ catch {
268
+ const lines = body.split('\n').filter(Boolean);
269
+ data = JSON.parse(lines[0]);
270
+ }
271
+ }
272
+ if (data.errors)
273
+ throw new Error(JSON.stringify(data.errors));
274
+ const pageItems = data?.data?.node?.pageItems;
275
+ const edges = pageItems?.edges || [];
276
+ const pageInfo = pageItems?.page_info || {};
277
+ return {
278
+ friends: edges.map(mapEdgeToFriend),
279
+ endCursor: pageInfo.end_cursor || null,
280
+ hasNextPage: pageInfo.has_next_page || false,
281
+ collectionId: resolvedCollectionId,
282
+ };
283
+ };
284
+ }
285
+ //# sourceMappingURL=getUserFriends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getUserFriends.js","sourceRoot":"","sources":["../../../../src/deltas/apis/users/getUserFriends.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const utils = require("../../../utils");
5
+ /**
6
+ * @ChoruOfficial
7
+ * @description A module for searching cities via Facebook's Directory Typeahead API.
8
+ * Calls useProfileCometDirectoryTypeaheadDataSourceQuery via /api/graphql/.
9
+ * @param {Object} defaultFuncs The default functions provided by the API wrapper.
10
+ * @param {Object} api The full API object.
11
+ * @param {Object} ctx The context object containing the user's session state.
12
+ * @returns {Function} An async function that searches for cities by name.
13
+ */
14
+ function default_1(defaultFuncs, api, ctx) {
15
+ /**
16
+ * Searches for cities matching the given query string.
17
+ * Uses Facebook's Directory Typeahead data source to find city results.
18
+ * @async
19
+ * @param {string} query The search query (city name or partial name).
20
+ * @param {string} [searchCategory='CURRENT_CITY'] The category to search.
21
+ * Supported values: 'CURRENT_CITY', 'HOMETOWN', etc.
22
+ * @returns {Promise<Array<Object>>} A promise that resolves to an array of city objects.
23
+ * @throws {Error} If the query is missing or the API request fails.
24
+ *
25
+ * @example
26
+ * const cities = await api.searchCity('vinh');
27
+ * const hometowns = await api.searchCity('ha noi', 'HOMETOWN');
28
+ */
29
+ return async function searchCity(query, searchCategory = 'CURRENT_CITY') {
30
+ if (!query) {
31
+ throw new Error('query is required.');
32
+ }
33
+ const variables = {
34
+ search_category: searchCategory,
35
+ query: query,
36
+ };
37
+ const form = {
38
+ av: ctx.userID,
39
+ __user: ctx.userID,
40
+ __a: '1',
41
+ fb_dtsg: ctx.fb_dtsg,
42
+ jazoest: ctx.jazoest,
43
+ lsd: ctx.lsd,
44
+ fb_api_caller_class: 'RelayModern',
45
+ fb_api_req_friendly_name: 'useProfileCometDirectoryTypeaheadDataSourceQuery',
46
+ variables: JSON.stringify(variables),
47
+ server_timestamps: 'true',
48
+ doc_id: '24825162803742896',
49
+ };
50
+ const customHeader = {
51
+ 'x-fb-friendly-name': 'useProfileCometDirectoryTypeaheadDataSourceQuery',
52
+ 'x-fb-lsd': ctx.lsd,
53
+ 'x-asbd-id': '359341',
54
+ origin: 'https://www.facebook.com',
55
+ referer: `https://www.facebook.com/profile.php?id=${ctx.userID}&sk=directory_personal_details`,
56
+ };
57
+ const resData = await utils.post('https://www.facebook.com/api/graphql/', ctx.jar, form, ctx.globalOptions, ctx, customHeader);
58
+ // resData.body may already be a parsed object (axios auto-parses JSON)
59
+ // or it may be a string/Buffer — handle both cases
60
+ let data;
61
+ if (typeof resData.body === 'object' && resData.body !== null && !Buffer.isBuffer(resData.body)) {
62
+ data = resData.body;
63
+ }
64
+ else {
65
+ const body = typeof resData.body === 'string' ? resData.body : resData.body.toString();
66
+ try {
67
+ data = JSON.parse(body);
68
+ }
69
+ catch {
70
+ // Facebook sometimes returns multiple JSON lines
71
+ const lines = body.split('\n').filter(Boolean);
72
+ data = JSON.parse(lines[0]);
73
+ }
74
+ }
75
+ if (data.errors)
76
+ throw new Error(JSON.stringify(data.errors));
77
+ // Extract city suggestions from: data.viewer.profile_directory_typeahead_suggestions
78
+ const suggestions = data?.data?.viewer?.profile_directory_typeahead_suggestions || [];
79
+ return suggestions
80
+ .filter((item) => item.fbid !== '-1')
81
+ .map((item) => ({
82
+ fbid: item.fbid,
83
+ title: item.title,
84
+ value: item.value,
85
+ photoUri: item.photo_uri,
86
+ subtitle: item.subtitle,
87
+ secondSubtitle: item.second_subtitle,
88
+ }));
89
+ };
90
+ }
91
+ //# sourceMappingURL=searchCity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchCity.js","sourceRoot":"","sources":["../../../../src/deltas/apis/users/searchCity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = searchCompanyModule;
4
+ const utils = require("../../../utils");
5
+ /**
6
+ * @ChoruOfficial
7
+ * @description A module for searching companies/workplaces via Facebook's Directory Typeahead API.
8
+ * Calls useProfileCometDirectoryTypeaheadDataSourceQuery via /api/graphql/.
9
+ * @param {Object} defaultFuncs The default functions provided by the API wrapper.
10
+ * @param {Object} api The full API object.
11
+ * @param {Object} ctx The context object containing the user's session state.
12
+ * @returns {Function} An async function that searches for companies by name.
13
+ */
14
+ function searchCompanyModule(defaultFuncs, api, ctx) {
15
+ /**
16
+ * Searches for companies/workplaces matching the given query string.
17
+ * Uses Facebook's Directory Typeahead data source with WORKPLACE category.
18
+ * @async
19
+ * @param {string} query The search query (company name or partial name).
20
+ * @returns {Promise<Array<Object>>} A promise that resolves to an array of company objects.
21
+ * @throws {Error} If the query is missing or the API request fails.
22
+ *
23
+ * @example
24
+ * const companies = await api.searchCompany('google');
25
+ * // companies[0] = { fbid: '...', title: 'Google', photoUri: '...', subtitle: '...', ... }
26
+ */
27
+ return async function searchCompany(query) {
28
+ if (!query) {
29
+ throw new Error('query is required.');
30
+ }
31
+ const variables = {
32
+ search_category: 'WORKPLACE',
33
+ query: query,
34
+ };
35
+ const form = {
36
+ av: ctx.userID,
37
+ __user: ctx.userID,
38
+ __a: '1',
39
+ fb_dtsg: ctx.fb_dtsg,
40
+ jazoest: ctx.jazoest,
41
+ lsd: ctx.lsd,
42
+ fb_api_caller_class: 'RelayModern',
43
+ fb_api_req_friendly_name: 'useProfileCometDirectoryTypeaheadDataSourceQuery',
44
+ variables: JSON.stringify(variables),
45
+ server_timestamps: 'true',
46
+ doc_id: '24825162803742896',
47
+ };
48
+ const customHeader = {
49
+ 'x-fb-friendly-name': 'useProfileCometDirectoryTypeaheadDataSourceQuery',
50
+ 'x-fb-lsd': ctx.lsd,
51
+ 'x-asbd-id': '359341',
52
+ origin: 'https://www.facebook.com',
53
+ referer: `https://www.facebook.com/profile.php?id=${ctx.userID}&sk=directory_work`,
54
+ };
55
+ const resData = await utils.post('https://www.facebook.com/api/graphql/', ctx.jar, form, ctx.globalOptions, ctx, customHeader);
56
+ // Handle both parsed object and string/Buffer response
57
+ let data;
58
+ if (typeof resData.body === 'object' && resData.body !== null && !Buffer.isBuffer(resData.body)) {
59
+ data = resData.body;
60
+ }
61
+ else {
62
+ const body = typeof resData.body === 'string' ? resData.body : resData.body.toString();
63
+ try {
64
+ data = JSON.parse(body);
65
+ }
66
+ catch {
67
+ const lines = body.split('\n').filter((l) => l);
68
+ data = JSON.parse(lines[0]);
69
+ }
70
+ }
71
+ if (data.errors)
72
+ throw new Error(JSON.stringify(data.errors));
73
+ const suggestions = data?.data?.viewer?.profile_directory_typeahead_suggestions || [];
74
+ return suggestions
75
+ .filter((item) => item.fbid !== '-1')
76
+ .map((item) => ({
77
+ fbid: item.fbid,
78
+ title: item.title,
79
+ value: item.value,
80
+ photoUri: item.photo_uri,
81
+ subtitle: item.subtitle,
82
+ secondSubtitle: item.second_subtitle,
83
+ }));
84
+ };
85
+ }
86
+ //# sourceMappingURL=searchCompany.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchCompany.js","sourceRoot":"","sources":["../../../../src/deltas/apis/users/searchCompany.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = searchJobTitleModule;
4
+ const utils = require("../../../utils");
5
+ /**
6
+ * @ChoruOfficial
7
+ * @description A module for searching job titles via Facebook's Directory Typeahead API.
8
+ * Calls useProfileCometDirectoryTypeaheadDataSourceQuery via /api/graphql/.
9
+ * @param {Object} defaultFuncs The default functions provided by the API wrapper.
10
+ * @param {Object} api The full API object.
11
+ * @param {Object} ctx The context object containing the user's session state.
12
+ * @returns {Function} An async function that searches for job titles by name.
13
+ */
14
+ function searchJobTitleModule(defaultFuncs, api, ctx) {
15
+ /**
16
+ * Searches for job titles/positions matching the given query string.
17
+ * Uses Facebook's Directory Typeahead data source with JOB_TITLE category.
18
+ * @async
19
+ * @param {string} query The search query (job title or partial name).
20
+ * @returns {Promise<Array<Object>>} A promise that resolves to an array of job title objects.
21
+ * @throws {Error} If the query is missing or the API request fails.
22
+ *
23
+ * @example
24
+ * const jobs = await api.searchJobTitle('developer');
25
+ * // jobs[0] = { fbid: '...', title: 'Software Developer', ... }
26
+ */
27
+ return async function searchJobTitle(query) {
28
+ if (!query) {
29
+ throw new Error('query is required.');
30
+ }
31
+ const variables = {
32
+ search_category: 'JOB_TITLE',
33
+ query: query,
34
+ };
35
+ const form = {
36
+ av: ctx.userID,
37
+ __user: ctx.userID,
38
+ __a: '1',
39
+ fb_dtsg: ctx.fb_dtsg,
40
+ jazoest: ctx.jazoest,
41
+ lsd: ctx.lsd,
42
+ fb_api_caller_class: 'RelayModern',
43
+ fb_api_req_friendly_name: 'useProfileCometDirectoryTypeaheadDataSourceQuery',
44
+ variables: JSON.stringify(variables),
45
+ server_timestamps: 'true',
46
+ doc_id: '24825162803742896',
47
+ };
48
+ const customHeader = {
49
+ 'x-fb-friendly-name': 'useProfileCometDirectoryTypeaheadDataSourceQuery',
50
+ 'x-fb-lsd': ctx.lsd,
51
+ 'x-asbd-id': '359341',
52
+ origin: 'https://www.facebook.com',
53
+ referer: `https://www.facebook.com/profile.php?id=${ctx.userID}&sk=directory_work`,
54
+ };
55
+ const resData = await utils.post('https://www.facebook.com/api/graphql/', ctx.jar, form, ctx.globalOptions, ctx, customHeader);
56
+ let data;
57
+ if (typeof resData.body === 'object' && resData.body !== null && !Buffer.isBuffer(resData.body)) {
58
+ data = resData.body;
59
+ }
60
+ else {
61
+ const body = typeof resData.body === 'string' ? resData.body : resData.body.toString();
62
+ try {
63
+ data = JSON.parse(body);
64
+ }
65
+ catch {
66
+ const lines = body.split('\n').filter(Boolean);
67
+ data = JSON.parse(lines[0]);
68
+ }
69
+ }
70
+ if (data.errors)
71
+ throw new Error(JSON.stringify(data.errors));
72
+ const suggestions = data?.data?.viewer?.profile_directory_typeahead_suggestions || [];
73
+ return suggestions
74
+ .filter((item) => item.fbid !== '-1')
75
+ .map((item) => ({
76
+ fbid: item.fbid,
77
+ title: item.title,
78
+ value: item.value,
79
+ photoUri: item.photo_uri,
80
+ subtitle: item.subtitle,
81
+ secondSubtitle: item.second_subtitle,
82
+ }));
83
+ };
84
+ }
85
+ //# sourceMappingURL=searchJobTitle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchJobTitle.js","sourceRoot":"","sources":["../../../../src/deltas/apis/users/searchJobTitle.ts"],"names":[],"mappings":"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"}