The source feed should have a group that has "following" activity selector enabled, for example the built-in timeline group. The target feed should have a group that has "current" activity selector enabled, for example the built-in user group.
// Follow a userval timeline = client.feed(group = "timeline", id = "john")timeline.follow(FeedId(group = "user", id = "tom"))// Follow a stocktimeline.follow(FeedId(group = "stock", id = "apple"))// Follow with more fieldstimeline.follow( targetFid = FeedId(group = "stock", id = "apple"), custom = mapOf("reason" to "investment"))
const timeline = client.feed("timeline", "john");await timeline.getOrCreate();// Follow a userawait timeline.follow("user:tom");// Follow a stockawait timeline.follow("stock:apple");// Follow with more fieldsawait timeline.follow("stock:apple", { push_preference: "all", custom: { reason: "investment", },});// Follow without Feed instanceawait client.follow({ source: "timeline:alice", target: "user:tom",});
const timeline = client.feed("timeline", "john");await timeline.getOrCreate();// Follow a userawait timeline.follow("user:tom");// Follow a stockawait timeline.follow("stock:apple");// Follow with more fieldsawait timeline.follow("stock:apple", { push_preference: "all", custom: { reason: "investment", },});// Follow without Feed instanceawait client.follow({ source: "timeline:alice", target: "user:tom",});
const timeline = client.feed("timeline", "john");await timeline.getOrCreate();// Follow a userawait timeline.follow("user:tom");// Follow a stockawait timeline.follow("stock:apple");// Follow with more fieldsawait timeline.follow("stock:apple", { push_preference: "all", custom: { reason: "investment", },});// Follow without Feed instanceawait client.follow({ source: "timeline:alice", target: "user:tom",});
// Follow a userfinal timeline = client.feed(group: 'timeline', id: 'john');await timeline.follow(targetFid: const FeedId(group: 'user', id: 'tom'));// Follow a stockawait timeline.follow(targetFid: const FeedId(group: 'stock', id: 'apple'));// Follow with more fieldsawait timeline.follow( targetFid: const FeedId(group: 'stock', id: 'apple'), custom: {'reason': 'investment'},);
const timeline = client.feeds.feed("timeline", "john");await timeline.getOrCreate({ user_id: "john",});// Follow a userawait client.feeds.follow({ source: timeline.feed, target: "user:tom",});// Follow a stockawait client.feeds.follow({ source: timeline.feed, target: "stock:apple",});// Follow with more fieldsawait client.feeds.follow({ source: timeline.feed, target: "stock:apple", push_preference: "all", custom: { reason: "investment", },});
// Create timeline feedtimeline := client.Feeds().Feed("timeline", "john") _, err = timeline.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{ UserID: getstream.PtrTo("john"),})if err != nil { log.Fatal("Error getting/creating timeline feed:", err)}log.Println("Timeline feed created/retrieved successfully")// Follow a user_, err = client.Feeds().Follow(context.Background(), &getstream.FollowRequest{ Source: "timeline:john", Target: "user:tom",})if err != nil { log.Fatal("Error following user:", err)}log.Println("Successfully followed user:tom")// Follow a stock_, err = client.Feeds().Follow(context.Background(), &getstream.FollowRequest{ Source: "timeline:john", Target: "stock:apple",})if err != nil { log.Fatal("Error following stock:", err)}log.Println("Successfully followed stock:apple")// Follow with more fields_, err = client.Feeds().Follow(context.Background(), &getstream.FollowRequest{ Source: "timeline:john", Target: "stock:apple", PushPreference: getstream.PtrTo("all"), Custom: map[string]any{ "reason": "investment", },})if err != nil { log.Fatal("Error following stock with custom fields:", err)}log.Println("Successfully followed stock:apple with custom fields")
// Follow a user$timeline = $feedsClient->feed('timeline', 'john');$timeline->getOrCreateFeed( new GeneratedModels\GetOrCreateFeedRequest(userID: 'john'));$response = $feedsClient->follow( new GeneratedModels\FollowRequest( source: 'timeline:john', target: 'user:tom' ));// Follow a stock$response = $feedsClient->follow( new GeneratedModels\FollowRequest( source: 'timeline:john', target: 'stock:apple' ));// Follow with more fields$response = $feedsClient->follow( new GeneratedModels\FollowRequest( source: 'timeline:john', target: 'stock:apple', pushPreference: 'all', custom: (object)['reason' => 'investment'] ));
// Follow a uservar response = await _feedsV3Client.FollowAsync( new FollowRequest { Source = $"user:{_testFeedId}", Target = $"user:{_testFeedId2}" });
# Follow a userresponse = self.client.feeds.follow( source=f"{self.USER_FEED_TYPE}:{self.test_user_id}", target=f"{self.USER_FEED_TYPE}:{self.test_user_id_2}",)
# Follow a userfollow_request = { source: 'user:user123', target: 'user:user456'}client.feeds.follow(follow_request)
Trying to follow a feed that is already followed will result in an error. You can also use the getOrCreateFollows endpoint that provides an idempotent batch follow mechanism.
You do not need to call getOrCreate on the source or target feed before following. If either feed does not exist yet, the feed is created automatically when you call follow. This applies to both the single follow and batch follow endpoints.
When unfollowing a feed, all previous activities of that feed are removed from the timeline.
Trying to unfollow a feed that is not followed, will result in an error. You can also use the getOrCreateUnfollows endpoint that provides an idempotent batch unfollow mechanism.
// Do I follow a list of feeds// My feed is timeline:johnlet 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:johnlet followerQuery = FollowsQuery( filter: .equal(.targetFeed, "timeline:john"))let followerList = client.followList(for: followerQuery)let followerPage1 = try await followerList.get()
// Do I follow a list of feeds// My feed is timeline:johnval followQuery = FollowsQuery( filter = Filters.and( FollowsFilterField.sourceFeed.equal("timeline:john"), FollowsFilterField.targetFeed.`in`("user:sara", "user:adam") ))val followList = client.followList(query = followQuery)val page1: Result<List<FollowData>> = followList.get()val page2: Result<List<FollowData>> = followList.queryMoreFollows()val page1And2 = followList.state.follows// Paginating through followers for a feed// My feed is timeline:johnval followerQuery = FollowsQuery( filter = FollowsFilterField.targetFeed.equal("timeline:john"))val followerList = client.followList(query = followerQuery)val followerPage1: Result<List<FollowData>> = followerList.get()
const myTimeline = client.feed("timeline", "john");await myTimeline.getOrCreate();// Do I follow a list of feedsconst response = await client.queryFollows({ filter: { source_feed: myTimeline.feed, 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 stateconst firstPage = await userFeed.queryFollowers({ limit: 20,});// Next page - won't store followers in stateconst secondPage = await userFeed.queryFollowers({ limit: 20, next: firstPage.next,});// or load when reading feed - will store followers in stateawait feed.getOrCreate({ followers_pagination: { limit: 10, },});// and then load next pages (or first if followers are not yet loaded) - will store followers in stateawait feed.loadNextPageFollowers({ limit: 10 });console.log(feed.state.getLatestValue().followers);// Filter by source - feeds that I follow - won't store followings in stateawait myTimeline.queryFollowing({ limit: 10 });// or load when reading feed - will store followings in stateawait feed.getOrCreate({ following_pagination: { limit: 10, },});// and then load next pages (or first if followings are not yet loaded) - will store followings in stateawait feed.loadNextPageFollowing({ limit: 10 });console.log(feed.state.getLatestValue().following);
const myTimeline = client.feed("timeline", "john");await myTimeline.getOrCreate();// Do I follow a list of feedsconst response = await client.queryFollows({ filter: { source_feed: myTimeline.feed, 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 stateconst firstPage = await userFeed.queryFollowers({ limit: 20,});// Next page - won't store followers in stateconst secondPage = await userFeed.queryFollowers({ limit: 20, next: firstPage.next,});// or load when reading feed - will store followers in stateawait feed.getOrCreate({ followers_pagination: { limit: 10, },});const { followers, follower_count, followers_pagination, is_loading_next_page, has_next_page, loadNextPage,} = useFollowers(feed);// and then load next pages (or first if followers are not yet loaded) - will store followers in stateawait loadNextPage({ limit: 10 });// Filter by source - feeds that I follow - won't store followings in stateawait myTimeline.queryFollowing({ limit: 10 });// or load when reading feed - will store followings in stateawait feed.getOrCreate({ following_pagination: { limit: 10, },});const { following, following_count, following_pagination, is_loading_next_page, has_next_page, loadNextPage,} = useFollowing(feed);// and then load next pages (or first if followings are not yet loaded) - will store followings in stateawait loadNextPage({ limit: 10 });
const myTimeline = client.feed("timeline", "john");await myTimeline.getOrCreate();// Do I follow a list of feedsconst response = await client.queryFollows({ filter: { source_feed: myTimeline.feed, 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 stateconst firstPage = await userFeed.queryFollowers({ limit: 20,});// Next page - won't store followers in stateconst secondPage = await userFeed.queryFollowers({ limit: 20, next: firstPage.next,});// or load when reading feed - will store followers in stateawait feed.getOrCreate({ followers_pagination: { limit: 10, },});const { followers, follower_count, followers_pagination, is_loading_next_page, has_next_page, loadNextPage,} = useFollowers(feed);// and then load next pages (or first if followers are not yet loaded) - will store followers in stateawait loadNextPage({ limit: 10 });// Filter by source - feeds that I follow - won't store followings in stateawait myTimeline.queryFollowing({ limit: 10 });// or load when reading feed - will store followings in stateawait feed.getOrCreate({ following_pagination: { limit: 10, },});const { following, following_count, following_pagination, is_loading_next_page, has_next_page, loadNextPage,} = useFollowing(feed);// and then load next pages (or first if followings are not yet loaded) - will store followings in stateawait loadNextPage({ limit: 10 });
// Do I follow a list of feeds// My feed is timeline:johnconst followQuery = FollowsQuery( filter: Filter.and([ Filter.equal(FollowsFilterField.sourceFeed, 'timeline:john'), Filter.in_(FollowsFilterField.targetFeed, ['user:sara', 'user:adam']), ]),);final followList = client.followList(followQuery);final page1 = await followList.get();final page2 = await followList.queryMoreFollows();final page1And2 = followList.state.follows;// Paginating through followers for a feed// My feed is timeline:johnconst followerQuery = FollowsQuery( filter: Filter.equal(FollowsFilterField.targetFeed, 'timeline:john'),);final followerList = client.followList(followerQuery);final followerPage1 = await followerList.get();
const myTimeline = client.feeds.feed("timeline", "john");await myTimeline.getOrCreate({ user_id: "john",});// Do I follow a list of feedsconst response = await client.feeds.queryFollows({ filter: { source_feed: myTimeline.feed, 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 feedconst firstPage = await client.feeds.queryFollows({ filter: { target_feed: userFeed.feed }, limit: 20,});// Next pageconst secondPage = await client.feeds.queryFollows({ filter: { target_feed: userFeed.feed }, limit: 20, next: firstPage.next,});// Filter by source - feeds that I followawait client.feeds.queryFollows({ filter: { source_feed: myTimeline.feed }, limit: 20,});
ctx := context.Background()// Create timeline feedmyTimeline := client.Feeds().Feed("timeline", "john")_, err = myTimeline.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{ UserID: getstream.PtrTo("john"),})if err != nil { log.Fatal("Error creating timeline feed:", err)}// Query follows to check if we follow a list of feedsresponse, err := client.Feeds().QueryFollows(ctx, &getstream.QueryFollowsRequest{ Filter: map[string]any{ "source_feed": "timeline:john", "target_feed": map[string]any{ "$in": []string{"user:sara", "user:adam"}, }, },})if err != nil { log.Fatal("Error querying follows:", err)}log.Printf("Follows: %+v", response.Data.Follows)// Create user feeduserFeed := client.Feeds().Feed("user", "john")_, err = userFeed.GetOrCreate(ctx, &getstream.GetOrCreateFeedRequest{ UserID: getstream.PtrTo("john"),})if err != nil { log.Fatal("Error creating user feed:", err)}// Paginating through followers for a feed - first pagefirstPage, err := client.Feeds().QueryFollows(ctx, &getstream.QueryFollowsRequest{ Filter: map[string]any{ "target_feed": "user:john", }, Limit: getstream.PtrTo(20),})if err != nil { log.Fatal("Error querying first page of follows:", err)}// Next pagesecondPage, err := client.Feeds().QueryFollows(ctx, &getstream.QueryFollowsRequest{ Filter: map[string]any{ "target_feed": "user:john", }, Limit: getstream.PtrTo(20), Next: firstPage.Data.Next,})if err != nil { log.Fatal("Error querying second page of follows:", err)}log.Printf("First page follows: %+v", firstPage.Data.Follows)log.Printf("Second page follows: %+v", secondPage.Data.Follows)// Filter by source - feeds that I followsourceFollows, err := client.Feeds().QueryFollows(ctx, &getstream.QueryFollowsRequest{ Filter: map[string]any{ "source_feed": "timeline:john", }, Limit: getstream.PtrTo(20),})if err != nil { log.Fatal("Error querying source follows:", err)}log.Printf("Source follows: %+v", sourceFollows.Data.Follows)
$myTimeline = $feedsClient->feed('timeline', 'john');$myTimeline->getOrCreateFeed( new GeneratedModels\GetOrCreateFeedRequest(userID: 'john'));// Do I follow a list of feeds$response = $feedsClient->queryFollows( new GeneratedModels\QueryFollowsRequest( filter: (object)[ 'source_feed' => 'timeline:john', 'target_feed' => (object)['$in' => ['user:sara', 'user:adam']] ] ));echo json_encode($response->getData()->follows);$userFeed = $feedsClient->feed('user', 'john');$userFeed->getOrCreateFeed( new GeneratedModels\GetOrCreateFeedRequest(userID: 'john'));// Paginating through followers for a feed$firstPage = $feedsClient->queryFollows( new GeneratedModels\QueryFollowsRequest( filter: (object)['target_feed' => 'user:john'], limit: 20 ));// Next page$secondPage = $feedsClient->queryFollows( new GeneratedModels\QueryFollowsRequest( filter: (object)['target_feed' => 'user:john'], limit: 20, next: $firstPage->getData()->next ));// Filter by source - feeds that I follow$sourceFollows = $feedsClient->queryFollows( new GeneratedModels\QueryFollowsRequest( filter: (object)['source_feed' => 'timeline:john'], limit: 20 ));
Some apps require the user's approval for following them.
// Sara needs to configure the feed with visibility = followers for enabling follow requestslet saraFeed = saraClient.feed( for: .init( group: "user", id: "sara", data: .init(visibility: .followers) ))try await saraFeed.getOrCreate()// Adam requesting to follow the feedlet adamTimeline = adamClient.feed(group: "timeline", id: "adam")try await adamTimeline.getOrCreate()let followRequest = try await adamTimeline.follow(saraFeed.feed) // user:saraprint(followRequest.status) // .pending// Sara acceptingtry await saraFeed.acceptFollow( adamTimeline.feed, // timeline:adam role: "feed_member" // optional)// or rejecting the requesttry await saraFeed.rejectFollow(adamTimeline.feed) // timeline:adam
// Sara needs to configure the feed with visibility = followers for enabling follow requestsval saraFeed = saraClient.feed( query = FeedQuery( group = "user", id = "sara", data = FeedInputData(visibility = FeedVisibility.Followers) ))saraFeed.getOrCreate()// Adam requesting to follow the feedval adamTimeline = adamClient.feed(group = "timeline", id = "adam")adamTimeline.getOrCreate()val followRequest = adamTimeline.follow(saraFeed.fid) // user:saraprintln(followRequest.getOrNull()?.status) // FollowStatus.PENDING// Sara acceptingsaraFeed.acceptFollow( sourceFid = adamTimeline.fid, // timeline:adam role = "feed_member" // optional)// or rejecting the requestsaraFeed.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.feed);console.log(followRequest.follow.status); // pendingawait saraClient.acceptFollow({ source: adamTimeline.feed, target: saraFeed.feed, // Optionally provide role follower_role: "feed_member",});await saraClient.rejectFollow({ source: adamTimeline.feed, target: saraFeed.feed,});
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.feed);console.log(followRequest.follow.status); // pendingawait saraClient.acceptFollow({ source: adamTimeline.feed, target: saraFeed.feed, // Optionally provide role follower_role: "feed_member",});await saraClient.rejectFollow({ source: adamTimeline.feed, target: saraFeed.feed,});
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.feed);console.log(followRequest.follow.status); // pendingawait saraClient.acceptFollow({ source: adamTimeline.feed, target: saraFeed.feed, // Optionally provide role follower_role: "feed_member",});await saraClient.rejectFollow({ source: adamTimeline.feed, target: saraFeed.feed,});
// Sara needs to configure the feed with visibility = followers for enabling follow requestsconst saraFeedQuery = FeedQuery( fid: FeedId(group: 'user', id: 'sara'), data: FeedInputData(visibility: FeedVisibility.followers),);final saraFeed = saraClient.feedFromQuery(saraFeedQuery);await saraFeed.getOrCreate();// Adam requesting to follow the feedfinal adamTimeline = adamClient.feed(group: 'timeline', id: 'adam');await adamTimeline.getOrCreate();final followRequest = await adamTimeline.follow(targetFid: saraFeed.fid); // user:saraprint(followRequest.getOrNull()?.status); // .pending// Sara acceptingawait saraFeed.acceptFollow( sourceFid: adamTimeline.fid, // timeline:adam role: 'feed_member', // optional);// or rejecting the requestawait saraFeed.rejectFollow(sourceFid: adamTimeline.fid); // timeline:adam
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: "adam",});const followRequest = await client.feeds.follow({ source: adamTimeline.feed, target: saraFeed.feed,});console.log(followRequest.follow.status); // pendingawait client.feeds.acceptFollow({ source: adamTimeline.feed, target: saraFeed.feed, // Optionally provide role follower_role: "feed_member",});await client.feeds.rejectFollow({ source: adamTimeline.feed, target: saraFeed.feed,});
// Sara needs to configure the feed with visibility = followers for enabling follow requestsGetOrCreateFeedRequest saraFeedRequest = GetOrCreateFeedRequest.builder() .userID("sara") .data(FeedInput.builder() .visibility("followers") .build()) .build();feeds.getOrCreateFeed("user", "sara", saraFeedRequest).execute();// Adam requesting to follow the feedGetOrCreateFeedRequest adamFeedRequest = GetOrCreateFeedRequest.builder() .userID("adam") .build();feeds.getOrCreateFeed("timeline", "adam", adamFeedRequest).execute();// Create follow request from adamTimeline to saraFeedFollowRequest followRequest = FollowRequest.builder() .source("timeline:adam") .target("user:sara") .build();SingleFollowResponse followResponse = feeds.follow(followRequest).execute().getData();System.out.println(followResponse.getFollow().getStatus()); // pending// Sara acceptingAcceptFollowRequest acceptRequest = AcceptFollowRequest.builder() .source("timeline:adam") .target("user:sara") .followerRole("feed_member") // optional .build();feeds.acceptFollow(acceptRequest).execute();// or rejecting the requestRejectFollowRequest rejectRequest = RejectFollowRequest.builder() .source("timeline:adam") .target("user:sara") .build();feeds.rejectFollow(rejectRequest).execute();
// Sara needs to configure the feed with visibility = followers for enabling follow requests$saraFeed = $feedsClient->feed('user', 'sara');$saraFeed->getOrCreateFeed( new GeneratedModels\GetOrCreateFeedRequest( userID: 'sara', data: new GeneratedModels\FeedInput(visibility: 'followers') ));// Adam requesting to follow the feed$adamTimeline = $feedsClient->feed('timeline', 'adam');$adamTimeline->getOrCreateFeed( new GeneratedModels\GetOrCreateFeedRequest(userID: 'adam'));$followRequest = $feedsClient->follow( new GeneratedModels\FollowRequest( source: 'timeline:adam', target: 'user:sara' ));echo $followRequest->getData()->follow->status; // pending// Sara accepting$acceptResponse = $feedsClient->acceptFollow( new GeneratedModels\AcceptFollowRequest( source: 'timeline:adam', target: 'user:sara', followerRole: 'feed_member' // optional ));// or rejecting the request$rejectResponse = $feedsClient->rejectFollow( new GeneratedModels\RejectFollowRequest( source: 'timeline:adam', target: 'user:sara' ));
// Sara needs to configure the feed with visibility = followers for enabling follow requestsawait _feedsV3Client.GetOrCreateFeedAsync( FeedGroupID: "user", FeedID: "sara", request: new GetOrCreateFeedRequest { UserID = "sara", Data = new FeedInput { Visibility = "followers" } });// Adam requesting to follow the feedawait _feedsV3Client.GetOrCreateFeedAsync( FeedGroupID: "timeline", FeedID: "adam", request: new GetOrCreateFeedRequest { UserID = "adam" });// Create follow request from adamTimeline to saraFeedvar followResponse = await _feedsV3Client.FollowAsync( new FollowRequest { Source = "timeline:adam", Target = "user:sara" });Console.WriteLine(followResponse.Follow.Status); // pending// Sara acceptingawait _feedsV3Client.AcceptFollowAsync( new AcceptFollowRequest { Source = "timeline:adam", Target = "user:sara", FollowerRole = "feed_member" // optional });// or rejecting the requestawait _feedsV3Client.RejectFollowAsync( new RejectFollowRequest { Source = "timeline:adam", Target = "user:sara" });
# Sara needs to configure the feed with visibility = followers for enabling follow requestsfeeds.get_or_create_feed( feed_group="user", feed_id="sara", user_id="sara", data={"visibility": "followers"})# Adam requesting to follow the feedfeeds.get_or_create_feed( feed_group="timeline", feed_id="adam", user_id="adam")# Create follow request from adamTimeline to saraFeedfollow_response = feeds.follow( source="timeline:adam", target="user:sara")print(follow_response["follow"]["status"]) # pending# Sara acceptingfeeds.accept_follow( source="timeline:adam", target="user:sara", follower_role="feed_member" # optional)# or rejecting the requestfeeds.reject_follow( source="timeline:adam", target="user:sara")
# Sara needs to configure the feed with visibility = followers for enabling follow requestsclient.feeds.get_or_create_feed( "user", "sara", GetStream::Generated::Models::GetOrCreateFeedRequest.new( user_id: "sara", data: { "visibility" => "followers" } ))# Adam requesting to follow the feedclient.feeds.get_or_create_feed( "timeline", "adam", GetStream::Generated::Models::GetOrCreateFeedRequest.new( user_id: "adam" ))# Create follow request from adamTimeline to saraFeedfollow_response = client.feeds.follow( GetStream::Generated::Models::FollowRequest.new( source: "timeline:adam", target: "user:sara" ))puts follow_response.data.follow.status # pending# Sara acceptingclient.feeds.accept_follow( GetStream::Generated::Models::AcceptFollowRequest.new( source: "timeline:adam", target: "user:sara", follower_role: "feed_member" # optional ))# or rejecting the requestclient.feeds.reject_follow( GetStream::Generated::Models::RejectFollowRequest.new( source: "timeline:adam", target: "user:sara" ))
Understanding the difference between push_preference, skip_push and create_notification_activity:
When following a feed, you can set push_preference to control push notifications for future activities from that feed:
all - Receive push notifications for all activities from the followed feed
none (default) - Don't receive push notifications for activities from the followed feed
The skip_push controls whether the follow action itself triggers a notification.
The create_notification_activity controls whether the follow action creates an activity on the source feed author's notification feed.
Note: You usually don't want to set skip_push and create_notification_activity true at the same time, for more information see the Push Overview page
// Scenario 1: Follow a user and receive notifications for their future activitiesawait timeline.follow("user:alice", { push_preference: "all", // You'll get push notifications for Alice's future posts});// Scenario 2: Follow a user but don't get notifications for their activitiesawait timeline.follow("user:bob", { push_preference: "none", // You won't get push notifications for Bob's future posts});// Scenario 3: Follow a user silentlyawait timeline.follow("user:charlie", { skip_push: true, // Charlie won't get a "you have a new follower" notification push_preference: "all", // But you'll still get notifications for Charlie's future posts});// Scenario 4: Silent follow with no future notificationsawait timeline.follow("user:diana", { skip_push: true, // Diana won't know you followed her push_preference: "none", // And you won't get notifications for her posts});// Scenario 5: Follow a user and create notification activity for Charileawait timeline.follow("user:charlie", { skip_push: true, // Charlie won't get a "you have a new follower" notification create_notification_activity: true, // Charlie's notification feed will have a new activity push_preference: "all", // But you'll still get notifications for Charlie's future posts});
getOrCreateFollows/getOrCreateUnfollows endpoints allow creating a maximum of 100 follow/unfollow at once.
These are idempotent endpoints (as opposed to follow and unfollow), trying to follow/unfollow a feed that's already/not yet followed won't cause errors.