bb-fca 2.0.6 → 2.0.7
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/dist/deltas/apis/posting/group.js +607 -0
- package/dist/deltas/apis/posting/group.js.map +1 -0
- 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 +53 -0
- package/dist/types/deltas/apis/posting/group.d.ts +90 -0
- 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/request.txt +60 -0
- package/src/deltas/apis/posting/group.ts +754 -0
- package/src/types/index.d.ts +53 -0
- package/LICENSE-MIT +0 -21
- package/examples/post.example.js +0 -189
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = searchGroupModule;
|
|
4
|
+
const utils = require("../../../utils");
|
|
5
|
+
function parseResponseBody(body) {
|
|
6
|
+
if (typeof body === 'object' && body !== null && !Buffer.isBuffer(body)) {
|
|
7
|
+
return body;
|
|
8
|
+
}
|
|
9
|
+
const raw = typeof body === 'string' ? body : body.toString();
|
|
10
|
+
const normalized = raw.replace(/^for \(;;\);\s*/, '');
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(normalized);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
const lines = normalized.split('\n').filter(Boolean);
|
|
16
|
+
return JSON.parse(lines[0]);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function parseLocalizedCount(text) {
|
|
20
|
+
const match = text.match(/([\d.,]+)\s*([kKmMbB])?/);
|
|
21
|
+
if (!match) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const base = Number((match[1] || '').replace(/,/g, '.'));
|
|
25
|
+
if (Number.isNaN(base)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const unit = (match[2] || '').toLowerCase();
|
|
29
|
+
if (unit === 'k') {
|
|
30
|
+
return Math.round(base * 1000);
|
|
31
|
+
}
|
|
32
|
+
if (unit === 'm') {
|
|
33
|
+
return Math.round(base * 1000000);
|
|
34
|
+
}
|
|
35
|
+
if (unit === 'b') {
|
|
36
|
+
return Math.round(base * 1000000000);
|
|
37
|
+
}
|
|
38
|
+
return Math.round(base);
|
|
39
|
+
}
|
|
40
|
+
function mapGroupEdge(edge) {
|
|
41
|
+
const viewModel = edge?.rendering_strategy?.view_model;
|
|
42
|
+
const profile = viewModel?.profile || {};
|
|
43
|
+
const primaryCTAProfile = viewModel?.ctas?.primary?.[0]?.profile || {};
|
|
44
|
+
const summaryText = viewModel?.primary_snippet_text_with_entities?.text || null;
|
|
45
|
+
const summaryParts = summaryText
|
|
46
|
+
? summaryText.split('·').map((part) => part.trim()).filter(Boolean)
|
|
47
|
+
: [];
|
|
48
|
+
const memberPart = summaryParts.find((part) => /member|thành viên|membro|mitglieder|membres/i.test(part)) || null;
|
|
49
|
+
return {
|
|
50
|
+
groupID: profile.id || null,
|
|
51
|
+
name: profile.name || null,
|
|
52
|
+
url: profile.url || primaryCTAProfile.url || null,
|
|
53
|
+
profileUrl: profile.profile_url || profile.url || primaryCTAProfile.url || null,
|
|
54
|
+
imageSrc: profile.profile_picture?.uri || null,
|
|
55
|
+
summary: summaryText,
|
|
56
|
+
privacy: summaryParts[0] || null,
|
|
57
|
+
memberText: memberPart,
|
|
58
|
+
memberCount: memberPart ? parseLocalizedCount(memberPart) : null,
|
|
59
|
+
joinState: primaryCTAProfile.viewer_join_state || null,
|
|
60
|
+
hasMembershipQuestions: typeof primaryCTAProfile.has_membership_questions === 'boolean'
|
|
61
|
+
? primaryCTAProfile.has_membership_questions
|
|
62
|
+
: null,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @ChoruOfficial
|
|
67
|
+
* @description Search Facebook groups by keyword using SearchCometResultsPaginatedResultsQuery.
|
|
68
|
+
*/
|
|
69
|
+
function searchGroupModule(defaultFuncs, api, ctx) {
|
|
70
|
+
/**
|
|
71
|
+
* Search groups by keyword.
|
|
72
|
+
* @param {string} keyword The keyword to search.
|
|
73
|
+
* @param {SearchGroupOptions} [options] Optional pagination and locale options.
|
|
74
|
+
* @returns {Promise<{ groups: any[]; cursor: string | null; hasNextPage: boolean; }>} Group search result and pagination cursor.
|
|
75
|
+
*/
|
|
76
|
+
return async function searchGroup(keyword, options = {}) {
|
|
77
|
+
if (!keyword || typeof keyword !== 'string') {
|
|
78
|
+
throw new Error('searchGroup: keyword must be a non-empty string.');
|
|
79
|
+
}
|
|
80
|
+
const limit = typeof options.limit === 'number' && Number.isInteger(options.limit)
|
|
81
|
+
? options.limit
|
|
82
|
+
: 10;
|
|
83
|
+
if (limit <= 0) {
|
|
84
|
+
throw new Error('searchGroup: options.limit must be a positive integer.');
|
|
85
|
+
}
|
|
86
|
+
const variables = {
|
|
87
|
+
allow_streaming: false,
|
|
88
|
+
args: {
|
|
89
|
+
callsite: 'comet:groups_search',
|
|
90
|
+
config: {
|
|
91
|
+
exact_match: false,
|
|
92
|
+
high_confidence_config: null,
|
|
93
|
+
intercept_config: null,
|
|
94
|
+
sts_disambiguation: null,
|
|
95
|
+
watch_config: null,
|
|
96
|
+
},
|
|
97
|
+
context: {
|
|
98
|
+
bsid: null,
|
|
99
|
+
tsid: null,
|
|
100
|
+
},
|
|
101
|
+
experience: {
|
|
102
|
+
client_defined_experiences: ['ADS_PARALLEL_FETCH'],
|
|
103
|
+
encoded_server_defined_params: null,
|
|
104
|
+
fbid: null,
|
|
105
|
+
type: 'GROUPS_TAB_GLOBAL',
|
|
106
|
+
},
|
|
107
|
+
filters: [],
|
|
108
|
+
text: keyword,
|
|
109
|
+
},
|
|
110
|
+
count: limit,
|
|
111
|
+
cursor: options.cursor ?? null,
|
|
112
|
+
feedLocation: 'SEARCH',
|
|
113
|
+
feedbackSource: 23,
|
|
114
|
+
fetch_filters: true,
|
|
115
|
+
focusCommentID: null,
|
|
116
|
+
locale: options.locale || 'vi_VN',
|
|
117
|
+
privacySelectorRenderLocation: 'COMET_STREAM',
|
|
118
|
+
referringStoryRenderLocation: null,
|
|
119
|
+
renderLocation: 'search_results_page',
|
|
120
|
+
scale: 1,
|
|
121
|
+
stream_initial_count: 0,
|
|
122
|
+
useDefaultActor: false,
|
|
123
|
+
};
|
|
124
|
+
const form = {
|
|
125
|
+
av: ctx.i_userID || ctx.userID,
|
|
126
|
+
__user: ctx.i_userID || ctx.userID,
|
|
127
|
+
__a: '1',
|
|
128
|
+
fb_dtsg: ctx.fb_dtsg,
|
|
129
|
+
jazoest: ctx.jazoest,
|
|
130
|
+
lsd: ctx.lsd || '',
|
|
131
|
+
fb_api_caller_class: 'RelayModern',
|
|
132
|
+
fb_api_req_friendly_name: 'SearchCometResultsPaginatedResultsQuery',
|
|
133
|
+
server_timestamps: 'true',
|
|
134
|
+
variables: JSON.stringify(variables),
|
|
135
|
+
doc_id: '26131941349797315',
|
|
136
|
+
};
|
|
137
|
+
const customHeader = {
|
|
138
|
+
'x-fb-friendly-name': 'SearchCometResultsPaginatedResultsQuery',
|
|
139
|
+
'x-fb-lsd': ctx.lsd || '',
|
|
140
|
+
'x-asbd-id': '359341',
|
|
141
|
+
origin: 'https://www.facebook.com',
|
|
142
|
+
referer: `https://www.facebook.com/groups/search/groups_home?q=${encodeURIComponent(keyword)}&locale=${encodeURIComponent(options.locale || 'vi_VN')}`,
|
|
143
|
+
};
|
|
144
|
+
const resData = await utils.post('https://www.facebook.com/api/graphql/', ctx.jar, form, ctx.globalOptions, ctx, customHeader);
|
|
145
|
+
const data = parseResponseBody(resData.body);
|
|
146
|
+
if (data?.errors) {
|
|
147
|
+
throw new Error(JSON.stringify(data.errors));
|
|
148
|
+
}
|
|
149
|
+
const results = data?.data?.serpResponse?.results;
|
|
150
|
+
const edges = Array.isArray(results?.edges) ? results.edges : [];
|
|
151
|
+
const pageInfo = results?.page_info || {};
|
|
152
|
+
return {
|
|
153
|
+
groups: edges.map(mapGroupEdge),
|
|
154
|
+
cursor: pageInfo.end_cursor || null,
|
|
155
|
+
hasNextPage: Boolean(pageInfo.has_next_page),
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=searchGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchGroup.js","sourceRoot":"","sources":["../../../../src/deltas/apis/threads/searchGroup.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|
@@ -374,6 +374,56 @@ export interface ThreadInfo {
|
|
|
374
374
|
};
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
export interface SearchGroupOptions {
|
|
378
|
+
limit?: number;
|
|
379
|
+
cursor?: string | null;
|
|
380
|
+
locale?: string;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export interface SearchGroupItem {
|
|
384
|
+
groupID: string | null;
|
|
385
|
+
name: string | null;
|
|
386
|
+
url: string | null;
|
|
387
|
+
profileUrl: string | null;
|
|
388
|
+
imageSrc: string | null;
|
|
389
|
+
summary: string | null;
|
|
390
|
+
privacy: string | null;
|
|
391
|
+
memberText: string | null;
|
|
392
|
+
memberCount: number | null;
|
|
393
|
+
joinState: string | null;
|
|
394
|
+
hasMembershipQuestions: boolean | null;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export interface SearchGroupResult {
|
|
398
|
+
groups: SearchGroupItem[];
|
|
399
|
+
cursor: string | null;
|
|
400
|
+
hasNextPage: boolean;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export interface GroupModule {
|
|
404
|
+
join(groupID: string): Promise<any>;
|
|
405
|
+
leave(groupID: string): Promise<any>;
|
|
406
|
+
getJoinedGroups(
|
|
407
|
+
cursor?: string | null,
|
|
408
|
+
count?: number,
|
|
409
|
+
): Promise<{
|
|
410
|
+
groups: Array<{
|
|
411
|
+
id: string;
|
|
412
|
+
name: string;
|
|
413
|
+
imageUri: string;
|
|
414
|
+
url: string;
|
|
415
|
+
memberCount: string;
|
|
416
|
+
privacy: string;
|
|
417
|
+
}>;
|
|
418
|
+
endCursor: string | null;
|
|
419
|
+
hasNextPage: boolean;
|
|
420
|
+
}>;
|
|
421
|
+
searchGroup(
|
|
422
|
+
keyword: string,
|
|
423
|
+
options?: SearchGroupOptions,
|
|
424
|
+
): Promise<SearchGroupResult>;
|
|
425
|
+
}
|
|
426
|
+
|
|
377
427
|
export interface MessageObject {
|
|
378
428
|
body?: string;
|
|
379
429
|
attachment?: ReadStream[];
|
|
@@ -852,6 +902,9 @@ export interface API {
|
|
|
852
902
|
/** Add an external module to extend the API. */
|
|
853
903
|
addExternalModule(moduleObj: Record<string, Function>): void;
|
|
854
904
|
|
|
905
|
+
/** Group-related API methods. */
|
|
906
|
+
group: GroupModule;
|
|
907
|
+
|
|
855
908
|
/** Allow accessing dynamically loaded methods. */
|
|
856
909
|
[key: string]: any;
|
|
857
910
|
}
|
|
@@ -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
|
+
};
|
|
@@ -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.7",
|
|
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",
|