Go boilerplate library for building atproto apps
atproto go
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: additional options for `ListAllRecords` call

+30 -10
+30 -10
public.go
··· 198 198 return &profile, nil 199 199 } 200 200 201 - // ListPublicRecords fetches up to limit records from a public collection. 201 + // ListPublicRecordsOpts configures a ListPublicRecords call. 202 + // All fields are optional; the zero value yields the lexicon defaults. 203 + type ListPublicRecordsOpts struct { 204 + Limit int // 0 means server default 205 + Cursor string // empty for first page 206 + Reverse bool // true returns newest-first 207 + } 208 + 209 + // ListPublicRecords fetches records from a public collection. 202 210 // Queries the user's PDS directly, so it works with any collection NSID. 203 - func (c *PublicClient) ListPublicRecords(ctx context.Context, did, collection string, limit int) ([]Record, error) { 211 + func (c *PublicClient) ListPublicRecords(ctx context.Context, did, collection string, opts ListPublicRecordsOpts) ([]Record, string, error) { 204 212 pdsEndpoint, err := c.GetPDSEndpoint(ctx, did) 205 213 if err != nil { 206 - return nil, fmt.Errorf("resolve PDS: %w", err) 214 + return nil, "", fmt.Errorf("resolve PDS: %w", err) 207 215 } 208 216 209 - reqURL := fmt.Sprintf("%s/xrpc/com.atproto.repo.listRecords?repo=%s&collection=%s&limit=%d", 210 - pdsEndpoint, url.QueryEscape(did), url.QueryEscape(collection), limit) 217 + q := url.Values{} 218 + q.Set("repo", did) 219 + q.Set("collection", collection) 220 + if opts.Limit > 0 { 221 + q.Set("limit", fmt.Sprintf("%d", opts.Limit)) 222 + } 223 + if opts.Cursor != "" { 224 + q.Set("cursor", opts.Cursor) 225 + } 226 + if opts.Reverse { 227 + q.Set("reverse", "true") 228 + } 229 + reqURL := fmt.Sprintf("%s/xrpc/com.atproto.repo.listRecords?%s", pdsEndpoint, q.Encode()) 211 230 212 231 req, err := http.NewRequestWithContext(ctx, "GET", reqURL, nil) 213 232 if err != nil { 214 - return nil, fmt.Errorf("build request: %w", err) 233 + return nil, "", fmt.Errorf("build request: %w", err) 215 234 } 216 235 217 236 resp, err := c.httpClient.Do(req) 218 237 if err != nil { 219 - return nil, fmt.Errorf("list records: %w", err) 238 + return nil, "", fmt.Errorf("list records: %w", err) 220 239 } 221 240 defer resp.Body.Close() 222 241 223 242 if resp.StatusCode != http.StatusOK { 224 - return nil, fmt.Errorf("list records: HTTP %d", resp.StatusCode) 243 + return nil, "", fmt.Errorf("list records: HTTP %d", resp.StatusCode) 225 244 } 226 245 227 246 var result struct { ··· 230 249 CID string `json:"cid"` 231 250 Value map[string]any `json:"value"` 232 251 } `json:"records"` 252 + Cursor string `json:"cursor"` 233 253 } 234 254 if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { 235 - return nil, fmt.Errorf("decode records: %w", err) 255 + return nil, "", fmt.Errorf("decode records: %w", err) 236 256 } 237 257 238 258 records := make([]Record, len(result.Records)) 239 259 for i, r := range result.Records { 240 260 records[i] = Record{URI: r.URI, CID: r.CID, Value: r.Value} 241 261 } 242 - return records, nil 262 + return records, result.Cursor, nil 243 263 } 244 264 245 265 // GetPublicRecord fetches a single public record from a user's PDS.