{% if verb == 'follow' %}
{{ actor }}_{{ verb }}_{{ time.strftime("%Y-%m-%d") }}
{% else %}
{{ verb }}_{{ time.strftime("%Y-%m-%d") }}
{% endif %}
Feed Group Types
Flat Feeds
Flat is the default feed type - and the only feed type that you can follow and apply a custom ranking. It’s not possible to follow either aggregated or notification feeds.
Create new feed groups based on the flat type in the dashboard.
Options
Name | Description | Default |
---|---|---|
Realtime Notifications | Enable realtime notifications | True |
Aggregated Feeds
Aggregated feeds are helpful if you want to group activities. Here are some examples of what you can achieve using aggregated feeds:
‘Eric followed 10 people’
‘Julie and 14 others liked your photo’
You can create new aggregated feed groups in the dashboard.
Options
There are several options you can configure for aggregated feeds. The most important setting is the aggregation format. This format determines how activities are grouped together.
Name | Description | Type |
---|---|---|
Realtime Notifications | Enable realtime notifications | true |
Aggregation Format | The aggregation format to use. This is used as a key to group activities by. | {{ verb }}_{{ time.strftime(“%Y-%m-%d”) }} |
How Aggregated Feeds Work
When you insert an activity to an aggregated feed we apply the aggregation format. The aggregation format + the activity’s data lead to a value for the “group”. This group is used to combine the activities.
The aggregation format is applied at write time. Changing the aggregation format only affects activities inserted after the change. The dashboard allows you to preview changes on your existing data though.
Aggregation Format Syntax
The following variables are available:
verb
the activity verb as it is sent to the APIs (e.g. "like")time
the activity creation date and time (or the value sent to APIs)object
the activity object as it is sent to the APIs (e.g. Item:13)actor
the activity actor (e.g. User:9)feed.group
the feed group name (e.g. if the feed is "notification:123", feed.group is notification)feed.user_id
the feed user id (e.g. if the feed is "notification:123", feed.user_id is 123))id
the internal unique activity id. This will be unique so if you use this nothing will be aggregated. Use this when you don't want aggregation, but only the mark_read/mark_seen functionality.
In addition, you can use any of the custom values you’ve provided when adding the activity.
Here are some common examples of aggregation formats:
Per actor, verb id and day:
{{ actor }}_{{ verb }}_{{ time.strftime("%Y-%m-%d") }}
Per activity verb and day:
{{ verb }}_{{ time.strftime("%Y-%m-%d") }}
Follows by actor, everything else grouped by verb and day
The aggregation rule uses the Jinja2 Template Syntax. Control structures like if
and else
are available, as well as these filters: int
, lower
and strftime
to format the time
variable. The options for strftime
are documented here. Please get in touch with support if you need help with your aggregation formula.
Each activity group inside an aggregated feed contains the 15 most recent activities. If you add more than 15 activities to one group, older activities will no longer be visible. Enterprise customers can contact support to increase this limit.
Data Format
The data format in which Aggregated Feeds are returned differs from regular Flat Feeds.
At the top level of the JSON response, the ‘results’ field contains an array of Activity Groups, plus additional metadata about the feed. Within the results array, each Activity Group contains a count of Activities and unique ‘actors’ contained within the group.
Notification Feeds
Notification Feed Groups extend the “Aggregated Feed Group” concept with additional features that make them well suited to notification systems:
Notification Feeds contain Activity Groups, each with a
seen
andread
status field. These fields can be updated to reflect how a user has interacted with a given notification.When retrieved, the Feed includes a real-time count of the total number of unseen and unread Activity Groups (notifications).
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.
You can create new Notification Feed Groups in the dashboard.
Options
There are several options to configure:
Name | Description | Type |
---|---|---|
Realtime Notifications | Enable realtime notifications | True |
Aggregation Format | The aggregation format to use. The default {{ verb.id }}_{{ time.strftime(“%Y-%m-%d”) }} (verbs grouped by day) or {{ id }} (to achieve a single activity per group) are most commonly used. | {{ verb }}_{{ time.strftime(“%Y-%m-%d”) }} |
Data Format
Similar to Aggregated Feeds, the data format in which Notification Feeds are retrieved differs from regular Flat Feeds.
At the top level of the JSON response the results
field contains an array of Activity Groups, along with overall unseen
and unread
counts and other metadata about the feed. Within the results array, each Activity Group contains the additional status fields that indicate the group is seen/read.
When reading the feed, set the mark_read
and mark_seen
parameter. The next time the feed is read, the seen and/or read status will be updated accordingly. Please keep in mind that the first call will always return the read
and seen
state prior to the change. This allows you to read a notification feed, mark activities as read or seen and display them according to the current state in a single API request.
name | type | description | default | optional |
---|---|---|---|---|
mark_read | array | Comma-separated list of activity group ids to mark as read, or True which means all | - | ✓ |
mark_seen | array | Comma-separated list of activity group ids to mark as seen, or True which means all | - | ✓ |
If passing IDs to mark_seen
or mark_read
, be sure to pass the ID of the activity group as returned by the API, not the IDs of individual activities.
Here’s an example:
// Mark all activities in the feed as seen
var result = await notificationFeed.GetActivitiesAsync(0, 5, null, ActivityMarker.Mark().AllSeen());
// Mark some activities as read via specific Activity Group Ids
// Mark all activities in the feed as seen
notificationFeed.get({mark_seen:true})
.then(function(data) { /* on success */ })
.catch(function(reason) { /* on failure */ });
// Mark some activities as read via specific Activity Group Ids
notificationFeed.get({mark_read: ['activityGroupIdOne', 'activityGroupIdTwo']})
.then(function(data) { /* on success */ })
.catch(function(reason) { /* on failure */ });
# Mark all activities in the feed as seen
results = notification_feed.get(mark_seen=True)['results']
# Mark some activities as read via specific Activity Group Ids
notification_feed.get(mark_read=[results[0]['id'], results[1]['id']])
# Mark all activities in the feed as seen
result = notification_feed.get(:limit=>5, :offset=>;0, :mark_seen=>;true)
# Mark some activities as read via specific Activity Group Ids
result = notification_feed.get(:limit=>5, :mark_read=>['activity_group_id_1', 'activity_group_id_2'])
# Mark all activities in the feed as seen
$options = ['mark_seen' => true];
$results = $notificationFeed->getActivities(0, 10, $options);
# Mark some activities as read via specific Activity Group Ids
$options = ['mark_read' => ['activity_group_id_1', 'activity_group_id_2']];
$results = $notificationFeed->getActivities(0, 10, $options);
NotificationFeed notifications = client.notificationFeed("notifications", "1");
// Mark all activities in the feed as seen
List<notificationgroup<activity>> activityGroups = notifications.getActivities(new Limit(5), new ActivityMarker().allSeen()).get();
for (NotificationGroup<activity> group : activityGroups) {
// ...
}
// Mark some activities as read via specific Activity Group Ids
activityGroups = notifications.getActivities(new Limit(5), new ActivityMarker().read("groupID1", "groupID2" /* ... */)).get();</activity></notificationgroup<activity>
notifications, err := client.NotificationFeed("notification", "1")
if err != nil {
panic(err)
}
// Mark all activities in the feed as seen
resp, err := notifications.GetActivities(context.TODO(), stream.WithNotificationsMarkSeen(true))
if err != nil {
panic(err)
}
for _, activity := range resp.Results {
fmt.Println(activity)
// ...
}
// Mark some activities as read via specific Activity Group Ids
resp, err = notifications.GetActivities(context.TODO(), stream.WithNotificationsMarkRead(
false, // don't mark all
"groupUUID1", "groupUUID2", //...
))
if err != nil {
panic(err)
}
for _, activity := range resp.Results {
fmt.Println(activity)
// ...
}
// Mark all activities in the feed as seen:
notificationFeed.get(markOption: .seenAll) { result in /* ... */ }
// Mark some activities as read via specific Activity Group Ids:
notificationFeed.get(markOption: .read(["activityGroupIdOne", "activityGroupIdTwo"]) { result in /* ... */ }
You’ll often want to listen to feed changes in real-time. This is explained in the section on real-time updates.
Each activity group inside a notification feed contains the 15 most recent activities. If you add more than 15 activities to one group, older activities will no longer be visible. Enterprise customers can contact support to increase this limit.