Email, SMS and Push Notifications Server
I recently came up with very convenient component – likeastore/notifier. Notifier is easy to setup Email, SMS and Push Notifications Server. It’s been open sourced few month, very specific to Likeastore needs, but due to great contributions it became very generic and can be used in your projects as well.
Once you need to setup infrastructure for notifications in your application, it will be really easy to do. It provides transport of Mandrill, Twilio, Android and iOS push notifications.
Starting up
The project already has comprehensive README that explains initial steps. At the moment, the server is available as github repository that you need to clone and prepare entry point for it. I’m thinking to pack the things into one npm
module. If you see it makes sense, please let me know.
To start, you need to clone the repo,
1
$ git clone https://github.com/likeastore/notifier.git
And then create app.js
file, there all setup of notifer
taking place.
1
2
3
4
5
6
var notifier = require('./source/notifier');
// TODO: configuration
// start the server
notifier.start(process.env.PORT || 7000);
Let’s go straight to configuration
part.
Events, Actions and Executors
The notifier
is HTTP server, that receives event
and turns that event into corresponding action
. One event could create as many actions as needed. Actions is something that later is going to be executed
.
The basic setup consits of 3 parts: receive event, resolve event and execute it.
1
2
3
4
notifier
.receive('incoming-event', function (event, actions, callback) { /* ... */ })
.resolve('created-action', function (action, actions, callback) { /* ... */ })
.execute('created-action', function (action, transport, callback) { /* ... */ });
Say, we have user-registered
event which we need to send a welcome email,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
notifier
.receive('user-registered', function (e, actions, callback) {
actions.create('send-welcome', {user: e.user}, callback);
})
.resolve('send-welcome', function (action, actions, callback) {
db.users.findOne({email: action.user}, function (err, user) {
if (err) {
return callback(err);
}
if (!user) {
return callback({message: 'user not found', email: action.email});
}
var data = {
email: action.user,
user: _.pick(user, userPick)
};
actions.resolved(action, data, callback);
});
})
.execute('send-welcome', function (action, transport, callback) {
var vars = [
{name: 'USERID', content: action.data.user._id},
{name: 'USER_NAME', content: action.data.user.displayName || action.data.user.name}
];
transport.mandrill('/messages/send-template', {
template_name: 'welcome-email',
template_content: [],
message: {
auto_html: null,
to: [{email: action.data.email}],
global_merge_vars: vars,
preserve_recipients: false
}
}, callback);
});
recieve
– receives event from outside and turns the event into corresponding action.
resolve
– step to extend action with additional data, email, name of user etc.
execute
– uses the transport to transmit the event
Transports
Mandrill provides support from emails notifications,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.execute('send-welcome', function (action, transport, callback) {
var vars = [
{name: 'USERID', content: action.data.user._id},
{name: 'USER_NAME', content: action.data.user.displayName || action.data.user.name}
];
transport.mandrill('/messages/send-template', {
template_name: 'welcome-email',
template_content: [],
message: {
auto_html: null,
to: [{email: action.data.email}],
global_merge_vars: vars,
preserve_recipients: false
}
}, callback);
});
Twilio is used for sms,
1
2
3
4
5
6
7
.execute('send-verify-sms', function (a, transport, callback) {
transport.twilio.messages.create({
to: a.data.phone,
from: '+12282201270',
body: 'Verification code: 1111',
}, callback);
});
For Android push notifications,
1
2
3
4
5
6
7
8
9
10
.execute('send-android-push-notification', function (a, transport, callback) {
var tokens = [];
tokens.push(a.data.token);
transport.android.push({
message: {key1: 'value1', key2: 'value2'},
tokens: tokens,
retries: 3
}, callback);
});
For Apple push notifications,
1
2
3
4
5
6
7
8
9
10
11
12
.execute('send-ios-push-notification', function (a, transport, callback) {
var tokens = [];
tokens.push(a.data.token);
transport.ios.push({
production: false, // use specific gateway based on 'production' property.
passphrase: 'secretPhrase',
alert: { "body" : "Your turn!", "action-loc-key" : "Play" , "launch-image" : "mysplash.png"},
badge: 1,
tokens: tokens
}, callback);
});
Configuration
Before the run, you need to make sure the notifier
is configured properly. Security tokens and connections strings to MongoDB. If you use Logentries, you can provide token and all logs will be submitted there.
The accessToken
is a shared secret between server and client, to prevent unauthorized access.
The config is using ENV variables on production and hardcoded values for development and staging.
Clients
notifier
can be used by any HTTP client, in most simple case curl
,
1
$ echo '{"event": "incoming-event"}' | curl -H "Content-Type:application/json" -d @- http://notifier.likeastore.com/api/events?access_token=ACCESS_TOKEN
We already have Node.js client DemocracyOS/notifier-client and plan to have browser client as well. But in essence it’s just HTTP post with event
payload and access_token
in query string, so basically it can be used from any language and platform.
I recently came up with very convenient component – likeastore/notifier. Notifier is easy to setup Email, SMS and Push Notifications Server. It’s been open sourced few month, very specific to Likeastore needs, but due to great contributions it became very generic and can be used in your projects as well.
Once you need to setup infrastructure for notifications in your application, it will be really easy to do. It provides transport of Mandrill, Twilio, Android and iOS push notifications.
Starting up
The project already has comprehensive README that explains initial steps. At the moment, the server is available as github repository that you need to clone and prepare entry point for it. I’m thinking to pack the things into one npm
module. If you see it makes sense, please let me know.
To start, you need to clone the repo,
1
|
|
And then create app.js
file, there all setup of notifer
taking place.
1 2 3 4 5 6 |
|
Let’s go straight to configuration
part.
Events, Actions and Executors
The notifier
is HTTP server, that receives event
and turns that event into corresponding action
. One event could create as many actions as needed. Actions is something that later is going to be executed
.
The basic setup consits of 3 parts: receive event, resolve event and execute it.
1 2 3 4 |
|
Say, we have user-registered
event which we need to send a welcome email,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
recieve
– receives event from outside and turns the event into corresponding action.resolve
– step to extend action with additional data, email, name of user etc.execute
– uses the transport to transmit the event
Transports
Mandrill provides support from emails notifications,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Twilio is used for sms,
1 2 3 4 5 6 7 |
|
For Android push notifications,
1 2 3 4 5 6 7 8 9 10 |
|
For Apple push notifications,
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Configuration
Before the run, you need to make sure the notifier
is configured properly. Security tokens and connections strings to MongoDB. If you use Logentries, you can provide token and all logs will be submitted there.
The accessToken
is a shared secret between server and client, to prevent unauthorized access.
The config is using ENV variables on production and hardcoded values for development and staging.
Clients
notifier
can be used by any HTTP client, in most simple case curl
,
1
|
|
We already have Node.js client DemocracyOS/notifier-client and plan to have browser client as well. But in essence it’s just HTTP post with event
payload and access_token
in query string, so basically it can be used from any language and platform.