# pip install stream-python
import stream
client = stream.connect('{{ api_key }}', '{{ api_secret }}', location='us-east')
# add an activity to Scott's notification feed
notification_feed_scott = client.feed('notification', 'scott')
activity_data = {'actor': 'Josh', 'verb': 'follow', 'object': 'Scott', 'time': '2018-05-04T20:24:03.042927'}
activity_response = notification_feed_scott.add_activity(activity_data)
Notification System
This tutorial explains how easy it is to build a notification feed with Stream. We also have libraries for React, React Native, and iOS, all of which make implementing notification feeds a breeze.
Step 1: Initialize Your Notification System
To start, we’ll describe how to notify Scott that his colleague Josh started following him. The code shows you how to connect to Stream and add an activity with the verb “follow”.
You can find your API Key and API Secret in the dashboard.
// node install getstream
const stream = require("getstream");
const client = stream.connect(
"753adfaa3x87",
"xwrybggzyk4um6v8c5ep79r7hqce5twj9j6pjj99584c7b2r36eqjejcp4h8te9y",
(location = "us-east"),
);
// add an activity to Scott's notification feed
const scott = client.feed("notification", "scott");
const activityData = {
actor: "Josh",
verb: "follow",
object: "Scott",
time: "2018-05-04T20:24:03.042927",
};
const activityResponse = scott.addActivity(activityData);
Step 2: Reading The Notification Feed
Now, read Scott’s notification feed to see how it looks:
# Read Scott's notification feed
scott = client.feed('notification', 'scott')
notifications = scott.get(limit=10)
print(notifications)
// Read Scott's notification feed
scott = client.feed("notification", "scott");
notifications = scott.get({ limit: 10 });
console.log(notifications);
{
"duration": "7.22ms",
"next": "",
"results": [
{
"activities": [
{
"actor": "Josh",
"foreign_id": "",
"id": "6ce847e8-4fd7-11e8-9750-121fdba36dae",
"object": "Scott",
"origin": null,
"target": "",
"time": "2018-05-04T20:24:03.042927",
"verb": "follow"
}
],
"activity_count": 1,
"actor_count": 1,
"created_at": "2018-05-04T20:24:03.042927",
"group": "follow_2018-05-04",
"id": "6cea1419-4fd7-11e8-8080-8001511b5cbe.follow_2018-05-04",
"is_read": false,
"is_seen": false,
"updated_at": "2018-05-04T20:24:03.042927",
"verb": "follow"
}
],
"unread": 1,
"unseen": 1
}
Now, bring your attention to the following details within the response: the notification counts, and the group. You will see the notification counts in the response: 'unread': 1
and 'unseen': 1
. Many notification systems will differentiate between a notification that has been seen as opposed to a notification that has been marked read. The design below highlights the common features of a notification feed:
Notice that each notification contains a list of activities. The activities are grouped together based on the rule set and defined within your Stream dashboard.
The group name of follow_2018-05-04 currently contains 1 activity.
By default, aggregation groups are based on the activity’s verb and time. For example, if multiple people follow you on the same day, there will only be 1 notification. This allows you to show a notification such as: “Josh and 3 others followed you”. Aggregation helps reduce noise within the notification feed, which is especially important when there’s an abundance of user engagement. You can configure or disable the exact rules for how activities are grouped together in the dashboard.
Step 3: Realtime Notification System
Stream includes support for listening to changes to your notification feed in real time. You can listen to changes using Websockets, SQS or webhooks. The example below shows how to use websockets to update the feed in real time.
The first step is to generate a token for authorizing the client-side connection for reading the feed.
token = client.feed('notification', 'scott').get_readonly_token()
print(token)
const token = serverClient.feed("notification", "scott").createUserToken();
console.log(token);
Next, use the token to connect to Stream’s websocket infrastructure. Create a file called test.html
and paste the following code (remember to use the token you generated above):
<html>
<script src="https://cdn.jsdelivr.net/npm/getstream/dist/js_min/getstream.js"></script>
<script type="text/javascript">
const token = "YOUR-TOKEN-HERE";
const client = stream.connect("{{ api_key }}", null, "{{ app_id }}");
const notificationScott = client.feed("notification", "scott", token);
function callback(data) {
alert("A new activity: " + JSON.stringify(data));
}
function successCallback() {
alert(
"Now listening to changes in realtime. Add an activity to see how realtime works.",
);
}
function failCallback(data) {
alert("Something went wrong, check the console logs");
console.log(data);
}
notificationScott.subscribe(callback).then(successCallback, failCallback);
</script>
</html>
Step 4: Follow Relationships
At this point, you should have a good understanding of how to add content directly to a user’s notification feed. However, there are many use cases for which you may want to notify a group of users. Some examples include:
Site-wide announcements to all users.
New lectures or homework assignments for a class of students.
Tickets going on sale for your favorite artist.
A new event for the group/meetup you follow.
For these types of use cases we recommend creating follow relationships. Let’s use the meetup scenario as an example. The code below demonstrates how to follow the Golang meetup. It also shows how to create a new event activity for the meetup. Now, you’ve probably noticed the “meetup” feed group isn’t configured at this point. To do so, head over to the dashboard and configure a flat feed group called “meetup”.
client.feed('notification', 'scott').follow('meetup', 'golang')
# Scott will now receive notifications about new activities added to the golang meetup feed
activity_data = {'actor': 'Jimmy', 'verb': 'add', 'object': 'event:123', 'event': {'name': 'golang package manager changes', 'location': 'Boulder'}, 'time': '2018-05-04T20:24:03.042927'}
activity_response = client.feed('meetup', 'golang').add_activity(activity_data)
client.feed("notification", "scott").follow("meetup", "golang");
// Scott will now receive notifications about new activities added to the golang meetup feed
const activityData = {
actor: "Jimmy",
verb: "add",
object: "event:123",
event: { name: "golang package manager changes", location: "Boulder" },
time: "2018-05-04T20:24:03.042927",
};
const activityResponse = client
.feed("meetup", "golang")
.addActivity(activityData);
Step 5: Read The Feed Again
To see what has changed, take a look at the feed. You’ll notice the event announcement is now present in Scott’s feed. In addition, the activities were not grouped together. The event announcement is in group ‘add_2018-05-04’ and the follow notification is in group ‘follow_2018-05-04’. The follow relationship is very convenient for when many people need to be notified.
# Read Scott's notification feed and mark the notifications as seen
notifications = client.feed('notification', 'scott').get(limit=10, mark_seen=True)
print(notifications)
// Read Scott's notification feed and mark the notifications as seen
const notifications = client
.feed("notification", "scott")
.get({ limit: 10, mark_seen: true });
console.log(notifications);
{
"duration": "9.98ms",
"next": "",
"results": [
{
"activities": [
{
"actor": "Jimmy",
"event": {
"date": "3rd of March 2025",
"name": "golang package manager changes"
},
"foreign_id": "",
"id": "16008049-4fd9-11e8-9959-121fdba36dae",
"object": "event:123",
"origin": "meetup:golang",
"target": "",
"time": "2018-05-04T20:24:03.042927",
"verb": "add"
}
],
"activity_count": 1,
"actor_count": 1,
"created_at": "2018-05-04T20:24:03.042927",
"group": "add_2018-05-04",
"id": "16014de8-4fd9-11e8-8080-800162bf0445.add_2018-05-04",
"is_read": false,
"is_seen": true,
"updated_at": "2018-05-04T20:24:03.042927",
"verb": "add"
},
{
"activities": [
{
"actor": "Josh",
"foreign_id": "",
"id": "6ce847e8-4fd7-11e8-9750-121fdba36dae",
"object": "Scott",
"origin": null,
"target": "",
"time": "2018-05-04T20:24:03.042927",
"verb": "follow"
}
],
"activity_count": 1,
"actor_count": 1,
"created_at": "2018-05-04T20:24:03.042927",
"group": "follow_2018-05-04",
"id": "6cea1419-4fd7-11e8-8080-8001511b5cbe.follow_2018-05-04",
"is_read": false,
"is_seen": true,
"updated_at": "2018-05-04T20:24:03.042927",
"verb": "follow"
}
],
"unread": 2,
"unseen": 2
}
Step 6: Marking Notifications As Seen
Did you notice how the request above marked the notification as seen? Note how reading the feed and marking the items as seen is combined in 1 API call. This is convenient since most notification feeds mark items as seen the same moment you open the feed.
When you read the feed again, you’ll see the notifications changed to seen
.You can also mark notifications as read
. This is typically done when a user clicks on a notification. The example below shows this process in action:
# Mark an activity as read
notifications = client.feed('notification', 'scott').get(mark_read=["insert-your-notification-id-here"])
# The notification id looks like this: 16014de8-4fd9-11e8-8080-800162bf0445.add_2018-05-04
// Mark an activity as read
const notifications = client
.feed("notification", "scott")
.get({ mark_read: ["insert-your-notification-id-here"] });
// The notification id looks like this: 16014de8-4fd9-11e8-8080-800162bf0445.add_2018-05-04
{
"duration": "12.10ms",
"next": "",
"results": [
{
"activities": [
{
"actor": "Jimmy",
"event": {
"date": "3rd of March 2025",
"name": "golang package manager changes"
},
"foreign_id": "",
"id": "16008049-4fd9-11e8-9959-121fdba36dae",
"object": "event:123",
"origin": "meetup:golang",
"target": "",
"time": "2018-05-04T20:24:03.042927",
"verb": "add"
}
],
"activity_count": 1,
"actor_count": 1,
"created_at": "2018-05-04T20:24:03.042927",
"group": "add_2018-05-04",
"id": "16014de8-4fd9-11e8-8080-800162bf0445.add_2018-05-04",
"is_read": false,
"is_seen": true,
"updated_at": "2018-05-04T20:24:03.042927",
"verb": "add"
},
{
"activities": [
{
"actor": "Josh",
"foreign_id": "",
"id": "6ce847e8-4fd7-11e8-9750-121fdba36dae",
"object": "Scott",
"origin": null,
"target": "",
"time": "2018-05-04T20:24:03.042927",
"verb": "follow"
}
],
"activity_count": 1,
"actor_count": 1,
"created_at": "2018-05-04T20:24:03.042927",
"group": "follow_2018-05-04",
"id": "6cea1419-4fd7-11e8-8080-8001511b5cbe.follow_2018-05-04",
"is_read": false,
"is_seen": true,
"updated_at": "2018-05-04T20:24:03.042927",
"verb": "follow"
}
],
"unread": 2,
"unseen": 0
}
Concluding The Notification System Tutorial
We hope you enjoyed this tutorial for building notification systems. If you have any questions please contact us.