Page through all Pinterest boards until the bookmark ends.

Replace the 20-page hard stop with a while-loop that follows bookmarks to completion, keeping only safety breaks for a repeated cursor or an absurd page ceiling.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Paulo Castellano 2026-07-24 22:12:50 -03:00
parent c040ba4686
commit 491895cbd9
2 changed files with 65 additions and 7 deletions

View file

@ -405,7 +405,8 @@ private function waitForMediaProcessing(SocialAccount $account, string $mediaId,
}
/**
* Get user's boards for board selection (follows Pinterest bookmark pagination).
* Get user's boards for board selection (follows Pinterest bookmark pagination
* until the API stops returning a bookmark).
*
* @return list<array<string, mixed>>
*/
@ -417,9 +418,23 @@ public function getBoards(SocialAccount $account): array
$boards = [];
$bookmark = null;
$maxPages = 20;
$pages = 0;
// Absurd ceiling only — normal accounts exit when bookmark is blank.
$maxPages = 1000;
while (true) {
$pages++;
if ($pages > $maxPages) {
Log::warning('Pinterest get boards hit safety page cap', [
'account_id' => $account->id,
'pages' => $pages,
'boards' => count($boards),
]);
break;
}
for ($page = 0; $page < $maxPages; $page++) {
$query = ['page_size' => 100];
if (filled($bookmark)) {
@ -441,11 +456,23 @@ public function getBoards(SocialAccount $account): array
array_push($boards, ...$items);
}
$bookmark = data_get($payload, 'bookmark');
$nextBookmark = data_get($payload, 'bookmark');
if (blank($bookmark)) {
if (blank($nextBookmark)) {
break;
}
if ($nextBookmark === $bookmark) {
Log::warning('Pinterest get boards returned a repeated bookmark', [
'account_id' => $account->id,
'pages' => $pages,
'boards' => count($boards),
]);
break;
}
$bookmark = $nextBookmark;
}
return $boards;

View file

@ -531,14 +531,45 @@
'items' => [
['id' => 'board_2', 'name' => 'Board 2'],
],
'bookmark' => 'page-3',
], 200)
->push([
'items' => [
['id' => 'board_3', 'name' => 'Board 3'],
],
], 200),
]);
$boards = $this->publisher->getBoards($this->socialAccount);
expect($boards)->toHaveCount(3)
->and($boards[0]['id'])->toBe('board_1')
->and($boards[1]['id'])->toBe('board_2')
->and($boards[2]['id'])->toBe('board_3');
Http::assertSentCount(3);
});
test('pinterest publisher stops board pagination on a repeated bookmark', function () {
Http::fake([
config('trypost.platforms.pinterest.api').'/boards*' => Http::sequence()
->push([
'items' => [['id' => 'board_1', 'name' => 'Board 1']],
'bookmark' => 'stuck',
], 200)
->push([
'items' => [['id' => 'board_2', 'name' => 'Board 2']],
'bookmark' => 'stuck',
], 200)
->push([
'items' => [['id' => 'should_not_fetch', 'name' => 'Nope']],
], 200),
]);
$boards = $this->publisher->getBoards($this->socialAccount);
expect($boards)->toHaveCount(2)
->and($boards[0]['id'])->toBe('board_1')
->and($boards[1]['id'])->toBe('board_2');
->and(collect($boards)->pluck('id')->all())->toBe(['board_1', 'board_2']);
Http::assertSentCount(2);
});