bb-fca 2.0.3 → 2.0.5
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.
Potentially problematic release.
This version of bb-fca might be problematic. Click here for more details.
- package/dist/deltas/apis/create.js +22 -0
- package/dist/deltas/apis/create.js.map +1 -1
- package/dist/deltas/apis/posting/post.js +346 -1
- package/dist/deltas/apis/posting/post.js.map +1 -1
- package/dist/deltas/apis/posting/story.js +147 -0
- package/dist/deltas/apis/posting/story.js.map +1 -1
- package/dist/deltas/apis/users/getUserFriends.js +285 -0
- package/dist/deltas/apis/users/getUserFriends.js.map +1 -0
- package/dist/deltas/apis/users/searchCity.js +91 -0
- package/dist/deltas/apis/users/searchCity.js.map +1 -0
- package/dist/deltas/apis/users/searchCompany.js +86 -0
- package/dist/deltas/apis/users/searchCompany.js.map +1 -0
- package/dist/deltas/apis/users/searchJobTitle.js +85 -0
- package/dist/deltas/apis/users/searchJobTitle.js.map +1 -0
- package/dist/deltas/apis/users/updateCity.js +98 -0
- package/dist/deltas/apis/users/updateCity.js.map +1 -0
- package/dist/deltas/apis/users/updateHometown.js +97 -0
- package/dist/deltas/apis/users/updateHometown.js.map +1 -0
- package/dist/deltas/apis/users/updateWorkExperience.js +131 -0
- package/dist/deltas/apis/users/updateWorkExperience.js.map +1 -0
- package/dist/index.d.ts +128 -0
- package/dist/types/deltas/apis/create.d.ts +22 -0
- package/dist/types/deltas/apis/posting/post.d.ts +7 -0
- package/dist/types/deltas/apis/posting/story.d.ts +21 -0
- package/dist/types/deltas/apis/users/getUserFriends.d.ts +30 -0
- package/dist/types/deltas/apis/users/searchCity.d.ts +10 -0
- package/dist/types/deltas/apis/users/searchCompany.d.ts +10 -0
- package/dist/types/deltas/apis/users/searchJobTitle.d.ts +10 -0
- package/dist/types/deltas/apis/users/updateCity.d.ts +10 -0
- package/dist/types/deltas/apis/users/updateHometown.d.ts +10 -0
- package/dist/types/deltas/apis/users/updateWorkExperience.d.ts +30 -0
- package/dist/types/utils/axios.d.ts +1 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/utils/axios.js +12 -0
- package/dist/utils/axios.js.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/examples/post.example.js +41 -1
- package/package.json +1 -1
- package/src/deltas/apis/create.ts +25 -0
- package/src/deltas/apis/posting/post.ts +439 -1
- package/src/deltas/apis/posting/story.ts +147 -0
- package/src/deltas/apis/users/getUserFriends.ts +373 -0
- package/src/deltas/apis/users/searchCity.ts +106 -0
- package/src/deltas/apis/users/searchCompany.ts +100 -0
- package/src/deltas/apis/users/searchJobTitle.ts +99 -0
- package/src/deltas/apis/users/updateCity.ts +113 -0
- package/src/deltas/apis/users/updateHometown.ts +112 -0
- package/src/deltas/apis/users/updateWorkExperience.ts +160 -0
- package/src/types/index.d.ts +128 -0
- package/src/utils/axios.ts +19 -0
- package/src/utils/index.ts +1 -0
- package/story_image/request1.txt +69 -0
- package/story_image/request2.txt +60 -0
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.default = default_1;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const utils = require("../../../utils");
|
|
4
39
|
const url_1 = require("url");
|
|
5
40
|
/**
|
|
6
41
|
* @namespace api.story
|
|
@@ -148,6 +183,106 @@ function default_1(defaultFuncs, api, ctx) {
|
|
|
148
183
|
throw error;
|
|
149
184
|
}
|
|
150
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Uploads a photo for story usage.
|
|
188
|
+
* Uses waterfallxapp=comet_stories to target the stories upload endpoint.
|
|
189
|
+
* @param {string} photoPath Absolute path to the photo file.
|
|
190
|
+
* @returns {Promise<{success: boolean, photoID: string, photoId: string, imageSrc: string, data: object}>}
|
|
191
|
+
*/
|
|
192
|
+
async function uploadStoryPhoto(photoPath) {
|
|
193
|
+
if (!photoPath) {
|
|
194
|
+
throw new Error('Photo path is required.');
|
|
195
|
+
}
|
|
196
|
+
if (typeof photoPath !== 'string') {
|
|
197
|
+
throw new Error('Photo path must be a string.');
|
|
198
|
+
}
|
|
199
|
+
if (!fs.existsSync(photoPath)) {
|
|
200
|
+
throw new Error(`Photo file not found: ${photoPath}`);
|
|
201
|
+
}
|
|
202
|
+
const photoStream = fs.createReadStream(photoPath);
|
|
203
|
+
const url = new url_1.URL('https://upload.facebook.com/ajax/react_composer/attachments/photo/upload');
|
|
204
|
+
url.searchParams.append('av', ctx.userID);
|
|
205
|
+
url.searchParams.append('__aaid', '0');
|
|
206
|
+
url.searchParams.append('__user', ctx.userID);
|
|
207
|
+
url.searchParams.append('__a', '1');
|
|
208
|
+
url.searchParams.append('dpr', '1');
|
|
209
|
+
url.searchParams.append('__ccg', 'EXCELLENT');
|
|
210
|
+
url.searchParams.append('__comet_req', '15');
|
|
211
|
+
url.searchParams.append('fb_dtsg', ctx.fb_dtsg);
|
|
212
|
+
url.searchParams.append('jazoest', ctx.jazoest);
|
|
213
|
+
url.searchParams.append('lsd', ctx.fb_dtsg);
|
|
214
|
+
const form = {
|
|
215
|
+
source: '8',
|
|
216
|
+
profile_id: ctx.userID,
|
|
217
|
+
waterfallxapp: 'comet_stories',
|
|
218
|
+
farr: photoStream,
|
|
219
|
+
};
|
|
220
|
+
const uploadResponse = await utils.postFormData(url.toString(), ctx.jar, form, ctx.globalOptions, ctx);
|
|
221
|
+
const uploadResult = JSON.parse(uploadResponse.body.toString().replace(/^for \(;;\);/, ''));
|
|
222
|
+
if (uploadResult.error || uploadResult.errors) {
|
|
223
|
+
throw new Error(JSON.stringify(uploadResult.error || uploadResult.errors));
|
|
224
|
+
}
|
|
225
|
+
const photoID = uploadResult.payload?.photoID || uploadResult.payload?.fbid || null;
|
|
226
|
+
if (!photoID) {
|
|
227
|
+
throw new Error('Could not extract photoID from upload response.');
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
success: true,
|
|
231
|
+
photoID: String(photoID),
|
|
232
|
+
photoId: String(photoID),
|
|
233
|
+
imageSrc: uploadResult.payload?.imageSrc || null,
|
|
234
|
+
data: uploadResult.payload,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Creates a new image-based story.
|
|
239
|
+
* @param {string} photoPath Absolute path to the photo file.
|
|
240
|
+
* @returns {Promise<{success: boolean, storyID: string}>} A promise that resolves with the new story's ID.
|
|
241
|
+
*/
|
|
242
|
+
async function createImageStory(photoPath) {
|
|
243
|
+
// Step 1: Upload photo for story
|
|
244
|
+
const uploadResult = await uploadStoryPhoto(photoPath);
|
|
245
|
+
// Step 2: Create story with the uploaded photo
|
|
246
|
+
const variables = {
|
|
247
|
+
input: {
|
|
248
|
+
audiences: [{ stories: { self: { target_id: ctx.userID } } }],
|
|
249
|
+
audiences_is_complete: true,
|
|
250
|
+
logging: {
|
|
251
|
+
composer_session_id: 'createStoriesImage-' + Date.now(),
|
|
252
|
+
},
|
|
253
|
+
navigation_data: {
|
|
254
|
+
attribution_id_v2: 'StoriesCreateRoot.react,comet.stories.create',
|
|
255
|
+
},
|
|
256
|
+
source: 'WWW',
|
|
257
|
+
attachments: [
|
|
258
|
+
{
|
|
259
|
+
photo: {
|
|
260
|
+
id: uploadResult.photoID,
|
|
261
|
+
overlays: [],
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
tracking: [null],
|
|
266
|
+
actor_id: ctx.userID,
|
|
267
|
+
client_mutation_id: '1',
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
const form = {
|
|
271
|
+
__a: '1',
|
|
272
|
+
fb_api_caller_class: 'RelayModern',
|
|
273
|
+
fb_api_req_friendly_name: 'StoriesCreateMutation',
|
|
274
|
+
variables: JSON.stringify(variables),
|
|
275
|
+
doc_id: '24226878183562473',
|
|
276
|
+
};
|
|
277
|
+
const res = await defaultFuncs.post('https://www.facebook.com/api/graphql/', ctx.jar, form, {});
|
|
278
|
+
if (res.data.errors)
|
|
279
|
+
throw new Error(JSON.stringify(res.data.errors));
|
|
280
|
+
const storyNode = res.data?.data?.story_create?.viewer?.actor?.story_bucket?.nodes[0]
|
|
281
|
+
?.first_story_to_show;
|
|
282
|
+
if (!storyNode || !storyNode.id)
|
|
283
|
+
throw new Error('Could not find the storyCardID in the response.');
|
|
284
|
+
return { success: true, storyID: storyNode.id };
|
|
285
|
+
}
|
|
151
286
|
return {
|
|
152
287
|
/**
|
|
153
288
|
* Creates a new text-based story.
|
|
@@ -157,6 +292,18 @@ function default_1(defaultFuncs, api, ctx) {
|
|
|
157
292
|
* @returns {Promise<{success: boolean, storyID: string}>}
|
|
158
293
|
*/
|
|
159
294
|
create,
|
|
295
|
+
/**
|
|
296
|
+
* Uploads a photo for use in an image story.
|
|
297
|
+
* @param {string} photoPath Absolute path to the photo file.
|
|
298
|
+
* @returns {Promise<{success: boolean, photoID: string, photoId: string, imageSrc: string, data: object}>}
|
|
299
|
+
*/
|
|
300
|
+
uploadStoryPhoto,
|
|
301
|
+
/**
|
|
302
|
+
* Creates a new image-based story. Handles upload + publish in one call.
|
|
303
|
+
* @param {string} photoPath Absolute path to the photo file.
|
|
304
|
+
* @returns {Promise<{success: boolean, storyID: string}>}
|
|
305
|
+
*/
|
|
306
|
+
createImageStory,
|
|
160
307
|
/**
|
|
161
308
|
* Reacts to a story with a specific emoji.
|
|
162
309
|
* @param {string} storyIdOrUrl The ID or full URL of the story to react to.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"story.js","sourceRoot":"","sources":["../../../../src/deltas/apis/posting/story.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"story.js","sourceRoot":"","sources":["../../../../src/deltas/apis/posting/story.ts"],"names":[],"mappings":"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"}
|
|
@@ -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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"}
|