Activity Feeds V3 is in closed alpha — do not use it in production (just yet).

For You Feed

It’s now common for apps to default to a “For you” style feed instead of just a following feed. This section of the docs will explain how to build a for you feed with Stream.

While the exact logic differs per app, fundamently the “for you” feed does a 2 different things:

1 - Activity Selectors

The feed pulls in activities from different sources (activity selectors). Examples include:

  • Popular activities
  • Activities close to you
  • Activities from people you follow
  • Activities from your follow recommendations
  • Specific editorial feeds
  • Activities that match your interests
  • Other activity queries/selections

Read more about the supported activity selectors here.

2- Ranking

After the feed combines the activities from different selectors it applies ranking. Stream supports expression based ranking out of the box. This allows you to define a formula to rank activities.

In the example below we’ll build a simple interest based for you feed

Step 1 - Create a feed group

For the feed group we’re enabling interest based ranking. We are ranking on interest_score * popularity * decay_exp(time) For activity selectors we’re also keeping it simple, showing just the activities from people you follow & popular activities.

We’re also enabling activity processors. The text topics activity processor uses an LLM to summarize the topics for an activity. It writes this data to activity.interest_tags. This update happens in the background.

const response = await serverClient.feeds.updateFeedGroup({
  id: "timeline",
  activity_selectors: [{ type: "following" }, { type: "popular" }],
  ranking: {
    type: "interest",
    score: "interest_score * popularity * decay_exp(time)",
    defaults: { popularity: 1 },
  },
  activity_processors: [{ type: "text_topics" }],
});

Step 2 - Activities with interest tags

Let’s add 2 activities to a feed

AddActivityRequest activity =
    AddActivityRequest.builder()
        .type("post")
        .feeds(List.of(testFeedId))
        .text("This is a test activity from Java SDK")
        .userID(testUserId)
        .build();

AddActivityResponse response = feeds.addActivity(activity).execute().getData();

The important part here is that the activity has the interest tags set.

Step 3 - Reading the interest based ranked feed

When reading an interest based feed you can either have Stream automatically calculate the interest weights, or pass them manually.

testFeed = new Feed("user", testUserId, feeds);
testFeed2 = new Feed("user", testUserId2, feeds);

GetOrCreateFeedRequest feedRequest1 =
    GetOrCreateFeedRequest.builder().userID(testUserId).build();
GetOrCreateFeedRequest feedRequest2 =
    GetOrCreateFeedRequest.builder().userID(testUserId2).build();

GetOrCreateFeedResponse feedResponse1 = testFeed.getOrCreate(feedRequest1).getData();
GetOrCreateFeedResponse feedResponse2 = testFeed2.getOrCreate(feedRequest2).getData();
testFeedId = feedResponse1.getFeed().getFeed();
testFeedId2 = feedResponse2.getFeed().getFeed();

Conclusion

In a few lines of code you created an interest based “for you” style feed. It includes popular content as well as activities from the people you follow. Activities from topics you engage with are shown higher in the feed.

This example kept things pretty basic but you can make it more complex.

  • You could include activities based on their interest_tags. So if someone engages with content about snowboarding you could show them more of that
  • Images can also be processed for interest tags
  • More ranking & activity selectors can be added. Activities close to you, activities from follow suggestions etc.

You can build infinitely complex “for you” style feeds with ranking & activity selectors. Be sure to reach out to our support team in case anything is missing. We’re often adding selector or processors based on customer feedback.

© Getstream.io, Inc. All Rights Reserved.