its for when you want to get like notifications for your reposts
1package main
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7
8 "github.com/bluesky-social/indigo/api/atproto"
9 "github.com/bluesky-social/indigo/api/bsky"
10 "github.com/bluesky-social/indigo/atproto/identity"
11 "github.com/bluesky-social/indigo/atproto/syntax"
12 "github.com/bluesky-social/indigo/xrpc"
13)
14
15func findUserPDS(ctx context.Context, did string) (string, error) {
16 id, err := identity.DefaultDirectory().LookupDID(ctx, syntax.DID(did))
17 if err != nil {
18 return "", err
19 }
20 pdsURI := id.PDSEndpoint()
21 if len(pdsURI) == 0 {
22 return "", fmt.Errorf("no PDS URL was found in identity document")
23 }
24
25 return pdsURI, nil
26}
27
28func fetchRecords[v any](ctx context.Context, xrpcClient *xrpc.Client, collection, did string, extractFn func(v) string) (Set[string], error) {
29 all := make(Set[string])
30 cursor := ""
31
32 for {
33 // todo: ratelimits?? idk what this does for those
34 out, err := atproto.RepoListRecords(ctx, xrpcClient, collection, cursor, 100, did, false)
35 if err != nil {
36 return nil, err
37 }
38
39 for _, record := range out.Records {
40 raw, _ := record.Value.MarshalJSON()
41 var val v
42 if err := json.Unmarshal(raw, &val); err != nil {
43 return nil, err
44 }
45 s := extractFn(val)
46 if len(s) > 0 {
47 all[s] = struct{}{}
48 }
49 }
50
51 if out.Cursor == nil || *out.Cursor == "" {
52 break
53 }
54 cursor = *out.Cursor
55 }
56
57 return all, nil
58}
59
60func fetchReposts(ctx context.Context, xrpcClient *xrpc.Client, did string) (Set[string], error) {
61 return fetchRecords(ctx, xrpcClient, "app.bsky.feed.repost", did, func(v bsky.FeedRepost) string { return v.Subject.Uri })
62}
63
64func fetchFollows(ctx context.Context, xrpcClient *xrpc.Client, did string) (Set[string], error) {
65 return fetchRecords(ctx, xrpcClient, "app.bsky.graph.follow", did, func(v bsky.GraphFollow) string { return v.Subject })
66}