Search code examples
gogoogle-admin-sdk

How do I iterate over the paginated list returned by Google Admin SDK UsersService.List?


So I am reading a paginated list of users successfully from the Admin API. I can see the NextPageToken as well as the first page of results. But there seems to be nothing in the returned UsersListCall object for me to iterate over? No place to specify the next page token, as we'd do with the HTTP style calls. Can someone give me a hint on where to start to iterate through these pages?

    adminService, err := admin.NewService(ctx,
        option.WithCredentials(credentials),
    )
    [...]
    users, err := adminService.Users.List().Customer("my_customer").Do()
    if err != nil {
        if e, ok := err.(*googleapi.Error); ok {
            fmt.Printf("Error code: %v\n", e.Code)
            fmt.Printf("Message: %v\n", e.Message)
        } else {
            fmt.Printf("Error: %v\n", err)
        }
        os.Exit(1)
    }

    fmt.Printf("token: %s\n", users.NextPageToken)

    for _, user := range users.Users {
        fmt.Printf("User: %s (%s)\n", user.Name.FullName, user.PrimaryEmail)
    }

Solution

  • The "trick" is to create an initial request and then use it to page with the response's NextPageToken until there are no more tokens.

    Try:

    package main
    
    import (
        "context"
        "fmt"
        "os"
    
        admin "google.golang.org/api/admin/directory/v1"
        "google.golang.org/api/googleapi"
    )
    
    func main() {
        ctx := context.Background()
        adminService, err := admin.NewService(ctx)
        if err != nil {
            panic(err)
        }
    
    
        // Create a request
        rqst := adminService.Users.List().Customer("my_customer")
        // Loop
        for {
            // Do'ing the request
            resp, err := rqst.Do()
            if err != nil {
                if e, ok := err.(*googleapi.Error); ok {
                    fmt.Printf("Error code: %v\n", e.Code)
                    fmt.Printf("Message: %v\n", e.Message)
                } else {
                    fmt.Printf("Error: %v\n", err)
                }
                os.Exit(1)
            }
    
            for _, user := range resp.Users {
                fmt.Printf("User: %s (%s)\n", user.Name.FullName, user.PrimaryEmail)
            }
    
            // Until there aren't any more pages
            if resp.NextPageToken == "" {
                break
            }
    
            // Using the NextPageToken to page
            rqst.PageToken(resp.NextPageToken)
        }
    }