Activity Feeds v3 is in beta — try it out!

Follows

Follow & Unfollow

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 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']
    )
);

// Unfollow
$response = $feedsClient->unfollow('timeline:john', 'user:tom');

Trying to follow a feed that is already followed will result in an error. Similarly, trying to unfollow a feed that is not followed, will result in an error.

When unfollowing a feed, all previous activities of that feed are removed from the timeline.

Querying 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
    )
);

Follows Queryable Built-In Fields

nametypedescriptionsupported operationsexample
source_feedstring or list of stringsThe feed ID that is following$in, $eq{ source_feed: { $eq: 'messaging:general' } }
target_feedstring or list of stringsThe feed ID being followed$in, $eq{ target_feed: { $in: [ 'sports:news', 'tech:updates' ] } }
statusstring or list of stringsThe follow status$in, $eq{ status: { $in: [ 'accepted', 'pending', 'rejected' ] } }
created_atstring, must be formatted as an RFC3339 timestampThe time the follow relationship was created$eq, $gt, $gte, $lt, $lte{ created_at: { $gte: '2023-12-04T09:30:20.45Z' } }

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
$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'
    )
);

Push Preferences on Follow

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

Note: The push_preference parameter controls future notifications from the followed feed, while skip_push controls whether the follow action itself triggers a notification.

Examples: Push Preferences vs Skip Push

Understanding the difference between push_preference and skip_push:

// Scenario 1: Follow a user and receive notifications for their future activities
await 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 activities
await timeline.follow("user:bob", {
  push_preference: "none", // You won't get push notifications for Bob's future posts
});

// Scenario 3: Follow a user silently
await 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 notifications
await 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
});
© Getstream.io, Inc. All Rights Reserved.