In this tutorial we are going to show how easy it is to build a notification feed using GetStream.io. First of all, let's quickly introduce you to our fictional example app. It's called bug-your-friends.com and allows you interact with your friends, ping them, follow them or poke them. Here's a quick list of example interactions:
- poke another user (eg. Thierry pokes Alessandra)
- follow a user (eg. Tommaso follows Iris)
- ping a user (eg. Josie pings Carolina)
Whenever a user is part of one of these interactions, we want to update his notification feed, update the number of unseen and unread notifications and listen to changes in realtime. We also want to present these interactions in an aggregated fashion, so that common events are grouped together (eg. Thierry poked you 100 times, Tommaso, Josie and 3 other people pinged you ...).
The unread notifications
The notification feed box
GetStream.io helps you build scalable newsfeeds and notification feeds. It's a REST API with clients in PHP, JS, Ruby and Python. To start, quickly signup using Github to get your API keys (in the dashboard), this is completely free and takes 3 clicks. Once you have an account, you need to install the client (in this tutorial we are going to use Python).
pip install stream-python
The first step in building our annoying app is to actually send events to users' notification feeds. Here's how you send a ping event.
import stream
client = stream.connect('api_key', 'api_secret')
def notify_ping(user, ping, ping_target):
activity = {'actor': user.username, 'verb': 'ping', 'object': ping.id}
feed = client.feed('notification', ping_target.id)
feed.add_activity(activity)
In the example above, we first create an instance of the api client (using the api key and secret from the dashboard), then we compose the ping event as an activity (actor, verb, object) and last we send that data to the notification feed of the pinged user. Note that you can also add custom fields to the activity. By default the activities are aggregated by verb and time. Later on we'll explain how to change this.
Reading a notification feed is even easier.
feed = client.feed('notification', current_user.id)
activities = feed.get()['results']
activities is a python dictionary containing the following information: * the list of activities present in the feed * the count of activities that are yet to be marked as seen * the count of activities that are yet to be marked as read
Every notification feed keeps count of the notifications that are yet to be marked as read and seen. Stream's API allows you to mark the entire feed as read or seen as well as marking single activities as such.
feed = client.feed('notification', current_user.id)
# marks the entire feed as seen
feed.get(seen=True)
# marks the entire feed as read
feed.get(read=True)
# marks one activity as seen and read
activity_id = activity['id']
feed.get(read=[activity_id], seen=[activity_id])
As we introduced briefly in the beginning, activities sent to feeds get aggregated into groups. Let's expand a bit on this.
Stream's notifications feeds use user defined aggregation rules. Whenever an activity is added to a feed, a group id will be assigned as the result of the aggregated function. The default aggregation rule groups activities by verb and creation date. Stream allows you to use different and even more complex aggregation rules based on the activity data. You can read more about this in aggregation docs.
Realtime notifications are a great addition to a notification feed. It is possible to subscribe to feed updates using the javascript client (available on npm and github). This is how you can get notification updates. Whenever something is added to the current user's feed, the updateNotificationCallback function will be fired.
<script src="path/to/stream.js" />
<script>
require 'stream'
client = stream.connect('api_secret', null, '733');
notification = client.feed('notification', '{{ current_user.id }}', '{{ feed.token }}');
function updateNotificationCallback(data){
// new activities will be available in the data argument
}
notification.subscribe(function callback(data) {
updateNotificationCallback(data);
});
</script>
In this tutorial we showed you how to quickly build an aggregated notification feed and listen to changes in realtime. To keep this tutorial brief we only scratched the surface of the feature set that Stream offers. To have a better understanding I suggest you to try the 1 minute interactive demo (https://getstream.io/get_started/) and to have a look at the code examples (https://getstream.io/docs/).