bb-fca 2.0.6 → 2.0.8
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/a.html +537 -0
- package/a.json +5915 -0
- package/dist/deltas/apis/posting/group.js +607 -0
- package/dist/deltas/apis/posting/group.js.map +1 -0
- package/dist/deltas/apis/posting/post.js +174 -25
- package/dist/deltas/apis/posting/post.js.map +1 -1
- package/dist/deltas/apis/threads/searchGroup.js +159 -0
- package/dist/deltas/apis/threads/searchGroup.js.map +1 -0
- package/dist/deltas/apis/users/searchGroups.js +221 -0
- package/dist/deltas/apis/users/searchGroups.js.map +1 -0
- package/dist/index.d.ts +79 -3
- package/dist/types/deltas/apis/posting/group.d.ts +90 -0
- package/dist/types/deltas/apis/posting/post.d.ts +1 -1
- package/dist/types/deltas/apis/threads/searchGroup.d.ts +15 -0
- package/dist/types/deltas/apis/users/searchGroups.d.ts +17 -0
- package/package.json +1 -1
- package/src/deltas/apis/posting/group.ts +754 -0
- package/src/deltas/apis/posting/post.ts +190 -32
- package/src/types/index.d.ts +79 -3
- package/task.txt +24 -0
- package/LICENSE-MIT +0 -21
- package/examples/post.example.js +0 -189
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = searchGroupsModule;
|
|
4
|
+
const utils = require("../../../utils");
|
|
5
|
+
/**
|
|
6
|
+
* @description A module for searching Facebook groups by keyword.
|
|
7
|
+
* Calls SearchCometResultsPaginatedResultsQuery via /api/graphql/.
|
|
8
|
+
* @param {Object} defaultFuncs The default functions provided by the API wrapper.
|
|
9
|
+
* @param {Object} api The full API object.
|
|
10
|
+
* @param {Object} ctx The context object containing the user's session state.
|
|
11
|
+
* @returns {Function} An async function that searches for groups by keyword.
|
|
12
|
+
*/
|
|
13
|
+
function searchGroupsModule(defaultFuncs, api, ctx) {
|
|
14
|
+
/**
|
|
15
|
+
* Generates a UUID v4 string for use as a batch search ID.
|
|
16
|
+
*/
|
|
17
|
+
function createBsid() {
|
|
18
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
19
|
+
const r = Math.random() * 16;
|
|
20
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
21
|
+
return Math.floor(v).toString(16);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parses a localised member count string (e.g. "1.2K members") into a number.
|
|
26
|
+
*/
|
|
27
|
+
function parseLocalizedCount(text) {
|
|
28
|
+
const match = text.match(/([\d.,]+)\s*([kKmMbB])?/);
|
|
29
|
+
if (!match)
|
|
30
|
+
return null;
|
|
31
|
+
const base = Number((match[1] || '').replace(/,/g, '.'));
|
|
32
|
+
if (Number.isNaN(base))
|
|
33
|
+
return null;
|
|
34
|
+
const unit = (match[2] || '').toLowerCase();
|
|
35
|
+
if (unit === 'k')
|
|
36
|
+
return Math.round(base * 1000);
|
|
37
|
+
if (unit === 'm')
|
|
38
|
+
return Math.round(base * 1000000);
|
|
39
|
+
if (unit === 'b')
|
|
40
|
+
return Math.round(base * 1000000000);
|
|
41
|
+
return Math.round(base);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Maps a single search result edge to a group object.
|
|
45
|
+
*/
|
|
46
|
+
function mapSearchGroupEdge(edge) {
|
|
47
|
+
const viewModel = edge?.rendering_strategy?.view_model;
|
|
48
|
+
const profile = viewModel?.profile || {};
|
|
49
|
+
const primaryCTAProfile = viewModel?.ctas?.primary?.[0]?.profile || {};
|
|
50
|
+
const summaryText = viewModel?.primary_snippet_text_with_entities?.text || null;
|
|
51
|
+
const summaryParts = summaryText
|
|
52
|
+
? summaryText
|
|
53
|
+
.split('·')
|
|
54
|
+
.map((part) => part.trim())
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
: [];
|
|
57
|
+
const memberPart = summaryParts.find((part) => /member|thành viên|membro|mitglieder|membres/i.test(part)) || null;
|
|
58
|
+
return {
|
|
59
|
+
groupID: profile.id || null,
|
|
60
|
+
name: profile.name || null,
|
|
61
|
+
url: profile.url || primaryCTAProfile.url || null,
|
|
62
|
+
profileUrl: profile.profile_url || profile.url || primaryCTAProfile.url || null,
|
|
63
|
+
imageSrc: profile.profile_picture?.uri || null,
|
|
64
|
+
summary: summaryText,
|
|
65
|
+
privacy: summaryParts[0] || null,
|
|
66
|
+
memberText: memberPart,
|
|
67
|
+
memberCount: memberPart ? parseLocalizedCount(memberPart) : null,
|
|
68
|
+
joinState: primaryCTAProfile.viewer_join_state || null,
|
|
69
|
+
hasMembershipQuestions: typeof primaryCTAProfile.has_membership_questions === 'boolean'
|
|
70
|
+
? primaryCTAProfile.has_membership_questions
|
|
71
|
+
: null,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Parses the HTTP response body, handling both pre-parsed objects and raw strings.
|
|
76
|
+
*/
|
|
77
|
+
function parseResponseBody(body) {
|
|
78
|
+
if (typeof body === 'object' && body !== null && !Buffer.isBuffer(body)) {
|
|
79
|
+
return body;
|
|
80
|
+
}
|
|
81
|
+
const raw = typeof body === 'string' ? body : body.toString();
|
|
82
|
+
const normalized = raw.replace(/^for \(;;\);\s*/, '');
|
|
83
|
+
try {
|
|
84
|
+
return JSON.parse(normalized);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
const lines = normalized.split('\n').filter(Boolean);
|
|
88
|
+
return JSON.parse(lines[0]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Searches for Facebook groups matching the given keyword.
|
|
93
|
+
* Uses Facebook's Search Comet endpoint with GROUPS_TAB_GLOBAL experience.
|
|
94
|
+
* @async
|
|
95
|
+
* @param {string} keyword The search keyword.
|
|
96
|
+
* @param {Object} [options] Optional parameters.
|
|
97
|
+
* @param {number} [options.limit=10] Number of results per page.
|
|
98
|
+
* @param {string|null} [options.cursor=null] Pagination cursor from a previous result.
|
|
99
|
+
* @param {string} [options.locale='vi_VN'] Locale for the search request.
|
|
100
|
+
* @returns {Promise<{ groups: any[]; cursor: string | null; hasNextPage: boolean }>}
|
|
101
|
+
* @throws {Error} If the keyword is missing or the API request fails.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* const result = await api.searchGroups('gaming');
|
|
105
|
+
* console.log(result.groups); // Array of group objects
|
|
106
|
+
* console.log(result.cursor); // cursor string for next page
|
|
107
|
+
* console.log(result.hasNextPage);
|
|
108
|
+
*
|
|
109
|
+
* // Page 2
|
|
110
|
+
* const page2 = await api.searchGroups('gaming', { cursor: result.cursor });
|
|
111
|
+
*/
|
|
112
|
+
return async function searchGroups(keyword, options = {}) {
|
|
113
|
+
if (!keyword || typeof keyword !== 'string') {
|
|
114
|
+
throw new Error('searchGroups: keyword must be a non-empty string.');
|
|
115
|
+
}
|
|
116
|
+
const limit = typeof options.limit === 'number' && Number.isInteger(options.limit)
|
|
117
|
+
? options.limit
|
|
118
|
+
: 10;
|
|
119
|
+
if (limit <= 0) {
|
|
120
|
+
throw new Error('searchGroups: options.limit must be a positive integer.');
|
|
121
|
+
}
|
|
122
|
+
const locale = options.locale || 'vi_VN';
|
|
123
|
+
const bsid = createBsid();
|
|
124
|
+
const tsid = Math.random().toString();
|
|
125
|
+
const variables = {
|
|
126
|
+
allow_streaming: false,
|
|
127
|
+
args: {
|
|
128
|
+
callsite: 'comet:groups_search',
|
|
129
|
+
config: {
|
|
130
|
+
exact_match: false,
|
|
131
|
+
high_confidence_config: null,
|
|
132
|
+
intercept_config: null,
|
|
133
|
+
sts_disambiguation: null,
|
|
134
|
+
watch_config: null,
|
|
135
|
+
},
|
|
136
|
+
context: {
|
|
137
|
+
bsid,
|
|
138
|
+
tsid,
|
|
139
|
+
},
|
|
140
|
+
experience: {
|
|
141
|
+
client_defined_experiences: ['ADS_PARALLEL_FETCH'],
|
|
142
|
+
encoded_server_defined_params: null,
|
|
143
|
+
fbid: null,
|
|
144
|
+
type: 'GROUPS_TAB_GLOBAL',
|
|
145
|
+
},
|
|
146
|
+
filters: [],
|
|
147
|
+
text: keyword,
|
|
148
|
+
},
|
|
149
|
+
count: limit,
|
|
150
|
+
cursor: options.cursor ?? null,
|
|
151
|
+
feedLocation: 'SEARCH',
|
|
152
|
+
feedbackSource: 23,
|
|
153
|
+
fetch_filters: true,
|
|
154
|
+
focusCommentID: null,
|
|
155
|
+
locale: null,
|
|
156
|
+
privacySelectorRenderLocation: 'COMET_STREAM',
|
|
157
|
+
referringStoryRenderLocation: null,
|
|
158
|
+
renderLocation: 'search_results_page',
|
|
159
|
+
scale: 1,
|
|
160
|
+
stream_initial_count: 0,
|
|
161
|
+
useDefaultActor: false,
|
|
162
|
+
__relay_internal__pv__GHLShouldChangeAdIdFieldNamerelayprovider: true,
|
|
163
|
+
__relay_internal__pv__GHLShouldChangeSponsoredDataFieldNamerelayprovider: true,
|
|
164
|
+
__relay_internal__pv__CometFeedStory_enable_post_permalink_white_space_clickrelayprovider: false,
|
|
165
|
+
__relay_internal__pv__CometUFICommentActionLinksRewriteEnabledrelayprovider: false,
|
|
166
|
+
__relay_internal__pv__CometUFICommentAvatarStickerAnimatedImagerelayprovider: false,
|
|
167
|
+
__relay_internal__pv__IsWorkUserrelayprovider: false,
|
|
168
|
+
__relay_internal__pv__TestPilotShouldIncludeDemoAdUseCaserelayprovider: false,
|
|
169
|
+
__relay_internal__pv__FBReels_deprecate_short_form_video_context_gkrelayprovider: true,
|
|
170
|
+
__relay_internal__pv__FBReels_enable_view_dubbed_audio_type_gkrelayprovider: true,
|
|
171
|
+
__relay_internal__pv__CometImmersivePhotoCanUserDisable3DMotionrelayprovider: false,
|
|
172
|
+
__relay_internal__pv__WorkCometIsEmployeeGKProviderrelayprovider: false,
|
|
173
|
+
__relay_internal__pv__IsMergQAPollsrelayprovider: false,
|
|
174
|
+
__relay_internal__pv__FBReelsMediaFooter_comet_enable_reels_ads_gkrelayprovider: true,
|
|
175
|
+
__relay_internal__pv__CometUFIReactionsEnableShortNamerelayprovider: false,
|
|
176
|
+
__relay_internal__pv__CometUFICommentAutoTranslationTyperelayprovider: 'ORIGINAL',
|
|
177
|
+
__relay_internal__pv__CometUFIShareActionMigrationrelayprovider: true,
|
|
178
|
+
__relay_internal__pv__CometUFISingleLineUFIrelayprovider: false,
|
|
179
|
+
__relay_internal__pv__CometUFI_dedicated_comment_routable_dialog_gkrelayprovider: true,
|
|
180
|
+
__relay_internal__pv__FBReelsIFUTileContent_reelsIFUPlayOnHoverrelayprovider: true,
|
|
181
|
+
__relay_internal__pv__GroupsCometGYSJFeedItemHeightrelayprovider: 150,
|
|
182
|
+
__relay_internal__pv__ShouldEnableBakedInTextStoriesrelayprovider: false,
|
|
183
|
+
__relay_internal__pv__StoriesShouldIncludeFbNotesrelayprovider: false,
|
|
184
|
+
};
|
|
185
|
+
const form = {
|
|
186
|
+
av: ctx.i_userID || ctx.userID,
|
|
187
|
+
__user: ctx.i_userID || ctx.userID,
|
|
188
|
+
__a: '1',
|
|
189
|
+
fb_dtsg: ctx.fb_dtsg,
|
|
190
|
+
jazoest: ctx.jazoest,
|
|
191
|
+
lsd: ctx.lsd || '',
|
|
192
|
+
locale,
|
|
193
|
+
fb_api_caller_class: 'RelayModern',
|
|
194
|
+
fb_api_req_friendly_name: 'SearchCometResultsPaginatedResultsQuery',
|
|
195
|
+
server_timestamps: 'true',
|
|
196
|
+
variables: JSON.stringify(variables),
|
|
197
|
+
doc_id: '26131941349797315',
|
|
198
|
+
};
|
|
199
|
+
const customHeader = {
|
|
200
|
+
'x-fb-friendly-name': 'SearchCometResultsPaginatedResultsQuery',
|
|
201
|
+
'x-fb-lsd': ctx.lsd || '',
|
|
202
|
+
'x-asbd-id': '359341',
|
|
203
|
+
origin: 'https://www.facebook.com',
|
|
204
|
+
referer: `https://www.facebook.com/groups/search/groups_home?q=${encodeURIComponent(keyword)}&locale=${encodeURIComponent(locale)}`,
|
|
205
|
+
};
|
|
206
|
+
const res = await utils.post('https://www.facebook.com/api/graphql/', ctx.jar, form, ctx.globalOptions, ctx, customHeader);
|
|
207
|
+
const data = parseResponseBody(res.body);
|
|
208
|
+
if (data?.errors) {
|
|
209
|
+
throw new Error(JSON.stringify(data.errors));
|
|
210
|
+
}
|
|
211
|
+
const results = data?.data?.serpResponse?.results;
|
|
212
|
+
const edges = Array.isArray(results?.edges) ? results.edges : [];
|
|
213
|
+
const pageInfo = results?.page_info || {};
|
|
214
|
+
return {
|
|
215
|
+
groups: edges.map(mapSearchGroupEdge),
|
|
216
|
+
cursor: pageInfo.end_cursor || null,
|
|
217
|
+
hasNextPage: Boolean(pageInfo.has_next_page),
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=searchGroups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchGroups.js","sourceRoot":"","sources":["../../../../src/deltas/apis/users/searchGroups.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -88,8 +88,30 @@ export interface PostComment {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
export interface GetPostCommentsOptions {
|
|
91
|
-
story_fbid
|
|
91
|
+
/** Numeric story_fbid (used with id to construct permalink.php URL) */
|
|
92
|
+
story_fbid?: string;
|
|
93
|
+
/** Facebook user/page ID (used with story_fbid) */
|
|
92
94
|
id?: string;
|
|
95
|
+
/** Direct Facebook post URL (e.g. https://www.facebook.com/user/posts/pfbid...) */
|
|
96
|
+
url?: string;
|
|
97
|
+
/** Cursor for fetching next page of comments (from page_info.end_cursor) */
|
|
98
|
+
after?: string;
|
|
99
|
+
/** GraphQL feedback ID for pagination (from page_info.feedback_id) */
|
|
100
|
+
feedback_id?: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface PageInfo {
|
|
104
|
+
end_cursor: string | null;
|
|
105
|
+
has_next_page: boolean;
|
|
106
|
+
has_previous_page?: boolean;
|
|
107
|
+
start_cursor?: string | null;
|
|
108
|
+
/** GraphQL feedback ID needed for pagination queries */
|
|
109
|
+
feedback_id?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface GetPostCommentsResult {
|
|
113
|
+
comments: PostComment[];
|
|
114
|
+
page_info: PageInfo | null;
|
|
93
115
|
}
|
|
94
116
|
|
|
95
117
|
export interface ShareResult {
|
|
@@ -374,6 +396,56 @@ export interface ThreadInfo {
|
|
|
374
396
|
};
|
|
375
397
|
}
|
|
376
398
|
|
|
399
|
+
export interface SearchGroupOptions {
|
|
400
|
+
limit?: number;
|
|
401
|
+
cursor?: string | null;
|
|
402
|
+
locale?: string;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export interface SearchGroupItem {
|
|
406
|
+
groupID: string | null;
|
|
407
|
+
name: string | null;
|
|
408
|
+
url: string | null;
|
|
409
|
+
profileUrl: string | null;
|
|
410
|
+
imageSrc: string | null;
|
|
411
|
+
summary: string | null;
|
|
412
|
+
privacy: string | null;
|
|
413
|
+
memberText: string | null;
|
|
414
|
+
memberCount: number | null;
|
|
415
|
+
joinState: string | null;
|
|
416
|
+
hasMembershipQuestions: boolean | null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export interface SearchGroupResult {
|
|
420
|
+
groups: SearchGroupItem[];
|
|
421
|
+
cursor: string | null;
|
|
422
|
+
hasNextPage: boolean;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export interface GroupModule {
|
|
426
|
+
join(groupID: string): Promise<any>;
|
|
427
|
+
leave(groupID: string): Promise<any>;
|
|
428
|
+
getJoinedGroups(
|
|
429
|
+
cursor?: string | null,
|
|
430
|
+
count?: number,
|
|
431
|
+
): Promise<{
|
|
432
|
+
groups: Array<{
|
|
433
|
+
id: string;
|
|
434
|
+
name: string;
|
|
435
|
+
imageUri: string;
|
|
436
|
+
url: string;
|
|
437
|
+
memberCount: string;
|
|
438
|
+
privacy: string;
|
|
439
|
+
}>;
|
|
440
|
+
endCursor: string | null;
|
|
441
|
+
hasNextPage: boolean;
|
|
442
|
+
}>;
|
|
443
|
+
searchGroup(
|
|
444
|
+
keyword: string,
|
|
445
|
+
options?: SearchGroupOptions,
|
|
446
|
+
): Promise<SearchGroupResult>;
|
|
447
|
+
}
|
|
448
|
+
|
|
377
449
|
export interface MessageObject {
|
|
378
450
|
body?: string;
|
|
379
451
|
attachment?: ReadStream[];
|
|
@@ -609,8 +681,9 @@ export interface API {
|
|
|
609
681
|
): Promise<DeletePostResult>;
|
|
610
682
|
getComments(
|
|
611
683
|
postID: string | GetPostCommentsOptions,
|
|
612
|
-
|
|
613
|
-
|
|
684
|
+
optionsOrCallback?: GetPostCommentsOptions | Callback<GetPostCommentsResult>,
|
|
685
|
+
callback?: Callback<GetPostCommentsResult>,
|
|
686
|
+
): Promise<GetPostCommentsResult>;
|
|
614
687
|
uploadPhoto(
|
|
615
688
|
photoPath: string,
|
|
616
689
|
callback?: Callback<UploadPhotoResult>,
|
|
@@ -852,6 +925,9 @@ export interface API {
|
|
|
852
925
|
/** Add an external module to extend the API. */
|
|
853
926
|
addExternalModule(moduleObj: Record<string, Function>): void;
|
|
854
927
|
|
|
928
|
+
/** Group-related API methods. */
|
|
929
|
+
group: GroupModule;
|
|
930
|
+
|
|
855
931
|
/** Allow accessing dynamically loaded methods. */
|
|
856
932
|
[key: string]: any;
|
|
857
933
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @namespace api.group
|
|
3
|
+
* @description A module for joining, leaving, and listing Facebook groups.
|
|
4
|
+
* @license Ex-it
|
|
5
|
+
*/
|
|
6
|
+
export default function (defaultFuncs: any, api: any, ctx: any): {
|
|
7
|
+
/**
|
|
8
|
+
* Joins a Facebook group.
|
|
9
|
+
* @async
|
|
10
|
+
* @param {string} groupID The ID of the group to join.
|
|
11
|
+
* @returns {Promise<Object>} A promise that resolves to the API response data on success.
|
|
12
|
+
* @throws {Error} If the groupID is missing or the API request fails.
|
|
13
|
+
*/
|
|
14
|
+
join: (groupID: string, inviteShortLinkKey?: string | null) => Promise<any>;
|
|
15
|
+
/**
|
|
16
|
+
* Leaves a Facebook group.
|
|
17
|
+
* @async
|
|
18
|
+
* @param {string} groupID The ID of the group to leave.
|
|
19
|
+
* @returns {Promise<Object>} A promise that resolves to the API response data on success.
|
|
20
|
+
* @throws {Error} If the groupID is missing or the API request fails.
|
|
21
|
+
*/
|
|
22
|
+
leave: (groupID: string) => Promise<any>;
|
|
23
|
+
/**
|
|
24
|
+
* Invites friends to a Facebook group.
|
|
25
|
+
* @async
|
|
26
|
+
* @param {string} groupID The ID of the group to invite friends to.
|
|
27
|
+
* @param {string[]} userIDs Array of user IDs to invite.
|
|
28
|
+
* @returns {Promise<Object>} A promise that resolves to the API response data on success.
|
|
29
|
+
* @throws {Error} If the groupID or userIDs are missing or the API request fails.
|
|
30
|
+
*/
|
|
31
|
+
inviteFriends: (groupID: string, userIDs: string[]) => Promise<any>;
|
|
32
|
+
/**
|
|
33
|
+
* Fetches the logged-in user's joined Facebook groups with cursor-based pagination.
|
|
34
|
+
*
|
|
35
|
+
* @param {string|null} [cursor=null] Pagination cursor from a previous result's `endCursor`.
|
|
36
|
+
* Pass `null` (or omit) for the first page.
|
|
37
|
+
* @param {number} [count=10] Number of groups to fetch per page (used for pagination requests).
|
|
38
|
+
* @returns {Promise<JoinedGroupsResult>} Groups list and pagination info.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Page 1
|
|
42
|
+
* const page1 = await api.group.getJoinedGroups();
|
|
43
|
+
* console.log(page1.groups); // Array of GroupEntry
|
|
44
|
+
* console.log(page1.endCursor); // cursor string for next page
|
|
45
|
+
*
|
|
46
|
+
* // Page 2+
|
|
47
|
+
* const page2 = await api.group.getJoinedGroups(page1.endCursor);
|
|
48
|
+
*/
|
|
49
|
+
getJoinedGroups: (cursor?: string | null, count?: number) => Promise<{
|
|
50
|
+
groups: {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
imageUri: string;
|
|
54
|
+
url: string;
|
|
55
|
+
memberCount: string;
|
|
56
|
+
privacy: string;
|
|
57
|
+
}[];
|
|
58
|
+
endCursor: string | null;
|
|
59
|
+
hasNextPage: boolean;
|
|
60
|
+
}>;
|
|
61
|
+
/**
|
|
62
|
+
* Search Facebook groups by keyword.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} keyword Search keyword.
|
|
65
|
+
* @param {{ limit?: number; cursor?: string | null; locale?: string }} [options]
|
|
66
|
+
* @returns {Promise<{ groups: any[]; cursor: string | null; hasNextPage: boolean }>} Search result and pagination info.
|
|
67
|
+
*/
|
|
68
|
+
searchGroup: (keyword: string, options?: {
|
|
69
|
+
limit?: number;
|
|
70
|
+
cursor?: string | null;
|
|
71
|
+
locale?: string;
|
|
72
|
+
}) => Promise<{
|
|
73
|
+
groups: any[];
|
|
74
|
+
cursor: string | null;
|
|
75
|
+
hasNextPage: boolean;
|
|
76
|
+
}>;
|
|
77
|
+
/**
|
|
78
|
+
* Alias for searchGroup.
|
|
79
|
+
* @see searchGroup
|
|
80
|
+
*/
|
|
81
|
+
searchGroups: (keyword: string, options?: {
|
|
82
|
+
limit?: number;
|
|
83
|
+
cursor?: string | null;
|
|
84
|
+
locale?: string;
|
|
85
|
+
}) => Promise<{
|
|
86
|
+
groups: any[];
|
|
87
|
+
cursor: string | null;
|
|
88
|
+
hasNextPage: boolean;
|
|
89
|
+
}>;
|
|
90
|
+
};
|
|
@@ -21,7 +21,7 @@ export default function (defaultFuncs: any, api: any, ctx: any): {
|
|
|
21
21
|
postID: any;
|
|
22
22
|
data: any;
|
|
23
23
|
}>;
|
|
24
|
-
getComments: (postID: any, callback
|
|
24
|
+
getComments: (postID: any, optionsOrCallback?: any, callback?: any) => Promise<any>;
|
|
25
25
|
uploadPhoto: (photoPath: any, callback: any) => Promise<any>;
|
|
26
26
|
uploadVideo: (videoPath: any, callback: any) => Promise<any>;
|
|
27
27
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type SearchGroupOptions = {
|
|
2
|
+
limit?: number;
|
|
3
|
+
cursor?: string | null;
|
|
4
|
+
locale?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* @ChoruOfficial
|
|
8
|
+
* @description Search Facebook groups by keyword using SearchCometResultsPaginatedResultsQuery.
|
|
9
|
+
*/
|
|
10
|
+
export default function searchGroupModule(defaultFuncs: any, api: any, ctx: any): (keyword: string, options?: SearchGroupOptions) => Promise<{
|
|
11
|
+
groups: any[];
|
|
12
|
+
cursor: string | null;
|
|
13
|
+
hasNextPage: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description A module for searching Facebook groups by keyword.
|
|
3
|
+
* Calls SearchCometResultsPaginatedResultsQuery via /api/graphql/.
|
|
4
|
+
* @param {Object} defaultFuncs The default functions provided by the API wrapper.
|
|
5
|
+
* @param {Object} api The full API object.
|
|
6
|
+
* @param {Object} ctx The context object containing the user's session state.
|
|
7
|
+
* @returns {Function} An async function that searches for groups by keyword.
|
|
8
|
+
*/
|
|
9
|
+
export default function searchGroupsModule(defaultFuncs: any, api: any, ctx: any): (keyword: string, options?: {
|
|
10
|
+
limit?: number;
|
|
11
|
+
cursor?: string | null;
|
|
12
|
+
locale?: string;
|
|
13
|
+
}) => Promise<{
|
|
14
|
+
groups: any[];
|
|
15
|
+
cursor: string | null;
|
|
16
|
+
hasNextPage: boolean;
|
|
17
|
+
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bb-fca",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "BB-FCA is a powerful and user-friendly Facebook Chat API wrapper for Node.js, designed to simplify the process of creating chatbots and automating interactions on Facebook Messenger. With BB-FCA, developers can easily send messages, manage conversations, and interact with the Facebook Messenger platform using a simple and intuitive API.",
|
|
5
5
|
"main": "dist/core/client.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|