fix: add cursor pagination support to REST fallback for followers/following
When GraphQL endpoints return 404 and fall back to REST API v1.1, pagination now works correctly by: - Accepting cursor parameter in getFollowersViaRest and getFollowingViaRest - Passing cursor to REST API requests - Extracting next_cursor_str from REST responses - Returning nextCursor in the result for proper --all pagination
This commit is contained in:
@@ -65,7 +65,7 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
.filter((u) => u !== null);
|
||||
}
|
||||
|
||||
private async getFollowersViaRest(userId: string, count: number): Promise<FollowingResult> {
|
||||
private async getFollowersViaRest(userId: string, count: number, cursor?: string): Promise<FollowingResult> {
|
||||
const params = new URLSearchParams({
|
||||
user_id: userId,
|
||||
count: String(count),
|
||||
@@ -73,6 +73,10 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
include_user_entities: 'false',
|
||||
});
|
||||
|
||||
if (cursor) {
|
||||
params.set('cursor', cursor);
|
||||
}
|
||||
|
||||
const urls = [
|
||||
`https://x.com/i/api/1.1/followers/list.json?${params.toString()}`,
|
||||
`https://api.twitter.com/1.1/followers/list.json?${params.toString()}`,
|
||||
@@ -95,11 +99,13 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
|
||||
const data = (await response.json()) as {
|
||||
users?: RestUser[];
|
||||
next_cursor_str?: string;
|
||||
};
|
||||
|
||||
const users = this.parseUsersFromRestResponse(data.users);
|
||||
const nextCursor = data.next_cursor_str && data.next_cursor_str !== '0' ? data.next_cursor_str : undefined;
|
||||
|
||||
return { success: true, users };
|
||||
return { success: true, users, nextCursor };
|
||||
} catch (error) {
|
||||
lastError = error instanceof Error ? error.message : String(error);
|
||||
}
|
||||
@@ -108,7 +114,7 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
return { success: false, error: lastError ?? 'Unknown error fetching followers' };
|
||||
}
|
||||
|
||||
private async getFollowingViaRest(userId: string, count: number): Promise<FollowingResult> {
|
||||
private async getFollowingViaRest(userId: string, count: number, cursor?: string): Promise<FollowingResult> {
|
||||
const params = new URLSearchParams({
|
||||
user_id: userId,
|
||||
count: String(count),
|
||||
@@ -116,6 +122,10 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
include_user_entities: 'false',
|
||||
});
|
||||
|
||||
if (cursor) {
|
||||
params.set('cursor', cursor);
|
||||
}
|
||||
|
||||
const urls = [
|
||||
`https://x.com/i/api/1.1/friends/list.json?${params.toString()}`,
|
||||
`https://api.twitter.com/1.1/friends/list.json?${params.toString()}`,
|
||||
@@ -138,11 +148,13 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
|
||||
const data = (await response.json()) as {
|
||||
users?: RestUser[];
|
||||
next_cursor_str?: string;
|
||||
};
|
||||
|
||||
const users = this.parseUsersFromRestResponse(data.users);
|
||||
const nextCursor = data.next_cursor_str && data.next_cursor_str !== '0' ? data.next_cursor_str : undefined;
|
||||
|
||||
return { success: true, users };
|
||||
return { success: true, users, nextCursor };
|
||||
} catch (error) {
|
||||
lastError = error instanceof Error ? error.message : String(error);
|
||||
}
|
||||
@@ -333,8 +345,7 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
|
||||
// GraphQL Following can also return 404 (queryId churn / endpoint flakiness).
|
||||
// Fallback to the internal v1.1 REST endpoint used by the web client through the relay.
|
||||
// Note: REST fallback does not support cursor pagination.
|
||||
const restAttempt = await this.getFollowingViaRest(userId, count);
|
||||
const restAttempt = await this.getFollowingViaRest(userId, count, cursor);
|
||||
if (restAttempt.success) {
|
||||
return restAttempt;
|
||||
}
|
||||
@@ -439,8 +450,7 @@ export function withUsers<TBase extends AbstractConstructor<TwitterClientBase>>(
|
||||
|
||||
// GraphQL Followers regularly returns 404 (queryId churn / endpoint flakiness).
|
||||
// Fallback to the internal v1.1 REST endpoint used by the web client through the relay.
|
||||
// Note: REST fallback does not support cursor pagination.
|
||||
const restAttempt = await this.getFollowersViaRest(userId, count);
|
||||
const restAttempt = await this.getFollowersViaRest(userId, count, cursor);
|
||||
if (restAttempt.success) {
|
||||
return restAttempt;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user