// Follow a user
let timeline = client.feed(group: "timeline", id: "john")
_ = try await timeline.follow(FeedId(group: "user", id: "tom"))
// Follow a stock
_ = try await timeline.follow(FeedId(group: "stock", id: "apple"))
// Follow with more fields
_ = try await timeline.follow(
FeedId(group: "stock", id: "apple"),
custom: ["reason": "investment"]
)
Activity Feeds V3 is in closed alpha — do not use it in production (just yet).
Follows
Follow & Unfollow
const timeline = client.feed("timeline", "john");
await timeline.getOrCreate();
// Follow a user
await timeline.follow("user:tom");
// Follow a stock
await timeline.follow("stock:apple");
// Follow with more fields
await timeline.follow("stock:apple", {
push_preference: "all",
custom: {
reason: "investment",
},
});
const timeline = client.feeds.feed("timeline", "john");
await timeline.getOrCreate({
user_id: "john",
});
// Follow a user
await client.feeds.follow({
source: timeline.fid,
target: "user:tom",
});
// Follow a stock
await client.feeds.follow({
source: timeline.fid,
target: "stock:apple",
});
// Follow with more fields
await client.feeds.follow({
source: timeline.fid,
target: "stock:apple",
push_preference: "all",
custom: {
reason: "investment",
},
});
package main
import (
"context"
"log"
"github.com/GetStream/getstream-go/v3"
)
func main() {
client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
feedsClient := client.Feeds()
// Follow a user
followResponse, err := feedsClient.Follow(ctx, &getstream.FollowRequest{
Source: "timeline:john",
Target: "user:tom",
})
if err != nil {
log.Fatal(err)
}
log.Printf("Follow created: %+v", followResponse.Data)
// Follow a stock
stockFollow, err := feedsClient.Follow(ctx, &getstream.FollowRequest{
Source: "timeline:john",
Target: "stock:apple",
})
if err != nil {
log.Fatal(err)
}
log.Printf("Stock follow created: %+v", stockFollow.Data)
// Follow with more fields
customFollow, err := feedsClient.Follow(ctx, &getstream.FollowRequest{
Source: "timeline:john",
Target: "stock:apple",
Custom: map[string]interface{}{
"reason": "investment",
},
})
if err != nil {
log.Fatal(err)
}
log.Printf("Custom follow created: %+v", customFollow.Data)
}
Querying Follows
// Do I follow a list of feeds
// My feed is timeline:john
let followQuery = FollowsQuery(
filter: .and([
.equal(.sourceFeed, "timeline:john"),
.in(.targetFeed, ["user:sara", "user:adam"])
])
)
let followList = client.followList(for: followQuery)
let page1 = try await followList.get()
let page2 = try await followList.queryMoreFollows()
let page1And2 = followList.state.follows
// Paginating through followers for a feed
// My feed is timeline:john
let followerQuery = FollowsQuery(
filter: .equal(.targetFeed, "timeline:john")
)
let followerList = client.followList(for: followerQuery)
let followerPage1 = try await followerList.get()
const myTimeline = client.feed("timeline", "john");
await myTimeline.getOrCreate();
// Do I follow a list of feeds
const response = await client.queryFollows({
filter: {
source_feed: myTimeline.fid,
target_feed: { $in: ["user:sara", "user:adam"] },
},
});
console.log(response.follows);
const userFeed = client.feed("user", "john");
await userFeed.getOrCreate();
// Paginating through followers for a feed - won't store followers in state
const firstPage = await userFeed.queryFollowers({
limit: 20,
});
// Next page - won't store followers in state
const secondPage = await userFeed.queryFollowers({
limit: 20,
next: firstPage.next,
});
// or load when reading feed - will store followers in state
await feed.getOrCreate({
followers_pagination: {
limit: 10,
},
});
// and then load next pages (or first if followers are not yet loaded) - will store followers in state
await feed.loadNextPageFollowers({ limit: 10 });
console.log(feed.state.getLatestValue().followers);
// Filter by source - feeds that I follow - won't store followings in state
await myTimeline.queryFollowing({ limit: 10 });
// or load when reading feed - will store followings in state
await feed.getOrCreate({
following_pagination: {
limit: 10,
},
});
// and then load next pages (or first if followings are not yet loaded) - will store followings in state
await feed.loadNextPageFollowing({ limit: 10 });
console.log(feed.state.getLatestValue().following);
const myTimeline = client.feeds.feed("timeline", "john");
await myTimeline.getOrCreate({
user_id: "john",
});
// Do I follow a list of feeds
const response = await client.feeds.queryFollows({
filter: {
source_feed: myTimeline.fid,
target_feed: { $in: ["user:sara", "user:adam"] },
},
});
console.log(response.follows);
const userFeed = client.feeds.feed("user", "john");
await userFeed.getOrCreate({
user_id: "john",
});
// Paginating through followers for a feed
const firstPage = await client.feeds.queryFollows({
filter: { target_feed: userFeed.fid },
limit: 20,
});
// Next page
const secondPage = await client.feeds.queryFollows({
filter: { target_feed: userFeed.fid },
limit: 20,
next: firstPage.next,
});
// Filter by source - feeds that I follow
await client.feeds.queryFollows({
filter: { source_feed: myTimeline.fid },
limit: 20,
});
package main
import (
"context"
"log"
"github.com/GetStream/getstream-go/v3"
)
func main() {
client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
feedsClient := client.Feeds()
// Create timeline feed
myTimeline := feedsClient.Feed("timeline", "john")
_, err = myTimeline.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
// Do I follow a list of feeds
response, err := feedsClient.QueryFollows(ctx, &getstream.QueryFollowsRequest{
Filter: map[string]interface{}{
"source_feed": "timeline:john",
"target_feed": map[string]interface{}{
"$in": []string{"user:sara", "user:adam"},
},
},
})
if err != nil {
log.Fatal(err)
}
log.Printf("Follows: %+v", response.Data.Follows)
// Create user feed
userFeed := feedsClient.Feed("user", "john")
_, err = userFeed.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
// Paginating through followers for a feed
firstPage, err := feedsClient.QueryFollows(ctx, &getstream.QueryFollowsRequest{
Filter: map[string]interface{}{
"target_feed": "user:john",
},
Limit: getstream.PtrTo(20),
})
if err != nil {
log.Fatal(err)
}
log.Printf("First page followers: %+v", firstPage.Data.Follows)
// Next page
secondPage, err := feedsClient.QueryFollows(ctx, &getstream.QueryFollowsRequest{
Filter: map[string]interface{}{
"target_feed": "user:john",
},
Limit: getstream.PtrTo(20),
Next: firstPage.Data.Next,
})
if err != nil {
log.Fatal(err)
}
log.Printf("Second page followers: %+v", secondPage.Data.Follows)
// Filter by source - feeds that I follow
followingResponse, err := feedsClient.QueryFollows(ctx, &getstream.QueryFollowsRequest{
Filter: map[string]interface{}{
"source_feed": "timeline:john",
},
Limit: getstream.PtrTo(20),
})
if err != nil {
log.Fatal(err)
}
log.Printf("Feeds I follow: %+v", followingResponse.Data.Follows)
}
Follow Requests
Some apps require the user’s approval for following them.
// Sara needs to configure the feed with visibility = followers for enabling follow requests
let saraFeed = saraClient.feed(
for: .init(
group: "user",
id: "sara",
data: .init(visibility: .followers)
)
)
try await saraFeed.getOrCreate()
// Adam requesting to follow the feed
let adamTimeline = adamClient.feed(group: "timeline", id: "adam")
try await adamTimeline.getOrCreate()
let followRequest = try await adamTimeline.follow(saraFeed.fid) // user:sara
print(followRequest.status) // .pending
// Sara accepting
try await saraFeed.acceptFollow(
adamTimeline.fid, // timeline:adam
role: "feed_member" // optional
)
// or rejecting the request
try await saraFeed.rejectFollow(adamTimeline.fid) // timeline:adam
const saraFeed = saraClient.feed("user", uuidv4());
await saraFeed.getOrCreate({
// You need to set followers visibility to have follow requests
data: { visibility: "followers" },
});
const adamTimeline = adamClient.feed("timeline", uuidv4());
await adamTimeline.getOrCreate();
const followRequest = await adamTimeline.follow(saraFeed.fid);
console.log(followRequest.follow.status); // pending
await saraClient.acceptFollow({
source_fid: adamTimeline.fid,
target_fid: saraFeed.fid,
// Optionally provide role
follower_role: "feed_member",
});
await saraClient.rejectFollow({
source_fid: adamTimeline.fid,
target_fid: saraFeed.fid,
});
const saraFeed = client.feeds.feed("user", uuidv4());
await saraFeed.getOrCreate({
// You need to set followers visibility to have follow requests
data: { visibility: "followers" },
user_id: 'sara'
});
const adamTimeline = client.feeds.feed("timeline", uuidv4());
await adamTimeline.getOrCreate({
user_id:
});
const followRequest = await client.feeds.follow({
source: adamTimeline.fid,
target: saraFeed.fid,
});
console.log(followRequest.follow.status); // pending
await client.feeds.acceptFollow({
source_fid: adamTimeline.fid,
target_fid: saraFeed.fid,
// Optionally provide role
follower_role: "feed_member",
});
await client.feeds.rejectFollow({
source_fid: adamTimeline.fid,
target_fid: saraFeed.fid,
});
- I'm working with the Stream Feeds React Native SDK and would like to ask questions about this documentation page: https://getstream.io/activity-feeds/docs/react-native/follows.md
- View as markdown
- Open in ChatGPT
- Open in Claude
On this page: