Reactions

Overview

You can react to both activities and comments. It's possible to configure any reaction types that best fit your app.

When adding reactions and the enforce_unique flag is set to true, the existing reaction of a user will be overridden with the new reaction. Use this flag if you want to ensure users have a single reaction per each comment/activity. The default value is false, in which case users can have multiple reactions.

// Add a reaction to an activity
_, err = client.Feeds().AddReaction(context.Background(), activityID, &getstream.AddReactionRequest{
  Type:       "like",
  Custom: map[string]any{
    "emoji": "❤️",
  },
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error adding reaction:", err)
}

// Adding a reaction without triggering push notifications
_, err = client.Feeds().AddReaction(context.Background(), activityID, &getstream.AddReactionRequest{
  Type:       "like",
  Custom: map[string]any{
    "emoji": "❤️",
  },
  UserID:   getstream.PtrTo("john"),
  SkipPush: getstream.PtrTo(true),
})
if err != nil {
  log.Fatal("Error adding reaction without push:", err)
}

// Add a reaction to a comment
_, err = client.Feeds().AddCommentReaction(context.Background(), commentID, &getstream.AddCommentReactionRequest{
  Type:      "like",
  Custom: map[string]any{
    "emoji": "👍",
  },
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error adding comment reaction:", err)
}

// Adding a comment reaction without triggering push notifications
_, err = client.Feeds().AddCommentReaction(context.Background(), commentID, &getstream.AddCommentReactionRequest{
  Type:      "like",
  Custom: map[string]any{
    "emoji": "👍",
  },
  UserID:   getstream.PtrTo("john"),
  SkipPush: getstream.PtrTo(true),
})
if err != nil {
  log.Fatal("Error adding comment reaction without push:", err)
}

// Delete activity reaction
_, err = client.Feeds().DeleteActivityReaction(context.Background(), activityID, "like", &getstream.DeleteActivityReactionRequest{
  UserID:     getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error deleting activity reaction:", err)
}

Overview of the reaction model

FeedsReactionResponse

NameTypeDescriptionConstraints
activity_idstringID of the activity that was reacted toRequired
comment_idstringID of the comment that was reacted to-
created_atnumberWhen the reaction was createdRequired
customobjectCustom data for the reaction-
typestringType of reactionRequired
updated_atnumberWhen the reaction was last updatedRequired
userUserResponseUser who created the reactionRequired

By default creating a reaction doesn't create an activity. Pass create_notification_activity: true to add a notification to the reacted-to user's notification feed — see Reaction notification creation timing (added June 23, 2026). The response includes notification_accepted and notification_task_id; notification_created is deprecated and mirrors notification_accepted.

When you read a feed the reactions are included. Here's an example:

feed := client.Feeds().Feed("user", "john")
feedResponse, err := feed.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
  UserID:          getstream.PtrTo("john"),
})

fmt.Println(feedResponse.Data.Activities[0].OwnReactions)
fmt.Println(feedResponse.Data.Activities[0].LatestReactions)
fmt.Println(feedResponse.Data.Activities[0].ReactionGroups)

Querying Reactions

You can query reactions to both activities and comments. Here are some examples:

// Query reactions to a specific activity
val activityReactionList = client.activityReactionList(
    ActivityReactionsQuery(
        activityId = "activity-123",
        filter = ActivityReactionsFilterField.reactionType.equal("like"),
    )
)
activityReactionList.get()
activityReactionList.state.reactions.collect { reactions ->
    // Handle activity reactions
}

// Query reactions to a specific comment
val commentReactionList = client.commentReactionList(
    CommentReactionsQuery(
        commentId = "comment-456",
        filter = CommentReactionsFilterField.reactionType.equal("like"),
    )
)
commentReactionList.get()
commentReactionList.state.reactions.collect { reactions ->
    // Handle comment reactions
}

Batch query activity reactions

batchQueryActivityReactions fetches a single user's reactions across a whole page of activities in one call, so you can merge own_reactions back onto a cached page without calling query reactions once per activity. Pass up to 100 activity IDs per request. The response contains reaction rows only (no activity payloads) and supports the same filter, sort, and pagination options as the single-activity query.

On a client-side connection the returned reactions are always the connected user's. Server-side, pass user_id to choose whose reactions to fetch.

// Fetch the connected user's reactions across a page of activities in one request.
const response = await client.batchQueryActivityReactions({
  activity_ids: activities.map((activity) => activity.id),
  // Optional: filter by reaction type, sort, or paginate with next/prev
  filter: { reaction_type: "like" },
});

// Merge response.reactions back onto the activities as own_reactions
console.log(response.reactions);

Reaction queryable built-in fields

Both batchQueryActivityReactions and batchQueryCommentReactions accept these filter fields.

nametypedescriptionsupported operationsexample
reaction_typestring or list of stringsThe type of reaction$in, $eq{ reaction_type: { $in: [ 'like', 'heart', 'thumbs_up' ] } }
user_idstring or list of stringsThe ID of the user who created the reaction$in, $eq{ user_id: { $eq: 'user_123' } }
created_atstring, must be formatted as an RFC3339 timestampThe time the reaction was created$eq, $gt, $gte, $lt, $lte{ created_at: { $gte: '2023-12-04T09:30:20.45Z' } }

Batch query comment reactions

batchQueryCommentReactions is the comment counterpart of batch query activity reactions. It fetches a single user's reactions across up to 100 comments in one call, returning reaction rows only (no comment payloads). Use it to hydrate own_reactions for a whole comment thread without a request per comment. It accepts the same filter fields, sort, and pagination options.

As with activities, a client-side connection returns the connected user's reactions; server-side, pass user_id.

const response = await client.batchQueryCommentReactions({
  comment_ids: comments.map((comment) => comment.id),
  filter: { reaction_type: "like" },
});

console.log(response.reactions);