notion-sdk-php icon indicating copy to clipboard operation
notion-sdk-php copied to clipboard

[BUG] Users\Client->findAll does not paginate

Open utdrmac opened this issue 1 year ago • 3 comments

Describe the bug Using findAll() to retrieve all users only returns the first 100 users. Notion API docs indicate you must paginate using the 'next_cursor' after checking 'has_more' in the result. There is no option to provide this information to the function either.

To Reproduce Steps to reproduce the behavior:

  1. Use Users\Client->findAll()
  2. Observe the returning array is only 100 elements

Expected behavior Either A) findAll() should paginate automatically, and return the entire list of users, or B) provide some way to pass the cursor so the next call fetches the next page.

utdrmac avatar Nov 11 '24 17:11 utdrmac

+1 Would be nice to have a way to get all the users

ALameLlama avatar Sep 18 '25 02:09 ALameLlama

I believe something like this would work if we wanted to do this for the users

    public function findAll(): array
    {
        $url = "https://api.notion.com/v1/users";
        $allUsers = [];
        $startCursor = null;

        do {
            $queryParams = $startCursor ? ['start_cursor' => $startCursor] : [];
            $requestUrl = $url . ($startCursor ? '?' . http_build_query($queryParams) : '');

            $request = Http::createRequest($requestUrl, $this->config);

            /** @var array{ results: UserJson[], has_more: bool, next_cursor: ?string } $body */
            $body = Http::sendRequest($request, $this->config);

            $allUsers = array_merge(
                $allUsers,
                array_map(
                    function (array $userData): User {
                        return User::fromArray($userData);
                    },
                    $body["results"]
                )
            );

            $startCursor = $body['next_cursor'] ?? null;
        } while (!empty($body['has_more']));

        return $allUsers;
    }

ALameLlama avatar Sep 18 '25 03:09 ALameLlama

I implemented something very similar in my own Notion class. I turned it into a "cron job" using cakephp-queue which runs weekly, and stores the users in Cache::write('notionusers', $allUsers); (simple file-based cache) This way, all my user lookups are fast, and local. We don't hire frequently enough for it to run any more frequently ;)

utdrmac avatar Oct 02 '25 21:10 utdrmac