note: notifications are not persisted in the current implementation yet
- api: an http server that only serve requests and pushes requests in the processing queues
- assembler: a worker that assembles the notifications
- for personalized notification, it:
- fetches the appropriate user attributes and replace any placeholders in the template
- translates the content according to the user's current locale
- retrieves the appropriate target data according to the notification method
- for group notifications, it:
- retrieves the appropriate target data for each user in the group
- breaks down the request into batches to minimize payload size
- for personalized notification, it:
- dispatcher: a worker that integrates with third party services and routes the notifications accordingly, it is self rate limited by utilizing redis
Run docker-compose up -d
- /
sendSingleNotification
body:
{
"user_id": "1",
"method":"sms",
"content": "Hi %name%, you destination is near!",
"personalization_tags":["name"]
}
content
can contain tags surrounded by '%' reflecting fields in the personalization_tags
array to be interpolated later
- /
sendGroupNotification
body:
{
"group_id": "1",
"method":"push_notification",
"content": "Hello there!"
}
The service is minimal and doesn't need direct access to any of the data, only the needed personalization fields, user locale and groups
- User
- user_id
- name
- mobile_number (for sms)
- device_token (for push notifications service)
- locale (for language setting)
- Group
- group_id
- users_ids
Each worker service has a concurrency pool size that can be configured (current default is 1 assembler and 5 dispatchers). Each worker is stateless so they can be replicated on multiple containers through an orchestrator.
- Write unit tests for the common code and rate limiter
- Write a more dynamic adn generic rate limiter to be easily used with any external service
- Write a data persistance layer and expose read endpoints for notifications
- Generate Notification IDs from a distributed data store instead of using UUIDs
- Check against invalid requests (check for missing fields, invalid users..etc)