Sending notifications to users
One of the things we often see nowadays are notifications. Think about your phone. How many times in the last 24 hours has it beeped because you received a message on a social network? Or how many times you’ve received an email that something is on sale.
Ever wondered how these are done? Well, wonder no more, and dive with me into designing a notification system!
Again, as is the case, let’s set the scope:
So, what does the above notification tell us?
Mobile notifications, also called iOS push notifications (or android push notifications) are those that you can see in your mobile when you receive a message. Each device handles them separately, but all are sent by a centralized store.
In the case of iOS, we need to set up a server allowing requests to Apple Push Notification service, or APN for short.
How it works is we basically have 3 parts:
Now, with this flow, in short, we basically:
The important thing that we need to store is a device token. It is an unique identifier of the device. This is also generated depending on device system
The push notifications on android are the same as on iOS. The only difference being who manages the messaging.
Rather than APNs, Firebase Cloud Messaging is often used as the provider.
With SMS, the flow is still the same as previously, only provider and device is different.
In here, we would again use a third party provider, e.g. Twilio. We also don’t require device token as phone number is our identifier.
Finally, emails are just as easy as SMS. The difference being provider (instead of SMS provider, we would use Mailchimp), and the identifier is email.
So, as we can see, the flow is basically:
So, what we need to do is gather the contacts. How would we do that?
Well, in the case of mobile apps, we could just create the tokens and send them to our web servers the moment our app is installed. However, with phones/emails, it’s more complicated.
Now, technologically, it’s easy to retrieve phones and emails. However, we need user to insert it themselves. Because of that, we’d most likely want to ask for these during sign up into application.
Keep in mind that in order to send the notifications to specific users, we want to keep a link to them. Imagine the following:
Both of these will have a different flow. For the first one, we don’t keep track of user ID, because there is none. We’d just send a reminder to a device that has no user ID.
However, in the latter, we want to send the info to specific user. But how would we know about it? Well, we need to link them!
So, in order to send the notifications properly, we need to store them:
So, in the high level design, we’d likely end up with the following design:
Now, that’s basically our basic system design! Now, let’s identify a couple flaws!
Finally, the flow will be like:
userId
, senderEmail
, title
, body
Now, we have a fairly robust system. We have multiple services connecting to a distributed service for managing notifications.
Furthermore, these services use message queues to allow for retry mechanism and managing high load.
So, what’s next? It sounds quite robust, right?
Well, there’s a bunch of things to consider. For example:
So, one thing we can add is a notification log. This log would basically write down every notification that was sent to APN/FCM/Mailchimp/Twilio (or any other provider). By logging all notifications, we’ll be able to tell exactly which notifications have been delivered.
To prevent overloading our server, we would add well known load balancers. Furthermore, we never touched authentication by service identifiers. We shoud also add that so not everyone can trigger the notifications. Finally, rate limiting will be our friend here as well.
As for notification settings, since user can opt out, we should keep in database if user wants to receive them or not. We can go event beyond and define types of notifications (such as those you see on LinkedIn settings).
We could also make a notification template ourselves so we have some prefilled content.
Finally, as is always required - monitoring and tracking.
And finally, monitoring. No system is finished until you have sufficient monitoring where you can easily identify what is going on, if you need to add servers, or if there is any other issue.
In this part, we’ve gone through a mind map of a notification system.