notifme / notifme-sdk
- суббота, 12 августа 2017 г. в 03:12:58
A Node.js library to send all kinds of transactional notifications.
A Node.js library to send all kinds of transactional notifications.
Easy channel integration — Want to start sending emails
| SMS
| pushes
| webpushes
? Do so in no time!
Unique documentation — Don't look everywhere for the parameters you need to pass, just do it once. Switching provider becomes a no-brainer.
Multiple providers strategies — Want to use more than one provider? Use fallback
and round-robin
strategies out of the box.
Queue system — Plug your own external queue system to ensure delivery (if you have one).
Tools for local testing — Run a catcher locally to intercept all your notifications and display them in a web interface.
MIT license — Use it like you want.
$ yarn add notifme-sdk
import NotifmeSdk from 'notifme-sdk'
const notifmeSdk = new NotifmeSdk({}) // empty config = no queue and provider is console.log
notifmeSdk
.send({sms: {from: '+15000000000', to: '+15000000001', text: 'Hello, how are you?'}})
.then(console.log)
Notification Catcher is a web interface for viewing and testing notifications during development.
$ yarn add --dev notification-catcher
$ yarn run notification-catcher
import NotifmeSdk from 'notifme-sdk'
const notifmeSdk = new NotifmeSdk({
useNotificationCatcher: true // <= this sends all your notifications to the catcher running on port 1025
})
notifmeSdk
.send({sms: {from: '+15000000000', to: '+15000000001', text: 'Hello, how are you?'}})
.then(console.log)
new NotifmeSdk({
channels: ..., // Object
requestQueue: ..., // false | 'in-memory' | Function
onSuccess: ..., // Function
onError: ..., // Function
useNotificationCatcher: ... // boolean
})
Option name | Required | Type | Description |
---|---|---|---|
channels |
false |
Object |
Define providers (Array ) and multiProviderStrategy (string ) for each channel (email, sms, push, webpush).See all details below: 2. Providers. |
requestQueue |
false |
false | string | Function |
Default: false .Queue used for your notification requests. You can pass 'in-memory' to mimic an external queue in your local environment. To use a real queue, see 3. Use a request queue below. |
onSuccess |
false |
Function |
Callback to call when a notification has been sent with success. The first parameter is described below and the second is your request. |
onError |
false |
Function |
Callback to call when a notification has an error in at least one channel. The first parameter is described below and the second is your request. |
useNotificationCatcher |
false |
boolean |
If true, all your notifications are sent to the catcher running on localhost:1025 (channels option will be completely ignored!) |
// Env: development
new NotifmeSdk({
requestQueue: false,
useNotificationCatcher: true,
onSuccess: (result, originalRequest) => {
console.log(`My request id ${originalRequest.id} was successful \\o/.`, result)
},
onError: (result, originalRequest) => {
console.log(`Oh no, my request id ${originalRequest.id} has errors.`, result.errors)
}
})
// Env: production
new NotifmeSdk({
channels: {
email: {
multiProviderStrategy: 'fallback', // If Mailgun fails, use Mailjet
providers: [{
type: 'smtp',
host: 'smtp.mailgun.org',
port: 465,
secure: true,
auth: {
user: 'postmaster@xxxxx.mailgun.org',
pass: 'xxxxx'
}
}, {
type: 'smtp',
host: 'in-v3.mailjet.com',
port: 587,
secure: true,
auth: {
user: 'xxxxx',
pass: 'xxxxx'
}
}]
},
sms: {
multiProviderStrategy: 'roundrobin', // Use Nexmo and Twilio in turns (and fallback if error)
providers: [{
type: 'nexmo',
apiKey: 'xxxxx',
apiSecret: 'xxxxx'
}, {
type: 'twilio',
accountSid: 'xxxxx',
authToken: 'xxxxx'
}]
}
},
onSuccess: (result, originalRequest) => {
// Maybe log success in database
},
onError: (result, originalRequest) => {
// Maybe retry failed channel(s) later
}
})
new NotifmeSdk({
channels: {
email: {
providers: [{
type: 'smtp',
host: 'smtp.example.com',
port: 465,
secure: true,
auth: {
user: 'xxxxx',
pass: 'xxxxx'
}
}]
}
}
})
new NotifmeSdk({
channels: {
email: {
providers: [{
type: 'sendmail',
sendmail: true,
newline: 'unix',
path: '/usr/sbin/sendmail'
}]
}
}
})
new NotifmeSdk({
channels: {
email: {
providers: [{
type: 'logger'
}]
}
}
})
See all options: Email provider options
new NotifmeSdk({
channels: {
sms: {
providers: [{
type: 'nexmo',
apiKey: 'xxxxx',
apiSecret: 'xxxxx'
}]
}
}
})
new NotifmeSdk({
channels: {
sms: {
providers: [{
type: 'twilio',
accountSid: 'xxxxx',
authToken: 'xxxxx'
}]
}
}
})
new NotifmeSdk({
channels: {
sms: {
providers: [{
type: 'logger'
}]
}
}
})
See all options: SMS provider options
new NotifmeSdk({
channels: {
push: {
providers: [{
type: 'apn',
token: {
key: './certs/key.p8',
keyId: 'xxxxx',
teamId: 'xxxxx'
}
}]
}
}
})
new NotifmeSdk({
channels: {
push: {
providers: [{
type: 'fcm',
id: 'xxxxx'
}]
}
}
})
new NotifmeSdk({
channels: {
push: {
providers: [{
type: 'wns',
clientId: 'xxxxx',
clientSecret: 'xxxxx',
notificationMethod: 'sendTileSquareBlock'
}]
}
}
})
new NotifmeSdk({
channels: {
push: {
providers: [{
type: 'adm',
clientId: 'xxxxx',
clientSecret: 'xxxxx'
}]
}
}
})
new NotifmeSdk({
channels: {
push: {
providers: [{
type: 'logger'
}]
}
}
})
See all options: Push provider options
new NotifmeSdk({
channels: {
webpush: {
providers: [{
type: 'gcm',
gcmAPIKey: 'xxxxx',
vapidDetails: {
subject: 'mailto: contact@example.com',
publicKey: 'xxxxx',
privateKey: 'xxxxx'
}
}]
}
}
})
new NotifmeSdk({
channels: {
webpush: {
providers: [{
type: 'logger'
}]
}
}
})
See all options: Webpush provider options
Strategy name | Description |
---|---|
fallback |
If the used provider returns an error, try the next in the list. |
roundrobin |
Use every provider in turns. If one of them returns an error, fallback to the next. |
no-fallback |
Deactivates fallback strategy. |
If you would like to see another provider or channel, please upvote the corresponding issue (or create one if it does not exist yet).
You can use your own queue system to handle notification requests. It must implement the following interface:
interface QueueType<T> {
enqueue(type: string, jobData: T): Promise<?Object>;
dequeue(type: string, callback: CallbackType<T>): void;
// Note: callback is an async method treating a request
}
new NotifmeSdk({
requestQueue: {
enqueue: (type, request) => { // 'type' is prefixed by 'notifme:'
return new Promise((resolve) => {
// Put request in your queue
resolve(/* info from your queue system */)
})
},
dequeue: (type, callback) => {
// Get a request from your queue
callback(request).then(/* Send ack for this request */)
}
}
})
notifmeSdk.send({
email: {
from: 'me@example.com',
to: 'john@example.com',
subject: 'Hi John',
html: '<b>Hello John! How are you?</b>'
}
})
See all parameters.
notifmeSdk.send({
sms: {
from: '+15000000000',
to: '+15000000001',
text: 'Hello John! How are you?'
}
})
See all parameters.
notifmeSdk.send({
push: {
registrationToken: 'xxxxx',
title: 'Hi John',
body: 'Hello John! How are you?',
icon: 'https://notifme.github.io/notifme-sdk/img/icon.png'
}
})
See all parameters.
notifmeSdk.send({
webpush: {
subscription: {
keys: {
auth: 'xxxxx',
p256dh: 'xxxxx'
},
endpoint: 'xxxxx'
},
title: 'Hi John',
body: 'Hello John! How are you?',
icon: 'https://notifme.github.io/notifme-sdk/img/icon.png'
}
})
See all parameters.
notifmeSdk.send({
email: {
from: 'me@example.com',
to: 'john@example.com',
subject: 'Hi John',
html: '<b>Hello John! How are you?</b>'
},
sms: {
from: '+15000000000',
to: '+15000000001',
text: 'Hello John! How are you?'
},
push: {
registrationToken: 'xxxxx',
title: 'Hi John',
body: 'Hello John! How are you?',
icon: 'https://notifme.github.io/notifme-sdk/img/icon.png'
},
webpush: {
subscription: {
keys: {
auth: 'xxxxx',
p256dh: 'xxxxx'
},
endpoint: 'xxxxx'
},
title: 'Hi John',
body: 'Hello John! How are you?',
icon: 'https://notifme.github.io/notifme-sdk/img/icon.png'
}
})
See all parameters.
send
returns a Promise resolving with an Object
of the following type:
type NotificationStatusType = {
status: 'queued' | 'success' | 'error',
channels?: {[channel: ChannelType]: {
id: string,
providerId: ?string
}},
info?: ?Object,
errors?: {[channel: ChannelType]: Error}
}
Examples:
Case | Returned JSON |
---|---|
Success (when Promise resolves) |
{status: 'success', channels: {sms: {id: 'id-116561976', providerId: 'sms-default-provider'}}} |
Success (when you use a queue for requests) |
{status: 'queued'} |
Error (here Notification Catcher is not running) |
{status: 'error', channels: {sms: {id: undefined, providerId: 'sms-notificationcatcher-provider'}}, errors: {sms: 'connect ECONNREFUSED 127.0.0.1:1025'}} |
Option name | Usage in production |
---|---|
useNotificationCatcher | false |
requestQueue | false | Function (see 3. Use a request queue) |
This project uses winston as logging library. You can add or remove loggers as you wish.
import NotifmeSdk from 'notifme-sdk'
import winston from 'winston'
const notifmeSdk = new NotifmeSdk({})
// To deactivate all loggers
notifmeSdk.logger.mute()
// Or set the loggers you want
notifmeSdk.logger.configure([
new (winston.transports.File)({filename: 'somefile.log'})
])
See winston's documentation for more details.
So that we can make a list of people using this library ;)
Contributions are very welcome!
To get started: fork this repository to your own GitHub account and then clone it to your local device.
$ git clone git@github.com:[YOUR_USERNAME]/notifme-sdk.git && cd notifme-sdk
$ yarn install
Before making a pull request, check that the code respects the Standard JS rules and the Flow type checker.
$ yarn run lint
Submit an issue to the project Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes.