Intro & Defaults

Feed groups are templates that define how different feeds behave in your application. The configuration options let you create feeds that work differently depending on your use case.

By adjusting settings like ranking, aggregation, activity selectors, and processors, you can tailor each feed group to serve specific purposes in your app.

Note that any write operation to feed groups/views can take up to 30 seconds to propagate to all API nodes.

Built-in groups

There are several feed groups setup by default.

GroupDescription
userA feed setup for the content a user creates. Typically you add activities here when someone writes a post
timelineThe timeline feed is used when you're following. So if user Charlie is following John, timeline:charlie would follow user:john
foryouA version of the timeline feed that adds popular content, and prioritizes popularity over recency
notificationA notification feed. Think of the bell icon you see in most apps
storyA feed set up for users to post story activities (activities with expiration data)
storiesA timeline feed which can be used to follow other users' stories.

You can update the default feed group configurations or create your own feed groups.

Create feed groups

Here's how to create a feed group using the API:

require 'getstream_ruby'

# Assuming you have an initialized API client
# client = GetStream::Client.new(api_key: ENV['STREAM_KEY'], api_secret: ENV['STREAM_SECRET'])

request = GetStream::Generated::Models::CreateFeedGroupRequest.new(
  id: "myid",
  activity_selectors: [
    GetStream::Generated::Models::ActivitySelectorConfig.new(type: "following")
  ],
  ranking: GetStream::Generated::Models::RankingConfig.new(type: "recency"),
  activity_processors: [
    GetStream::Generated::Models::ActivityProcessorConfig.new(type: "text_interest_tags")
  ],
  custom: { description: "My custom feed group" }
)

response = client.feeds.create_feed_group(request)

Applications can't have more than 100 feed groups

Overview of the feed group model

FeedGroupResponse

NameTypeDescriptionConstraints
activity_processorsActivityProcessorConfig[]Configuration for activity processors-
activity_selectorsActivitySelectorConfigResponse[]Configuration for activity selectors-
aggregationAggregationConfigConfiguration for activity aggregation-
created_atnumberWhen the feed group was createdRequired
customobjectCustom data for the feed group-
default_visibilitystringDefault visibility for activities. One of: public, visible, followers, members, private-
deleted_atnumber--
idstringIdentifier within the groupRequired
notificationNotificationConfigConfiguration for notifications-
push_notificationPushNotificationConfigConfiguration for push notifications-
rankingRankingConfigConfiguration for activity ranking-
storiesStoriesConfigConfiguration for stories feature-
updated_atnumberWhen the feed group was last updatedRequired

Alternatively you can use the getOrCreateFeedGroup endpoint that will create and apply settings, or return the existing group.

List feed groups

To list existing feed groups and their configurations:

# List all feed groups (excluding soft-deleted ones)
response = client.feeds.list_feed_groups(false)

# List all feed groups including soft-deleted ones
response = client.feeds.list_feed_groups(true)

Activity Ranking

When ranking activities you can specify a ranking formula.

require 'getstream_ruby'

response = client.feeds.create_feed_group(
  GetStream::Generated::Models::CreateFeedGroupRequest.new(
    id: 'mytimeline',
    ranking: GetStream::Generated::Models::RankingConfig.new(
      type: 'expression',
      score: 'decay_linear(time) * popularity'
    ),
    activity_selectors: [
      GetStream::Generated::Models::ActivitySelectorConfig.new(type: 'following')
    ]
  )
)

For you Feeds

Many apps want to have a "for you" or personalized feed. There are a couple benefits to a personalized feed:

  • Works well even if your users don't spend much time setting up follows
  • Can be a mechanism to discover new content or things to follow

Stream offers a few built-in methods to create a for you feed and gives you the API access to do more advanced customization if needed.

This next example is a bit more complicated. It uses an activity processor to add topic data to activities, activity selectors to pull in content from different sources, and ranks content you're likely to engage with higher in the feed.

require 'getstream_ruby'

# Create feed group with activity processors, activity selectors, and ranking
create_request = GetStream::Generated::Models::CreateFeedGroupRequest.new(
  id: "mytimeline",
  activity_processors: [
    GetStream::Generated::Models::ActivityProcessorConfig.new(type: "text_interest_tags"),
    GetStream::Generated::Models::ActivityProcessorConfig.new(type: "image_interest_tags")
  ],
  activity_selectors: [
    GetStream::Generated::Models::ActivitySelectorConfig.new(type: "popular"),
    GetStream::Generated::Models::ActivitySelectorConfig.new(type: "following"),
    GetStream::Generated::Models::ActivitySelectorConfig.new(type: "interest")
  ],
  ranking: GetStream::Generated::Models::RankingConfig.new(
    type: "interest",
    score: "decay_linear(time) * interest_score * decay_linear(popularity)"
  )
)

client.feeds.create_feed_group(create_request)

# Create and get the feed for a specific user
get_or_create_request = GetStream::Generated::Models::GetOrCreateFeedRequest.new(
  user_id: "thierry"
)
feed_response = client.feeds.get_or_create_feed("mytimeline", "thierry", get_or_create_request)

Aggregation & Notification Feeds

Aggregation groups similar activities together, which is useful for notification feeds and reducing noise.

Aggregation Format

You can create your own aggregated feeds:

require 'getstream_ruby'

my_notification_group = client.feeds.create_feed_group(
  GetStream::Generated::Models::CreateFeedGroupRequest.new(
    id: 'myid',
    # Group by activity type and day
    aggregation: GetStream::Generated::Models::AggregationConfig.new(
      format: '{{ type }}-{{ time.strftime("%Y-%m-%d") }}'
    ),
    # Enable notification tracking
    notification: GetStream::Generated::Models::NotificationConfig.new(
      track_read: true,
      track_seen: true
    )
  )
)

Notification Feed Example

The built-in notification feed comes with the necessary configurations:

require 'getstream_ruby'

# Get or create notification feed
notification_feed_request = GetStream::Generated::Models::GetOrCreateFeedRequest.new(
  limit: 20,
  user_id: 'jane'
)

response = client.feeds.get_or_create_feed('notification', 'jane', notification_feed_request)

# Access the aggregated activities
notifications = response.aggregated_activities if response.respond_to?(:aggregated_activities)

Marking Notifications as Read

notificationFeed.markActivity(
    request = MarkActivityRequest(
        // Mark all notifications as read...
        markAllRead = true,
        // ...or only selected ones
        markRead = listOf(
            /* group names to mark as read */
        )
    )
)

Updating feed groups

It's possible to update any custom or built-in feed group:

require 'getstream_ruby'

update_request = GetStream::Generated::Models::UpdateFeedGroupRequest.new(
  # Fields to update, e.g.:
  # activity_processors: [...],
  # activity_selectors: [...],
  # ranking: GetStream::Generated::Models::RankingConfig.new(...),
  # custom: { ... }
)

response = client.feeds.update_feed_group("myid", update_request)

Deleting feed groups

Deleting feed groups will not cascade delete associated resources. It will make feeds within the feed group unreadable but any fanout that has happened before deletion will stay in effect.

If you need a clean slate during development it is advised to create a new feed group instead.

require 'getstream_ruby'

# Soft delete (default)
client.feeds.delete_feed_group("mytimeline", false)

# Hard delete
# client.feeds.delete_feed_group("mytimeline", true)