its for when you want to get like notifications for your reposts
at main 2.6 kB view raw
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 syntax.DID) (string, error) { 16 id, err := identity.DefaultDirectory().LookupDID(ctx, 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 fetchProfile(ctx context.Context, did syntax.DID) (*bsky.ActorDefs_ProfileViewDetailed, error) { 29 return bsky.ActorGetProfile(ctx, &xrpc.Client{Host: "https://public.api.bsky.app"}, string(did)) 30} 31 32func fetchRecords[v any](ctx context.Context, xrpcClient *xrpc.Client, cb func(syntax.ATURI, v), cursor *string, collection string, did syntax.DID) error { 33 if xrpcClient == nil { 34 pdsURI, err := findUserPDS(ctx, did) 35 if err != nil { 36 return err 37 } 38 xrpcClient = &xrpc.Client{ 39 Host: pdsURI, 40 } 41 } 42 43 var cur string = "" 44 if cursor != nil { 45 cur = *cursor 46 } 47 48 for { 49 // todo: ratelimits?? idk what this does for those 50 out, err := atproto.RepoListRecords(ctx, xrpcClient, collection, cur, 100, string(did), true) 51 if err != nil { 52 return err 53 } 54 55 for _, record := range out.Records { 56 raw, _ := record.Value.MarshalJSON() 57 var val v 58 if err := json.Unmarshal(raw, &val); err != nil { 59 return err 60 } 61 cb(syntax.ATURI(record.Uri), val) 62 } 63 64 if out.Cursor == nil || *out.Cursor == "" { 65 break 66 } 67 cur = *out.Cursor 68 } 69 70 return nil 71} 72 73type FetchFollowItem struct { 74 rkey syntax.RecordKey 75 follow bsky.GraphFollow 76} 77 78func fetchFollows(ctx context.Context, xrpcClient *xrpc.Client, cursor *string, did syntax.DID) ([]FetchFollowItem, error) { 79 out := make([]FetchFollowItem, 0) 80 fetchRecords(ctx, xrpcClient, func(uri syntax.ATURI, f bsky.GraphFollow) { 81 out = append(out, FetchFollowItem{rkey: uri.RecordKey(), follow: f}) 82 }, cursor, "app.bsky.graph.follow", did) 83 return out, nil 84} 85 86func fetchRepostLikes(ctx context.Context, xrpcClient *xrpc.Client, cursor *string, did syntax.DID) (map[syntax.RecordKey]bsky.FeedLike, error) { 87 out := make(map[syntax.RecordKey]bsky.FeedLike) 88 fetchRecords(ctx, xrpcClient, func(uri syntax.ATURI, f bsky.FeedLike) { 89 if f.Via != nil && syntax.ATURI(f.Via.Uri).Collection() == "app.bsky.feed.repost" { 90 out[uri.RecordKey()] = f 91 } 92 }, cursor, "app.bsky.feed.like", did) 93 return out, nil 94}