Custom feeds
Custom feeds are algorithmic feed generators. To users, this is their timeline. This tutorial will explain how to interact with a feed generator in the network.
Anybody can create custom feed. See the Custom Feeds Starter Template to get started.
Getting a feed generator's description
- Typescript
- Python
Call app.bsky.feed.getFeedGenerator to view a feedgen's description.
agent.app.bsky.feed.getFeedGenerator({
feed: feedUri
})
The output will match this interface:
{
view: { // AppBskyFeedDefs.GeneratorView
uri: string;
cid: string;
did: string;
creator: AppBskyActorDefs.ProfileView;
displayName: string;
description?: string;
descriptionFacets?: AppBskyRichtextFacet.Main[];
avatar?: string;
likeCount?: number;
viewer?: GeneratorViewerState;
indexedAt: string;
}
isOnline: boolean;
isValid: boolean;
}
Call app.bsky.feed.getFeedGenerator to view a feedgen's description.
client.app.bsky.feed.get_feed_generator({'feed': feed_uri})
The output will match this model:
class Response(base.ResponseModelBase):
is_online: bool
is_valid: bool
view: 'models.AppBskyFeedDefs.GeneratorView'
where view
is:
class GeneratorView(base.ModelBase):
cid: str
creator: 'models.AppBskyActorDefs.ProfileView'
did: str
display_name: str
indexed_at: str
uri: str
avatar: t.Optional[str] = None
description: t.Optional[str]
description_facets: t.Optional[t.List['models.AppBskyRichtextFacet.Main']] = None
like_count: t.Optional[int] = None
viewer: t.Optional['models.AppBskyFeedDefs.GeneratorViewerState'] = None
Viewing a feed generator's posts
- Typescript
- Python
Call app.bsky.feed.getFeed to view posts from a feedgen.
agent.app.bsky.feed.getFeed({
feed: feedUri,
limit: 30,
cursor
})
The output will match this interface:
{
cursor?: string;
feed: AppBskyFeedDefs.FeedViewPost[];
}
Use the returned cursor to fetch additional pages of posts.
Call app.bsky.feed.getFeed to view posts from a feedgen.
client.app.bsky.feed.get_feed({'feed': feed_uri, 'limit': 30, 'cursor': cursor})
The output will match this interface:
class Response(base.ResponseModelBase):
feed: t.List['models.AppBskyFeedDefs.FeedViewPost']
cursor: t.Optional[str] = None
Use the returned cursor to fetch additional pages of posts.
Has the user liked a feedgen?
- Typescript
- Python
When you call app.bsky.feed.getFeedGenerator, you can examine the viewer
field to determine if the user has liked the feedgen.
{
like?: string; // the URI of the like record if liked
}
For example:
const res = await agent.app.bsky.feed.getFeedGenerator({
feed: feedUri
})
if (res.data.list.viewer?.like) {
// has liked list
}
When you call app.bsky.feed.getFeedGenerator, you can examine the viewer
field to determine if the user has liked the feedgen.
class GeneratorViewerState(base.ModelBase):
like: t.Optional[str] = None # the URI of the like record if liked
For example:
feed = client.app.bsky.feed.get_feed_generator({'feed': feed_uri})
if feed.view.viewer and feed.view.viewer.like:
print('liked')
Liking and unliking a feedgen
- Typescript
- Python
Liking a feed is the same as liking any other item in the network. You just use the URI and CID of the feed generator to identify the feed.
const {data: feedInfo} = agent.app.bsky.feed.getFeedGenerator({
feed: feedUri
})
await agent.like(feedUri, feedInfo.view.cid)
Unliking a feed works the same way:
const {data: feedInfo} = agent.app.bsky.feed.getFeedGenerator({
feed: feedUri
})
await agent.unlike(feedInfo.view.viewer.like)
Liking a feed is the same as liking any other item in the network. You just use the URI and CID of the feed generator to identify the feed.
feed = client.app.bsky.feed.get_feed_generator({'feed': feed_uri})
client.like(feed.view.uri, feed.view.cid)
Unliking a feed works the same way:
feed = client.app.bsky.feed.get_feed_generator({'feed': feed_uri})
if feed.view.viewer and feed.view.viewer.like:
print(client.unlike(feed.view.viewer.like))