const myNotificationGrpup = await serverClient.feeds.createFeedGroup({
id: "myid",
// Group by activity type and day
aggregation: { format: '{{ type }}-{{ time.strftime("%Y-%m-%d") }}' },
// Enable notification tracking
notification: {
track_read: true,
track_seen: true,
},
});Notification Feeds
Notification feeds let you notify users about relevant interactions, for example
- someone started to follow them
- someone liked their post
- someone left a comment on their post
Creating notification feeds
The built-in notification feed comes with the necessary configurations, but it's also possible to create your own notification feed group:
myNotificationGroup, err := client.Feeds().CreateFeedGroup(context.Background(), &getstream.CreateFeedGroupRequest{
ID: "myid2",
// Group by activity type and day
Aggregation: &getstream.AggregationConfig{
Format: getstream.PtrTo("{{ type }}-{{ time.strftime(\"%Y-%m-%d\") }}"),
},
// Enable notification tracking
Notification: &getstream.NotificationConfig{
TrackRead: getstream.PtrTo(true),
TrackSeen: getstream.PtrTo(true),
},
})
if err != nil {
log.Fatal("Error creating feed group:", err)
}// Create notification feed group with aggregation and tracking
$request = new GeneratedModels\CreateFeedGroupRequest(
id: "myid",
defaultVisibility: 'public',
// Group by activity type and day
aggregation: new GeneratedModels\AggregationConfig(
format: '{{ type }}-{{ time.strftime("%Y-%m-%d") }}'
),
// Enable notification tracking
notification: new GeneratedModels\NotificationConfig(
trackRead: true,
trackSeen: true
)
);
// Create the feed group
$response = $feedsClient->createFeedGroup($request);await _feedsV3Client.CreateFeedGroupAsync(new CreateFeedGroupRequest
{
ID = "aggregated-group",
DefaultVisibility = "public",
ActivityProcessors = new List<ActivityProcessorConfig>
{
new() { Type = "default" }
},
Aggregation = new AggregationConfig
{
Format = "{{ type }}-{{ time.strftime(\"%Y-%m-%d\") }}"
}
});self.client.feeds.create_feed_group(
id = feed_group_id,
default_visibility="public",
activity_processors=[
ActivityProcessorConfig(type="default")
],
aggregation=AggregationConfig(
format="{{ type }}-{{ time.strftime(\"%Y-%m-%d\") }}"
)
)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 configuration
The notification config includes several settings that control how notifications are tracked and deduplicated:
- TrackSeen: When enabled, tracks which notifications have been seen by the user
- TrackRead: When enabled, tracks which notifications have been read by the user
- DeduplicationWindow: Controls how duplicate notifications are handled (only available for the built-in
notificationfeed group)- Empty string (
"") = always deduplicate (default behavior) - Duration string (e.g.,
"24h","7d") = time-based deduplication window
- Empty string (
Note: Comments are not deduplicated. Each comment will create a separate notification activity, regardless of the deduplication window setting.
The built-in notification feed group has deduplication enabled by default (always deduplicate). To change the deduplication window, you need to update the notification feed group.
Aggregation format
The built-in notification feed uses the following aggregation format: "{{ target_id }}_{ type }}_{{ time.strftime('%Y-%m-%d') }}". You can change this syntax by updating the notification feed group.
You can see all supported fields and syntax for aggregation in the Aggregation guide.
It's possible to turn off aggregation, but still enable notification tracking. In that case every new activity will increase unread/unseen count. When you have aggregation turned on, unread/unseen will refer to the number of aggregated groups.
Adding notification activities
The built-in notification groups can automatically create notifications for the most common interactions (see Built-in notification feed section).
If you want to extend that, or create your own notification feed, you can add notification activities using server-side integration. You can add webhook handlers for the relevant events to create notifications without API calls from your client-side application to your server-side application.
It's important to note that target_id is only defined if a notification is created by Stream API. If you want to extend or replace this behavior by adding notification activities from your own application, you most likely need to extend the default aggregation format. You can see all supported fields and syntax for aggregation in the Aggregation guide.
Manual Activity Addition to Notification Feeds
You can directly add activities to notification feeds for complete control over notifications (only available server-side):
// Add a custom notification directly to a user's notification feed
await serverClient.feeds.addActivity({
feeds: ["notification:user-123"], // Target user's notification feed
type: "milestone", // Custom activity type
text: "You've reached 1000 followers!",
user_id: "user_id",
extra_data: {
milestone_type: "followers",
count: 1000,
},
});
// Add activity to custom notification feed group
await serverClient.feeds.addActivity({
feeds: ["alerts:user-123"], // Custom notification feed group
type: "system_alert",
text: "Your subscription expires in 3 days",
user_id: "user_id",
});ctx := context.Background()
// Add a custom notification directly to a user's notification feed
_, err = client.Feeds().AddActivity(ctx, &getstream.AddActivityRequest{
Feeds: []string{"notification:john"}, // Target user's notification feed
Type: "milestone", // Custom activity type
Text: getstream.PtrTo("You've reached 1000 followers!"),
UserID: getstream.PtrTo("<user id>"),
Custom: map[string]any{
"milestone_type": "followers",
"count": 1000,
},
})
if err != nil {
log.Fatal("Error adding milestone activity:", err)
}
// Add activity to custom notification feed group
_, err = client.Feeds().AddActivity(ctx, &getstream.AddActivityRequest{
Feeds: []string{"alerts:john"}, // Custom notification feed group
Type: "system_alert",
Text: getstream.PtrTo("Your subscription expires in 3 days"),
UserID: getstream.PtrTo("<user id>"),
})
if err != nil {
log.Fatal("Error adding system alert activity:", err)
}use GetStream\GeneratedModels;
// Add a custom notification directly to a user's notification feed
$feedsClient->addActivity(new GeneratedModels\AddActivityRequest(
feeds: ["notification:john"], // Target user's notification feed
type: "milestone", // Custom activity type
text: "You've reached 1000 followers!",
userID: "<user id>",
custom: (object)[
"milestone_type" => "followers",
"count" => 1000,
]
));
// Add activity to custom notification feed group
$feedsClient->addActivity(new GeneratedModels\AddActivityRequest(
feeds: ["alerts:john"], // Custom notification feed group
type: "system_alert",
text: "Your subscription expires in 3 days",
userID: "<user id>"
));Important: When adding activities directly to notification feeds, ensure the activity type is included in the feed group's push_types configuration to trigger push notifications.
Built-in notification feed
Creating notification activities
The built-in notification feed allows you to automatically create notification activities. The following actions are supported and will automatically create notification activities for the target user depending on the action.
| Action | Trigger User | Target User (Recipient) | Notification Type | Notification Text | Deduplicated? | Notes |
|---|---|---|---|---|---|---|
| React to Activity | User who reacts (e.g., Bob) | Activity author (e.g., Alice) | reaction | {user} reacted to your activity | ✅ Yes | Multiple reactions from the same user on the same activity are deduplicated within the deduplication window |
| React to Comment | User who reacts (e.g., Charlie) | Comment author (e.g., Bob) | comment_reaction | {user} reacted to your comment | ✅ Yes | Multiple reactions from the same user on the same comment are deduplicated within the deduplication window. The activity author does NOT receive a notification for reactions |
| Comment on Activity | User who comments (e.g., Bob) | Activity author (e.g., Alice) | comment | {user} commented on your activity | ❌ No | Each comment creates a new notification; not deduplicated |
| Reply to Comment | User who replies (e.g., Charlie) | Comment author (e.g., Bob) | comment_reply | {user} replied to your comment | ❌ No | Each reply creates a new notification; not deduplicated. The activity author does NOT receive a notification for replies |
| Follow User | User who follows (e.g., Bob) | User being followed (e.g., Alice) | follow | {user} started following you | ✅ Yes | Multiple follows/unfollows from the same user are deduplicated within the deduplication window |
| Mention in Activity | User who creates activity with mention (e.g., Alice) | Mentioned user (e.g., Bob) | mention | {user} mentioned you in an activity | ✅ Yes | Multiple mentions from the same user on the same activity are deduplicated within the deduplication window |
| Mention in Comment | User who creates comment with mention (e.g., Charlie) | Mentioned user (e.g., Bob) | comment_mention | {user} mentioned you in a comment | ✅ Yes | Multiple mentions from the same user on the same comment are deduplicated within the deduplication window. The activity author does NOT receive a notification for mentions (they already get a comment notification) |
| Update Activity (add mentions) | User who updates activity (e.g., Alice) | Mentioned user (e.g., Bob) | mention | {user} mentioned you in an activity | ✅ Yes | When mentions are added via UpdateActivity or UpdateActivityPartial with handle_mention_notifications=true, mention notifications are automatically created for newly mentioned users. Multiple mentions from the same user on the same activity are deduplicated within the deduplication window |
| Update Comment (add mentions) | User who updates comment (e.g., Charlie) | Mentioned user (e.g., Bob) | comment_mention | {user} mentioned you in a comment | ✅ Yes | When mentions are added via UpdateComment with handle_mention_notifications=true, comment_mention notifications are automatically created for newly mentioned users. Multiple mentions from the same user on the same comment are deduplicated within the deduplication window. The activity author does NOT receive a notification for mentions (they already get a comment notification) |
Adding notifications with the create notification activity flag only works if the target user (the one who should receive the notification) has a feed with group notification, and id <user id>.
// Eric follows Jane
ericFeed.follow(
targetFid = janeFeed.fid,
createNotificationActivity = true // When true Jane's notification feed will be updated with follow activity
)
// Eric comments on Jane's activity
ericFeed.addComment(
ActivityAddCommentRequest(
comment = "Agree!",
activityId = janeActivity.activityId,
createNotificationActivity = true // When true Jane's notification feed will be updated with comment activity
)
)
// Eric reacts to Jane's activity
ericFeed.addReaction(
activityId = janeActivity.activityId,
request = AddReactionRequest(
type = "like",
createNotificationActivity = true // When true Jane's notification feed will be updated with reaction activity
),
)
// Eric reacts to a comment posted to Jane's activity by Sara
ericFeed.addCommentReaction(
commentId = saraComment.id,
request = AddCommentReactionRequest(
type = "like",
createNotificationActivity = true // When true Sara's notification feed will be updated with comment reaction activity
),
)// Eric follows Jane
await ericTimeline.follow(janeFeed, {
// When true Jane's notification feed will be updated with follow activity
create_notification_activity: true,
});
// Eric comments on Jane's activity
await ericClient.addComment({
comment: "Agree!",
object_id: janeActivity.id,
object_type: "activity",
// When true Jane's notification feed will be updated with comment activity
create_notification_activity: true,
});
// Eric reacts to Jane's activity
await ericClient.addReaction({
activity_id: janeActivity.id,
// When true Jane's notification feed will be updated with reaction activity
type: "like",
create_notification_activity: true,
});
// Eric reacts to a comment posted to Jane's activity by Sara
await ericClient.addCommentReaction({
id: saraComment.id,
type: "like",
// When true Sara's notification feed will be updated with comment reaction activity
create_notification_activity: true,
});// Eric follows Jane
await ericTimeline.follow(janeFeed, {
// When true Jane's notification feed will be updated with follow activity
create_notification_activity: true,
});
// Eric comments on Jane's activity
await ericClient.addComment({
comment: "Agree!",
object_id: janeActivity.id,
object_type: "activity",
// When true Jane's notification feed will be updated with comment activity
create_notification_activity: true,
});
// Eric reacts to Jane's activity
await ericClient.addReaction({
activity_id: janeActivity.id,
// When true Jane's notification feed will be updated with reaction activity
type: "like",
create_notification_activity: true,
});
// Eric reacts to a comment posted to Jane's activity by Sara
await ericClient.addCommentReaction({
id: saraComment.id,
type: "like",
// When true Sara's notification feed will be updated with comment reaction activity
create_notification_activity: true,
});// Eric follows Jane
await ericTimeline.follow(janeFeed, {
// When true Jane's notification feed will be updated with follow activity
create_notification_activity: true,
});
// Eric comments on Jane's activity
await ericClient.addComment({
comment: "Agree!",
object_id: janeActivity.id,
object_type: "activity",
// When true Jane's notification feed will be updated with comment activity
create_notification_activity: true,
});
// Eric reacts to Jane's activity
await ericClient.addReaction({
activity_id: janeActivity.id,
// When true Jane's notification feed will be updated with reaction activity
type: "like",
create_notification_activity: true,
});
// Eric reacts to a comment posted to Jane's activity by Sara
await ericClient.addCommentReaction({
id: saraComment.id,
type: "like",
// When true Sara's notification feed will be updated with comment reaction activity
create_notification_activity: true,
});// Eric follows Jane
await ericFeed.follow(
targetFid: janeFeed.fid,
createNotificationActivity:
true, // When true Jane's notification feed will be updated with follow activity
);
// Eric comments on Jane's activity
await ericFeed.addComment(
request: ActivityAddCommentRequest(
comment: 'Agree!',
activityId: janeActivity.activityId,
createNotificationActivity:
true, // When true Jane's notification feed will be updated with comment activity
),
);
// Eric reacts to Jane's activity
await ericFeed.addActivityReaction(
activityId: janeActivity.activityId,
request: const AddReactionRequest(
type: 'like',
createNotificationActivity: true, // When true Jane's notification feed will be updated with reaction activity
),
);
// Eric reacts to a comment posted to Jane's activity by Sara
await ericFeed.addCommentReaction(
commentId: saraComment.activityId,
request: const AddCommentReactionRequest(
type: 'like',
createNotificationActivity:
true, // When true Sara's notification feed will be updated with comment reaction activity
),
);// Eric follows Jane
await serverClient.feeds.follow({
source: ericTimeline.feed,
target: janeFeed.feed,
// When true Jane's notification feed will be updated with follow activity
create_notification_activity: true,
});
// Eric comments on Jane's activity
await serverClient.feeds.addComment({
comment: "Agree!",
object_id: janeActivity.id,
object_type: "activity",
// When true Jane's notification feed will be updated with comment activity
create_notification_activity: true,
user_id: "eric",
});
// Eric reacts to Jane's activity
await serverClient.feeds.addReaction({
activity_id: janeActivity.id,
// When true Jane's notification feed will be updated with reaction activity
type: "like",
create_notification_activity: true,
user_id: "eric",
});
// Eric reacts to a comment posted to Jane's activity by Sara
await serverClient.feeds.addCommentReaction({
id: saraComment.id,
type: "like",
// When true Sara's notification feed will be updated with comment reaction activity
create_notification_activity: true,
user_id: "eric",
});ctx := context.Background()
// Eric follows Jane
_, err = client.Feeds().Follow(ctx, &getstream.FollowRequest{
Source: "user:eric",
Target: "user:jane",
CreateNotificationActivity: getstream.PtrTo(true), // When true Jane's notification feed will be updated with follow activity
})
if err != nil {
log.Fatal("Error following user:", err)
}
// Eric comments on Jane's activity
_, err = client.Feeds().AddComment(ctx, &getstream.AddCommentRequest{
Comment: "Agree!",
ObjectID: "janeActivity.id", // This would be the actual activity ID
ObjectType: "activity",
CreateNotificationActivity: getstream.PtrTo(true), // When true Jane's notification feed will be updated with comment activity
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error adding comment:", err)
}
// Eric reacts to Jane's activity
_, err = client.Feeds().AddReaction(ctx, "janeActivity.id", &getstream.AddReactionRequest{ // This would be the actual activity ID
Type: "like",
CreateNotificationActivity: getstream.PtrTo(true), // When true Jane's notification feed will be updated with reaction activity
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error adding reaction:", err)
}
// Eric reacts to a comment posted to Jane's activity by Sara
_, err = client.Feeds().AddCommentReaction(ctx, "saraComment.id", &getstream.AddCommentReactionRequest{ // This would be the actual comment ID
Type: "like",
CreateNotificationActivity: getstream.PtrTo(true), // When true Sara's notification feed will be updated with comment reaction activity
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error adding comment reaction:", err)
}use GetStream\GeneratedModels;
// Eric follows Jane
$feedsClient->follow(new GeneratedModels\FollowRequest(
source: "user:eric",
target: "user:jane",
createNotificationActivity: true // When true Jane's notification feed will be updated with follow activity
));
// Eric comments on Jane's activity
$feedsClient->addComment(new GeneratedModels\AddCommentRequest(
comment: "Agree!",
objectID: "janeActivity.id", // This would be the actual activity ID
objectType: "activity",
createNotificationActivity: true, // When true Jane's notification feed will be updated with comment activity
userID: "eric"
));
// Eric reacts to Jane's activity
$feedsClient->addActivityReaction("janeActivity.id", new GeneratedModels\AddReactionRequest( // This would be the actual activity ID
type: "like",
createNotificationActivity: true, // When true Jane's notification feed will be updated with reaction activity
userID: "eric"
));
// Eric reacts to a comment posted to Jane's activity by Sara
$feedsClient->addCommentReaction("saraComment.id", new GeneratedModels\AddCommentReactionRequest( // This would be the actual comment ID
type: "like",
createNotificationActivity: true, // When true Sara's notification feed will be updated with comment reaction activity
userID: "eric"
));Updating mentions in activities and comments
You can also create or remove mention notifications when updating activities or comments. This flag defaults to false for all endpoints it's supported in.
// Alice updates her activity to mention Bob
ericFeed.updateActivity(
activityId = activityId,
text = "Hey @Bob check this out!",
mentionedUserIds = listOf("bob"),
handleMentionNotifications = true // When true, Bob will receive a mention notification
)
// Alice updates her comment to mention Charlie
ericFeed.updateComment(
commentId = commentId,
comment = "Hey @Charlie!",
mentionedUserIds = listOf("charlie"),
handleMentionNotifications = true // When true, Charlie will receive a comment_mention notification
)
// Alice removes mentions from her activity
ericFeed.updateActivity(
activityId = activityId,
text = "Updated text without mentions",
mentionedUserIds = emptyList(),
handleMentionNotifications = true // When true, mention notifications for removed users are deleted
)// Alice updates her activity to mention Bob
await ericClient.updateActivity({
id: activityId,
text: "Hey @Bob check this out!",
mentioned_user_ids: ["bob"],
handle_mention_notifications: true, // When true, Bob will receive a mention notification
});
// Alice updates her comment to mention Charlie
await ericClient.updateComment({
id: commentId,
comment: "Hey @Charlie!",
mentioned_user_ids: ["charlie"],
handle_mention_notifications: true, // When true, Charlie will receive a comment_mention notification
});
// Alice removes mentions from her activity
await ericClient.updateActivity({
id: activityId,
text: "Updated text without mentions",
mentioned_user_ids: [],
handle_mention_notifications: true, // When true, mention notifications for removed users are deleted
});// Alice updates her activity to mention Bob
await ericFeed.updateActivity(
activityId: activityId,
request: UpdateActivityRequest(
text: "Hey @Bob check this out!",
mentionedUserIDs: ["bob"],
handleMentionNotifications: true, // When true, Bob will receive a mention notification
),
);
// Alice updates her comment to mention Charlie
await ericFeed.updateComment(
commentId: commentId,
request: UpdateCommentRequest(
comment: "Hey @Charlie!",
mentionedUserIDs: ["charlie"],
handleMentionNotifications: true, // When true, Charlie will receive a comment_mention notification
),
);
// Alice removes mentions from her activity
await ericFeed.updateActivity(
activityId: activityId,
request: UpdateActivityRequest(
text: "Updated text without mentions",
mentionedUserIDs: [],
handleMentionNotifications: true, // When true, mention notifications for removed users are deleted
),
);// Alice updates her activity to mention Bob
await serverClient.feeds.updateActivity({
id: activityId,
text: "Hey @Bob check this out!",
mentioned_user_ids: ["bob"],
handle_mention_notifications: true, // When true, Bob will receive a mention notification
user_id: "alice",
});
// Alice updates her comment to mention Charlie
await serverClient.feeds.updateComment({
id: commentId,
comment: "Hey @Charlie!",
mentioned_user_ids: ["charlie"],
handle_mention_notifications: true, // When true, Charlie will receive a comment_mention notification
user_id: "alice",
});
// Alice removes mentions from her activity
await serverClient.feeds.updateActivity({
id: activityId,
text: "Updated text without mentions",
mentioned_user_ids: [],
handle_mention_notifications: true, // When true, mention notifications for removed users are deleted
user_id: "alice",
});ctx := context.Background()
// Alice updates her activity to mention Bob
_, err = client.Feeds().UpdateActivity(ctx, activityId, &getstream.UpdateActivityRequest{
Text: "Hey @Bob check this out!",
MentionedUserIDs: []string{"bob"},
HandleMentionNotifications: getstream.PtrTo(true), // When true, Bob will receive a mention notification
UserID: getstream.PtrTo("alice"),
})
if err != nil {
log.Fatal("Error updating activity:", err)
}
// Alice updates her comment to mention Charlie
_, err = client.Feeds().UpdateComment(ctx, commentId, &getstream.UpdateCommentRequest{
Comment: "Hey @Charlie!",
MentionedUserIDs: getstream.PtrTo([]string{"charlie"}),
HandleMentionNotifications: getstream.PtrTo(true), // When true, Charlie will receive a comment_mention notification
UserID: getstream.PtrTo("alice"),
})
if err != nil {
log.Fatal("Error updating comment:", err)
}
// Alice removes mentions from her activity
_, err = client.Feeds().UpdateActivity(ctx, activityId, &getstream.UpdateActivityRequest{
Text: "Updated text without mentions",
MentionedUserIDs: []string{},
HandleMentionNotifications: getstream.PtrTo(true), // When true, mention notifications for removed users are deleted
UserID: getstream.PtrTo("alice"),
})
if err != nil {
log.Fatal("Error updating activity:", err)
}use GetStream\GeneratedModels;
// Alice updates her activity to mention Bob
$feedsClient->updateActivity(activityId, new GeneratedModels\UpdateActivityRequest(
text: "Hey @Bob check this out!",
mentionedUserIDs: ["bob"],
handleMentionNotifications: true, // When true, Bob will receive a mention notification
userID: "alice"
));
// Alice updates her comment to mention Charlie
$feedsClient->updateComment(commentId, new GeneratedModels\UpdateCommentRequest(
comment: "Hey @Charlie!",
mentionedUserIDs: ["charlie"],
handleMentionNotifications: true, // When true, Charlie will receive a comment_mention notification
userID: "alice"
));
// Alice removes mentions from her activity
$feedsClient->updateActivity(activityId, new GeneratedModels\UpdateActivityRequest(
text: "Updated text without mentions",
mentionedUserIDs: [],
handleMentionNotifications: true, // When true, mention notifications for removed users are deleted
userID: "alice"
));Commenting and reacting to your own activities and comments will not create notification activities.
Deleting notification activities
When you add notification activities with create_notification_activity you can also have the API automatically remove these when the corresponding trigger entity is deleted.
This is done by using the flag delete_notification_activity which defaults to false for all endpoints it's supported in.
| Action | Notification Type Deleted | Notes |
|---|---|---|
| Remove Activity Reaction | reaction | Only the notification activity created by the user removing the reaction is deleted. Other users' reaction notifications remain unaffected. |
| Remove Comment Reaction | comment_reaction | Only the notification activity created by the user removing the reaction is deleted. Other users' comment reaction notifications remain unaffected. |
| Delete Comment | comment | Deletes the comment notification for the activity author. |
| Delete Comment | comment_mention | When a comment with mentions is deleted, comment_mention notifications are deleted for all mentioned users if delete_notification_activity=true. |
| Unfollow User | follow | Only the notification activity created by the user performing the unfollow is deleted. |
| Delete Activity | mention | When an activity with mentions is deleted, mention notifications are deleted for all mentioned users if delete_notification_activity=true. |
| Delete Activities (batch) | mention | When multiple activities with mentions are deleted via DeleteActivities with delete_notification_activity=true, mention notifications are deleted for all mentioned users across all deleted activities. |
| Update Activity (remove mentions) | mention | When mentions are removed via UpdateActivity or UpdateActivityPartial with handle_mention_notifications=true, mention notifications are automatically removed for users no longer mentioned. |
| Update Comment (remove mentions) | comment_mention | When mentions are removed via UpdateComment with handle_mention_notifications=true, comment_mention notifications are automatically removed for users no longer mentioned. |
Deletion Scope: The deletion behavior differs depending on the action:
- Reactions and Follows: Only the notification activity created by the specific user performing the deletion is removed. Other users' notifications remain unaffected.
- Activities and Comments with Mentions: When an activity or comment containing mentions is deleted, notification activities are removed for all mentioned users if
delete_notification_activity=true.
// Eric unfollows Jane
ericFeed.unfollow(
targetFid = janeFeed.fid,
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity = true
)
// Eric removes his comment
ericFeed.deleteComment(
commentId = commentId,
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity = true
)
// Eric removes his activity reaction
ericFeed.deleteReaction(
activityId = janeActivity.activityId,
type = "like",
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity = true
)
// Eric removes his comment reaction
ericFeed.deleteCommentReaction(
commentId = saraComment.id,
type = "like",
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity = true
)
// Eric deletes his activity with mentions
ericFeed.deleteActivity(
activityId = activityId,
// When true, mention notifications for all mentioned users will be removed
deleteNotificationActivity = true
)
// Eric deletes multiple activities with mentions (batch operation)
ericFeed.deleteActivities(
activityIds = listOf(activityId1, activityId2),
// When true, mention notifications for all mentioned users will be removed
deleteNotificationActivity = true
)// Eric unfollows Jane
await ericTimeline.unfollow(janeFeed, {
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
});
// Eric removes his comment
await ericClient.deleteComment({
id: commentId,
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
});
// Eric removes his activity reaction
await ericClient.deleteActivityReaction({
activity_id: janeActivity.id,
type: "like",
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
});
// Eric removes his comment reaction
await ericClient.deleteCommentReaction({
id: saraComment.id,
type: "like",
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
});
// Eric deletes his activity with mentions
await ericClient.deleteActivity({
id: activityId,
// When true, mention notifications for all mentioned users will be removed
delete_notification_activity: true,
});
// Eric deletes multiple activities with mentions (batch operation)
await ericClient.deleteActivities({
ids: [activityId1, activityId2],
// When true, mention notifications for all mentioned users will be removed
delete_notification_activity: true,
});// Eric unfollows Jane
await ericFeed.unfollow(
targetFid: janeFeed.fid,
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity: true,
);
// Eric removes his comment
await ericFeed.deleteComment(
commentId: commentId,
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity: true,
);
// Eric removes his activity reaction
await ericFeed.deleteActivityReaction(
activityId: janeActivity.activityId,
type: 'like',
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity: true,
);
// Eric removes his comment reaction
await ericFeed.deleteCommentReaction(
commentId: saraComment.id,
type: 'like',
// When true the corresponding notification activity will be removed from Jane's notification feed
deleteNotificationActivity: true,
);
// Eric deletes his activity with mentions
await ericFeed.deleteActivity(
activityId: activityId,
// When true, mention notifications for all mentioned users will be removed
deleteNotificationActivity: true,
);
// Eric deletes multiple activities with mentions (batch operation)
await ericFeed.deleteActivities(
activityIds: [activityId1, activityId2],
// When true, mention notifications for all mentioned users will be removed
deleteNotificationActivity: true,
);// Eric unfollows Jane
await serverClient.feeds.unfollow({
source: ericTimeline.feed,
target: janeFeed.feed,
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
});
// Eric removes his comment
await serverClient.feeds.deleteComment({
id: commentId,
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
user_id: "eric",
});
// Eric removes his activity reaction
await serverClient.feeds.deleteActivityReaction({
activity_id: janeActivity.id,
type: "like",
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
user_id: "eric",
});
// Eric removes his comment reaction
await serverClient.feeds.deleteCommentReaction({
id: saraComment.id,
type: "like",
// When true the corresponding notification activity will be removed from Jane's notification feed
delete_notification_activity: true,
user_id: "eric",
});
// Eric deletes his activity with mentions
await serverClient.feeds.deleteActivity({
id: activityId,
// When true, mention notifications for all mentioned users will be removed
delete_notification_activity: true,
user_id: "eric",
});
// Eric deletes multiple activities with mentions (batch operation)
await serverClient.feeds.deleteActivities({
ids: [activityId1, activityId2],
// When true, mention notifications for all mentioned users will be removed
delete_notification_activity: true,
user_id: "eric",
});ctx := context.Background()
// Eric unfollows Jane
_, err = client.Feeds().Unfollow(ctx, &getstream.UnfollowRequest{
Source: "user:eric",
Target: "user:jane",
DeleteNotificationActivity: getstream.PtrTo(true), // When true the corresponding notification activity will be removed from Jane's notification feed
})
if err != nil {
log.Fatal("Error unfollowing user:", err)
}
// Eric removes his comment
_, err = client.Feeds().DeleteComment(ctx, "commentId", &getstream.DeleteCommentRequest{ // This would be the actual comment ID
DeleteNotificationActivity: getstream.PtrTo(true), // When true the corresponding notification activity will be removed from Jane's notification feed
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error deleting comment:", err)
}
// Eric removes his activity reaction
_, err = client.Feeds().DeleteReaction(ctx, "janeActivity.id", &getstream.DeleteReactionRequest{ // This would be the actual activity ID
Type: "like",
DeleteNotificationActivity: getstream.PtrTo(true), // When true the corresponding notification activity will be removed from Jane's notification feed
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error deleting reaction:", err)
}
// Eric removes his comment reaction
_, err = client.Feeds().DeleteCommentReaction(ctx, "saraComment.id", &getstream.DeleteCommentReactionRequest{ // This would be the actual comment ID
Type: "like",
DeleteNotificationActivity: getstream.PtrTo(true), // When true the corresponding notification activity will be removed from Jane's notification feed
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error deleting comment reaction:", err)
}
// Eric deletes his activity with mentions
_, err = client.Feeds().DeleteActivity(ctx, "activityId", &getstream.DeleteActivityRequest{ // This would be the actual activity ID
DeleteNotificationActivity: getstream.PtrTo(true), // When true, mention notifications for all mentioned users will be removed
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error deleting activity:", err)
}
// Eric deletes multiple activities with mentions (batch operation)
_, err = client.Feeds().DeleteActivities(ctx, &getstream.DeleteActivitiesRequest{
ActivityIDs: []string{"activityId1", "activityId2"},
DeleteNotificationActivity: getstream.PtrTo(true), // When true, mention notifications for all mentioned users will be removed
UserID: getstream.PtrTo("eric"),
})
if err != nil {
log.Fatal("Error deleting activities:", err)
}use GetStream\GeneratedModels;
// Eric unfollows Jane
$feedsClient->unfollow(new GeneratedModels\UnfollowRequest(
source: "user:eric",
target: "user:jane",
deleteNotificationActivity: true // When true the corresponding notification activity will be removed from Jane's notification feed
));
// Eric removes his comment
$feedsClient->deleteComment("commentId", new GeneratedModels\DeleteCommentRequest( // This would be the actual comment ID
deleteNotificationActivity: true, // When true the corresponding notification activity will be removed from Jane's notification feed
userID: "eric"
));
// Eric removes his activity reaction
$feedsClient->deleteActivityReaction("janeActivity.id", new GeneratedModels\DeleteReactionRequest( // This would be the actual activity ID
type: "like",
deleteNotificationActivity: true, // When true the corresponding notification activity will be removed from Jane's notification feed
userID: "eric"
));
// Eric removes his comment reaction
$feedsClient->deleteCommentReaction("saraComment.id", new GeneratedModels\DeleteCommentReactionRequest( // This would be the actual comment ID
type: "like",
deleteNotificationActivity: true, // When true the corresponding notification activity will be removed from Jane's notification feed
userID: "eric"
));
// Eric deletes his activity with mentions
$feedsClient->deleteActivity("activityId", new GeneratedModels\DeleteActivityRequest( // This would be the actual activity ID
deleteNotificationActivity: true, // When true, mention notifications for all mentioned users will be removed
userID: "eric"
));
// Eric deletes multiple activities with mentions (batch operation)
$feedsClient->deleteActivities(new GeneratedModels\DeleteActivitiesRequest(
activityIDs: ["activityId1", "activityId2"],
deleteNotificationActivity: true, // When true, mention notifications for all mentioned users will be removed
userID: "eric"
));Trigger and Target
The trigger is the entity that triggered the creation of the notification activity. This can be a follow, a reaction or a comment. When the trigger is a comment the comment data is available on the trigger object, this allows for deep linking back to the comment that triggered the notification.
The target is the receiver of the trigger action. This can be a feed (e.g., a user's feed), an activity or a comment. When the target is an activity the activity data will be present in the target object. When the target is a comment the parent activity data and comment data will be present in the target object.
Example: A reply to a comment will include the data of the reply comment in the trigger and the parent comment and activity in the target.
{
"target": {
"id": "<activity_id>",
"type": "<activity_type>",
"user_id": "<activity_user_id>",
"comment": {
"id": "<parent_comment_id>",
"comment": "this is the parent comment",
"user_id": "<parent_comment_user_id>"
}
},
"trigger": {
"text": "<comment_user_id> replied to your comment",
"type": "comment_reply",
"comment": {
"id": "<comment_id>",
"user_id": "<comment_user_id>",
"comment": "this is the reply comment"
}
}
}Aggregating on comments and activities
By default the built-in notification feed aggregates on activities only with the aggregation format {{ target_id }}-{{ type }}-{{ time.strftime('%Y-%m-%d') }}.
If you want to aggregate on comments and activities alike you need to update the aggregation format to
{% if comment_id %}
{{ comment_id }}_{{ type }}_{{ time.strftime('%Y-%m-%d') }}
{% else %}
{{ target_id }}_{{ type }}_{{ time.strftime('%Y-%m-%d') }}
{% endif %}This lets you show notifications like
- Your comment has 5 new likes or
- Your comment has 3 new replies
Reading notification activities
let notificationFeed = client.feed(group: "notification", id: "jane")
let notifications = try await notificationFeed.getOrCreate()val notificationFeed = client.feed(group = "notification", id = "jane")
val notifications = notificationFeed.getOrCreate()// Read notifications
await notificationFeed.getOrCreate({
limit: 20,
});
console.log(notificationFeed.currentState.is_loading_activities);
console.log(notificationFeed.currentState.aggregated_activities);
await notificationFeed.getNextPage();const notificationFeed = client.feed("notification", "jane");
await notificationFeed.getOrCreate({
limit: 20,
});
const { aggregated_activities, isLoading, hasNextPage, loadNextPage } =
useAggregatedActivities(feed) ?? {};const notificationFeed = client.feed("notification", "jane");
await notificationFeed.getOrCreate({
limit: 20,
});
const { aggregated_activities, isLoading, hasNextPage, loadNextPage } =
useAggregatedActivities(feed) ?? {};final notificationFeed = client.feed(group: 'notification', id: 'john');
await notificationFeed.getOrCreate();const notificationFeed = client.feed("notification", "jane");
// Read notifications
const notifications = (
await notificationFeed.getOrCreate({
limit: 20,
user_id: "<user_id>",
})
).aggregated_activities;notificationFeed := client.Feeds().Feed("notification", "john")
// Read notifications
response, err := notificationFeed.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
Limit: getstream.PtrTo(20),
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
log.Printf("Response: %+v\n", response.Data.AggregatedActivities)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();use GetStream\GeneratedModels\GetOrCreateFeedRequest;
$notificationFeed = $feedsClient->feed("notification", "jane");
// Read notifications
$feedRequest = new GetOrCreateFeedRequest(
limit: 20,
userID: "jane"
);
$response = $notificationFeed->getOrCreateFeed($feedRequest);
// Access the aggregated activities
$notifications = $response->data->aggregatedActivities;var feedResponse1 = await _feedsV3Client.GetOrCreateFeedAsync(
FeedGroupID: "user",
FeedID: _testFeedId,
request: new GetOrCreateFeedRequest { UserID = _testUserId }
);
var feedResponse2 = await _feedsV3Client.GetOrCreateFeedAsync(
FeedGroupID: "user",
FeedID: _testFeedId2,
request: new GetOrCreateFeedRequest { UserID = _testUserId2 }
);feed_response_1 = self.test_feed.get_or_create(user_id=self.test_user_id)
feed_response_2 = self.test_feed_2.get_or_create(
user_id=self.test_user_id_2
)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)This is what Jane's notification feed looks like after the above interactions (only relevant fields shown):
- Three aggregated activity groups:
<activity id>-comment-2025-08-04<activity id>-reaction-2025-08-04<feed id>-follow-2025-08-04
notification_contexthas information about the activity/action that triggered the notification- Please note that
notification_contextfield is only defined if you're using the built-innotificationfeed andcreate_notification_activityflag
- Please note that
When reading notifications, every aggregated activity group contains at most 100 activities (can be configured with aggregation group limit). The user_count field is also computed from the last n activities, defined by aggregation group limit.
If a group has more activities than the limit, user_count_truncated will be set to true, signaling that user_count may not be accurate. This enables creating notifications like "100+ people commented on your post". The activity_count field is always accurate, even if the group has more activities than the limit.
Example API response:
{
aggregated_activities: [
{
activity_count: 1,
user_count: 1,
user_count_truncated: false,
group: "activity123-comment-2025-08-04",
activities: [
{
type: "comment",
user: {
id: "eric",
name: "Eric",
// other User fields
},
notification_context: {
trigger: {
text: "Eric commented on your activity",
type: "comment",
},
target: {
user_id: "jane",
type: "post",
text: "As earnestly shameless elsewhere defective estimable fulfilled of",
id: "a0668408-0eb9-4906-a1cf-be79f988051d",
attachments: [
{
type: "image",
image_url: "https://...",
},
],
},
},
// Other activity fields
},
],
},
{
activity_count: 1,
user_count: 1,
group: "activity123-reaction-2025-08-04",
activities: [
{
type: "reaction",
user: {
id: "eric",
name: "Eric",
},
notification_context: {
target: {
id: "8966090a-30bf-4fe2-b8bc-b0fe36200e56",
user_id: "jane",
type: "post",
text: "Ask too matter formed county wicket oppose talent",
},
trigger: {
type: "reaction",
text: "Eric reacted to your activity",
},
},
},
],
},
{
activity_count: 1,
user_count: 1,
group: "jane-follow-2025-08-04",
activities: [
{
type: "follow",
user: {
id: "eric",
name: "Eric",
},
notification_context: {
target: {
id: "jane",
name: "Jane",
},
trigger: {
type: "follow",
text: "Eric started following you",
},
},
},
],
},
{
activity_count: 1,
user_count: 1,
group: "comment456-comment_reply-2025-08-04",
activities: [
{
type: "comment_reply",
user: {
id: "charlie",
name: "Charlie"
},
notification_context: {
target: {
id: "8966090a-30bf-4fe2-b8bc-b0fe36200e56",
user_id: "alice",
type: "post",
text: "Ask too matter formed county wicket oppose talent",
comment: {
id: "comment456",
user_id: "bob",
comment: "Great post! I totally agree with this."
}
},
trigger: {
type: "comment_reply",
text: "Charlie replied to your comment"
}
}
}
]
},
];
}Push Notifications
For information on configuring push notifications, see Feed Group Push Configuration.
Notification status
If notification tracking is turned on for the feed group then you'll receive notification status when reading the feed. Notification status tells
- How many unread notifications does the feed have?
- Which notifications are read?
- How many unseen notifications does the feed have?
- Which notifications are seen?
Unread/unseen count is computed from the last 1000 activities of the feed, and aggregated into maximum 100 groups. This means that unread/unseen count will never be more than 100.
For example, take the notification system on Facebook. If you click the notification icon, all notifications get marked as seen. However, an individual notification only gets marked as read when you click on it.
Here is an example payload for notificaiton status:
{
notification_status: {
// Number of unread notifications
unread: 12,
// Number of unseen notifications
unseen: 0,
last_seen_at: // Date object with last seen timestamp,
seen_activities: [],
last_read_at: // Date object with last read timestamp,
read_activities: ['activity123-reaction-2025-08-04'],
}
}
// Check if a group is read/seen
const isRead = (lastReadAt && group.updated_at.getTime() < lastReadAt.getTime()) || readActivities.includes(group.group);
const isSeen = (lastSeenAt && group.updated_at.getTime() < lastSeenAt.getTime()) || seenActivities.includes(group.group);{
notification_status: {
// Number of unread notifications
unread: 12,
// Number of unseen notifications
unseen: 0,
last_seen_at: // Date object with last seen timestamp,
seen_activities: [],
last_read_at: // Date object with last read timestamp,
read_activities: ['activity123-reaction-2025-08-04'],
}
}
const {
unread,
unseen,
last_read_at,
last_seen_at,
read_activities,
seen_activities,
} = useNotificationStatus(feed) ?? {};
const isRead = useIsAggregatedActivityRead({ feed, aggregatedActivity });
const isSeen = useIsAggregatedActivitySeen({ feed, aggregatedActivity });{
notification_status: {
// Number of unread notifications
unread: 12,
// Number of unseen notifications
unseen: 0,
last_seen_at: // Date object with last seen timestamp,
seen_activities: [],
last_read_at: // Date object with last read timestamp,
read_activities: ['activity123-reaction-2025-08-04'],
}
}
const {
unread,
unseen,
last_read_at,
last_seen_at,
read_activities,
seen_activities,
} = useNotificationStatus(feed) ?? {};
const isRead = useIsAggregatedActivityRead({ feed, aggregatedActivity });
const isSeen = useIsAggregatedActivitySeen({ feed, aggregatedActivity });{
notification_status: {
// Number of unread notifications
unread: 12,
// Number of unseen notifications
unseen: 0,
last_seen_at: // Date object with last seen timestamp,,
seen_activities: [],
last_read_at: // Date object with last read timestamp,,
read_activities: ['activity-reaction-2025-08-04'],
}
}
// Check if a group is read/seen
const isRead = (lastReadAt && group.updated_at.getTime() < lastReadAt.getTime()) || readActivities.includes(group.group);
const isSeen = (lastSeenAt && group.updated_at.getTime() < lastSeenAt.getTime()) || seenActivities.includes(group.group);{
NotificationStatus: {
// Number of unread notifications
Unread: 12,
// Number of unseen notifications
Unseen: 0,
LastReadAt: // Timestamp object with last seen timestamp,,
SeenActivities: [],
LastSeenAt: // Timestamp object with last read timestamp,,
ReadActivities: ['activity123-reaction-2025-08-04'],
}
}
import (
// Other imports...
"slices"
)
// Check if a group is read/seen
group := response.Data.AggregatedActivities[0]
lastSeenAt := response.Data.NotificationStatus.LastSeenAt
seenActivities := response.Data.NotificationStatus.SeenActivities
lastReadAt := response.Data.NotificationStatus.LastReadAt
readActivities := response.Data.NotificationStatus.ReadActivities
isRead := (lastReadAt != nil && lastReadAt.Time != nil && group.UpdatedAt.Time != nil && group.UpdatedAt.Time.Before(*lastReadAt.Time)) || slices.Contains(readActivities, group.Group)
isSeen := (lastSeenAt != nil && lastSeenAt.Time != nil && group.UpdatedAt.Time != nil && group.UpdatedAt.Time.Before(*lastSeenAt.Time)) || slices.Contains(seenActivities, group.Group)use GetStream\GeneratedModels;
{
"notificationStatus": {
// Number of unread notifications
"unread": 12,
// Number of unseen notifications
"unseen": 0,
"lastSeenAt": // DateTime object with last seen timestamp,
"seenActivities": [],
"lastReadAt": // DateTime object with last read timestamp,
"readActivities": ["activity123-reaction-2025-08-04"],
}
}
// Check if a group is read/seen
$group = $response->getData()->aggregatedActivities[0];
$lastSeenAt = $response->getData()->notificationStatus->lastSeenAt;
$seenActivities = $response->getData()->notificationStatus->seenActivities;
$lastReadAt = $response->getData()->notificationStatus->lastReadAt;
$readActivities = $response->getData()->notificationStatus->readActivities;
$isRead = ($lastReadAt && $group->updatedAt->getTimestamp() * 1e+9 < $lastReadAt->getTimestamp() * 1e+9) || ($readActivities && in_array($group->group, $readActivities));
$isSeen = ($lastSeenAt && $group->updatedAt->getTimestamp() * 1e+9 < $lastSeenAt->getTimestamp() * 1e+9) || ($seenActivities && in_array($group->group, $seenActivities));Marking notifications as seen
notificationFeed.markActivity(
request = MarkActivityRequest(
// Mark all notifications as seen...
markAllSeen = true,
// ...or only selected ones
markSeen = listOf(
/* group names to mark as seen */
)
)
)await notificationFeed.markActivity({
// Mark all notifications as seen...
mark_all_seen: true,
// ...or only selected ones
mark_seen: [
/* group names to mark as seen */
],
});await notificationFeed.markActivity({
// Mark all notifications as seen...
mark_all_seen: true,
// ...or only selected ones
mark_seen: [
/* group names to mark as seen */
],
});await notificationFeed.markActivity({
// Mark all notifications as seen...
mark_all_seen: true,
// ...or only selected ones
mark_seen: [
/* group names to mark as seen */
],
});await notificationFeed.markActivity(
request: const MarkActivityRequest(
// Mark all notifications as seen...
markAllSeen: true,
// ...or only selected ones
markSeen: [
/* group names to mark as seen */
],
),
);await notificationFeed.markActivity({
// Mark all notifications as seen...
mark_all_seen: true,
// ...or only selected ones
mark_seen: [
/* group names to mark as seen */
],
user_id: "<user id>",
});notificationFeed := client.Feeds().Feed("notification", "john")
_, err = notificationFeed.MarkActivity(context.Background(), &getstream.MarkActivityRequest{
// Mark all notifications as seen...
MarkAllSeen: getstream.PtrTo(true),
// ...or only selected ones
MarkSeen: []string{
// group names to mark as seen
},
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error:", err)
}use GetStream\GeneratedModels;
$notificationFeed = $feedsClient->feed("notification", "john");
$notificationFeed->markActivity(new GeneratedModels\MarkActivityRequest(
// Mark all notifications as seen...
markAllSeen: true,
// ...or only selected ones
markSeen: [
// group names to mark as seen
],
userID: "john"
));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 */
)
)
)await notificationFeed.markActivity({
// Mark all notifications as read...
mark_all_read: true,
// ...or only selected ones
mark_read: [
/* group names to mark as read */
],
});await notificationFeed.markActivity({
// Mark all notifications as read...
mark_all_read: true,
// ...or only selected ones
mark_read: [
/* group names to mark as read */
],
});await notificationFeed.markActivity({
// Mark all notifications as read...
mark_all_read: true,
// ...or only selected ones
mark_read: [
/* group names to mark as read */
],
});await notificationFeed.markActivity(
request: const MarkActivityRequest(
// Mark all notifications as read...
markAllRead: true,
// ...or only selected ones
markRead: [
// group names to mark as read
],
),
);await notificationFeed.markActivity({
// Mark all notifications as read...
mark_all_read: true,
// ...or only selected ones
mark_read: [
/* group names to mark as read */
],
user_id: "<user id>",
});notificationFeed := client.Feeds().Feed("notification", "john")
_, err = notificationFeed.MarkActivity(context.Background(), &getstream.MarkActivityRequest{
// Mark all notifications as read...
MarkAllRead: getstream.PtrTo(true),
// ...or only selected ones
MarkRead: []string{
// group names to mark as read
},
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error:", err)
}use GetStream\GeneratedModels\MarkActivityRequest;
// Create notification feed
$notificationFeed = $feedsClient->feed("notification", "john");
// Mark all notifications as read
$markRequest = new MarkActivityRequest(
markAllRead: true,
userID: "john"
);
$response = $notificationFeed->markActivity($markRequest);
// Or mark only selected notifications as read
$markSelectedRequest = new MarkActivityRequest(
markRead: [
// group names to mark as read
],
userID: "john"
);
$response = $notificationFeed->markActivity($markSelectedRequest);Pagination
Pagination for notification (aggregated) feeds work the same way as it works for any other feed:
let feed = client.feed(
for: .init(
group: "user",
id: "john",
activityLimit: 10
)
)
// Page 1
try await feed.getOrCreate()
let activities = feed.state.activities // First 10 activities
// Page 2
let page2Activities = try await feed.queryMoreActivities(limit: 10)
let page1And2Activities = feed.state.activitiesval feed = client.feed(
query = FeedQuery(
group = "user",
id = "john",
activityLimit = 10
)
)
// Page 1
feed.getOrCreate()
val activities = feed.state.activities // First 10 activities
// Page 2
val page2Activities: Result<List<ActivityData>> = feed.queryMoreActivities(limit = 10)
val page1And2Activities = feed.state.activitiesconst feed = client.feed("user", "jack");
// First page
await feed.getOrCreate({
limit: 10,
});
// Second page
await feed.getNextPage();
console.log(feed.state.getLatestValue().is_loading_activities);
// Truthy if feed has next page
console.log(feed.state.getLatestValue().next);
console.log(feed.state.getLatestValue().activities);
// Only if feed group has aggregation turned on
console.log(feed.state.getLatestValue().aggregated_activities);const feed = client.feed("user", "jack");
// First page
await feed.getOrCreate({
limit: 10,
});
const { activities, loadNextPage, is_loading, has_next_page } =
useFeedActivities(feed) ?? {};
// Only if feed group has aggregation turned on
const { aggregated_activities, is_loading, has_next_page } =
useAggregatedActivities(feed) ?? {};const feed = client.feed("user", "jack");
// First page
await feed.getOrCreate({
limit: 10,
});
const { activities, loadNextPage, is_loading, has_next_page } =
useFeedActivities(feed) ?? {};
// Only if feed group has aggregation turned on
const { aggregated_activities, is_loading, has_next_page } =
useAggregatedActivities(feed) ?? {};final feed = client.feedFromQuery(
const FeedQuery(
fid: FeedId(group: 'user', id: 'john'),
activityLimit: 10,
),
);
// Page 1
await feed.getOrCreate();
final activities = feed.state.activities; // First 10 activities
// Page 2
final page2Activities = await feed.queryMoreActivities(limit: 10);
final page1And2Activities = feed.state.activities;const feed = client.feeds.feed("user", "jack");
const firstPage = await feed.getOrCreate({
limit: 10,
user_id: "user_id",
});
const nextPage = await feed.getOrCreate({
next: firstPage.next,
limit: 10,
user_id: "user_id",
});feed := client.Feeds().Feed("user", "john")
// First page
firstPage, err := feed.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
Limit: getstream.PtrTo(10),
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error getting first page:", err)
}
// Second page request using next cursor
nextPage, err := feed.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
Next: firstPage.Data.Next,
Limit: getstream.PtrTo(10),
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error getting next page:", err)
}
log.Printf("First page activities count: %d", len(firstPage.Data.Activities))
log.Printf("Next page activities count: %d", len(nextPage.Data.Activities))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();$feed = $feedsClient->feed('user', 'jack');
$feedResponse1 = $feed->getOrCreateFeed(
new GeneratedModels\GetOrCreateFeedRequest(userID: "jack", limit: 10)
);
$feedResponse2 = $feed->getOrCreateFeed(
new GeneratedModels\GetOrCreateFeedRequest(userID: "jack", limit: 10, next: $feedResponse1->getData()->next)
);var feedResponse1 = await _feedsV3Client.GetOrCreateFeedAsync(
FeedGroupID: "user",
FeedID: _testFeedId,
request: new GetOrCreateFeedRequest { UserID = _testUserId }
);
var feedResponse2 = await _feedsV3Client.GetOrCreateFeedAsync(
FeedGroupID: "user",
FeedID: _testFeedId2,
request: new GetOrCreateFeedRequest { UserID = _testUserId2 }
);feed_response_1 = self.test_feed.get_or_create(user_id=self.test_user_id)
feed_response_2 = self.test_feed_2.get_or_create(
user_id=self.test_user_id_2
)feed = client.feed('user', 'jack')
# First page
first_page = feed.get_or_create_feed(
GetStream::Generated::Models::GetOrCreateFeedRequest.new(
user_id: 'jack',
limit: 10
)
)
# Second page using next cursor from first page
if first_page.next
second_page = feed.get_or_create_feed(
GetStream::Generated::Models::GetOrCreateFeedRequest.new(
user_id: 'jack',
limit: 10,
next: first_page.next
)
)
end