A collection of Custom Bluesky Feeds, including Fresh Feeds, all under one roof
at main 79 lines 2.4 kB view raw
1package static 2 3import ( 4 "context" 5 "fmt" 6 "strconv" 7 8 appbsky "github.com/bluesky-social/indigo/api/bsky" 9) 10 11type StaticFeed struct { 12 FeedActorDID string 13 FeedName string 14 StaticPostURIs []string 15} 16 17// NewStaticFeed returns a new StaticFeed, a list of aliases for the feed, and an error 18// StaticFeed is a trivial implementation of the Feed interface, so its aliases are just the input feedName 19func NewStaticFeed(ctx context.Context, feedActorDID string, feedName string, staticPostURIs []string) (*StaticFeed, []string, error) { 20 return &StaticFeed{ 21 FeedActorDID: feedActorDID, 22 FeedName: feedName, 23 StaticPostURIs: staticPostURIs, 24 }, []string{feedName}, nil 25} 26 27// GetPage returns a list of FeedDefs_SkeletonFeedPost, a new cursor, and an error 28// It takes a feed name, a user DID, a limit, and a cursor 29// The feed name can be used to produce different feeds from the same feed generator 30func (sf *StaticFeed) GetPage(ctx context.Context, feed string, userDID string, limit int64, cursor string) ([]*appbsky.FeedDefs_SkeletonFeedPost, *string, error) { 31 cursorAsInt := int64(0) 32 var err error 33 34 if cursor != "" { 35 cursorAsInt, err = strconv.ParseInt(cursor, 10, 64) 36 if err != nil { 37 return nil, nil, fmt.Errorf("cursor is not an integer: %w", err) 38 } 39 } 40 41 posts := []*appbsky.FeedDefs_SkeletonFeedPost{} 42 43 for i, postURI := range sf.StaticPostURIs { 44 if int64(i) < cursorAsInt { 45 continue 46 } 47 48 if int64(len(posts)) >= limit { 49 break 50 } 51 52 posts = append(posts, &appbsky.FeedDefs_SkeletonFeedPost{ 53 Post: postURI, 54 }) 55 } 56 57 cursorAsInt += int64(len(posts)) 58 59 var newCursor *string 60 61 if cursorAsInt < int64(len(sf.StaticPostURIs)) { 62 newCursor = new(string) 63 *newCursor = strconv.FormatInt(cursorAsInt, 10) 64 } 65 66 return posts, newCursor, nil 67} 68 69// Describe returns a list of FeedDescribeFeedGenerator_Feed, and an error 70// StaticFeed is a trivial implementation of the Feed interface, so it returns a single FeedDescribeFeedGenerator_Feed 71// For a more complicated feed, this function would return a list of FeedDescribeFeedGenerator_Feed with the URIs of aliases 72// supported by the feed 73func (sf *StaticFeed) Describe(ctx context.Context) ([]appbsky.FeedDescribeFeedGenerator_Feed, error) { 74 return []appbsky.FeedDescribeFeedGenerator_Feed{ 75 { 76 Uri: "at://" + sf.FeedActorDID + "/app.bsky.feed.generator/" + sf.FeedName, 77 }, 78 }, nil 79}