Skip to content

A redis based notification engine. It implements the rsmq-worker to safely create notifications and recurring reports

License

Notifications You must be signed in to change notification settings

mpneuried/redis-notifications

Repository files navigation

redis-notifications

Build Status Build Status NPM version

A redis based notification engine. It implements the rsmq-worker to safely create notifications and recurring reports.

The goal is to define a simple API to be able to send notifications and mails to multiple users. A user can define a setting to only receive one mail per day as a report. This is all done within a queuing solution. so it's scalable and failsafe.

NPM

Install

  npm install redis-notifications

Initialize

initialize

    var RedisNotifications = require( "redis-notifications" );

    var nf = new RedisNotifications();

    // REQUIRED EVENT LISTENERS
    // listen to errors
    nf.on( "error", function( err ){});

    // Hook to read details of an user
    nf.on( "readUser", function( user_id, cb ){ /* ... */ });

    // Hook to generate the message content for the notification and the mail
    nf.on( "getContent", function( type, user, editor, additional, cb ){  /* ... */ });

    // Hook to write/send the notification to the user. Is is done immediately on every create
    nf.on( "createNotification", function( user, editor, message, cb ){ /* ... */ });

    // Hook to send a report to a user.
    nf.on( "sendMail", function( user, messages, isReport, cb ){ /* ... */ });

    // INIT
    nf.init();

    // METHODS
    // define the data of the editor
    var editor = { id: "ABCDE", firstname: "William", lastname: "Creator", email: "william.create@example.com" };

    // create a notification to a single user
    nf.create( editor, { type: "notification_type", user: 123 }, function( err, msgid ){  /* ... */  });

Config

  • options ( Object optional ) The configuration object

    • options.maxBufferReadCount: ( Number optional; default = 100 ) Count of users to read at once to send mails

    RSMQ-Worker Options

    • options.queuename: ( String optional; default = rnqueue ) The queuename to pull the messages
    • options.interval: ( Number[] optional; default = [ 0, 1, 5, 10 ] ) An Array of increasing wait times in seconds
    • options.maxReceiveCount: ( Number optional; default = 10 ) Receive count until a message will be exceeded
    • options.invisibletime: ( Number optional; default = 30 ) A time in seconds to hide a message after it has been received.
    • options.defaultDelay: ( Number optional; default = 1 ) The default delay in seconds for for sending new messages to the queue.
    • options.timeout: ( Number optional; default = 3000 ) Message processing timeout in ms. So you have to call the next() method of message at least after e.g. 3000ms. If set to 0 it'll wait until infinity.
    • options.prefix: ( String optional; default = notifications ) The redis namespace for rsmq
    • options.client: ( RedisClient optional; default = null ) A already existing redis client instance to use.
    • options.host: ( String optional; default = localhost ) Host to connect to redis if redis instance has been defined
    • options.port: ( Number optional; default = 6379 ) Port to connect to redis if redis instance has been defined
    • options.options: ( Object optional; default = {} ) Options to connect to redis if redis instance has been defined

Event Hooks

readUser

Call to read a user by the given id. So you have to implement the DB/API read yourself

Arguments

  • user_id : ( String|Number ) The user id to read

  • cb : ( Function ) The callback function

    Callback Params:

    • err : ( Null|Error ) An optional error
    • user : ( Object ) The user result with the following fields. You can also add additional fields you need later
      • user.id : ( String|Number, required ) The user_id

      • user.firstname : ( String, required ) The user's first name.

      • user.lastname : ( String, optional ) The user's last name.

      • user.email : ( String, required ) The user's email.

      • user.timezone : ( String, required ) A timezone string. It has to be a valid moment timezone string

      • user.sendInterval : ( String, required ) The send interval. This defines if, how and when the user will receive a email

        Possible values:

        • 0: The user will never receive a mail
        • p: receive the only prio mails ( created with high:true ) immediately
        • i: receive the mail immediately
        • d{time}: receive the mail daily report. The time has to be a 4 digit number. E.g. 0800 = 8 in the morning within his timezone. 2330 = half an hour before midnight.

getContent

Create the notification content

Arguments

  • type : ( String ) The message type you defined on .create{Multile}()

  • user : ( Object ) User result generated by you within the readUser hook

  • editor : ( Object ) User editor you added on .create{Multile}()

  • additional : ( Object ) User additional data you added on .create{Multile}()

  • cb : ( Function ) The callback function

    Callback Params:

    • err : ( Null|Error ) An optional error
    • content : ( Object ) The content result with the following fields. You can also add additional fields you need later
      • content.subject : ( String, required ) The message subject/headline
      • content.body : ( String, required ) The message body
      • content.teaser : ( String, optional ) The message teaser. HTML will be stripped out! If not defined the module truncates the body to 100 chars.

createNotification

This will called immediately after .create{Multile}(). Here you have to write the notification to your db and/or send it immediately to the user.

Arguments

  • user : ( Object ) User result generated by you within the readUser hook

  • editor : ( Object ) User editor you added on .create{Multile}()

  • message : ( Object ) The message content you created within the getContent hook

  • cb : ( Function ) The callback function

    Callback Params:

    • err : ( Null|Error ) An optional error

sendMail

Send a mail to the user. This is only done if sendInterval is d{time}, i or p Only on d{time} a report is generated witch could contain more than one message.

Arguments

  • user : ( Object ) User result generated by you within the readUser hook

  • messages : ( Object[] ) An Array messages you created within the getContent hooks

  • isReport : ( Boolean ) A flag that tells you this mail is a report because the user used sendInterval = "d{time}".

  • cb : ( Function ) The callback function

    Callback Params:

    • err : ( Null|Error ) An optional error

error

An error occurred

Arguments

  • err : ( Error ) A error

Methods

.init()

After you added the required hooks you have the call .init() to start the module.

.create( editor, message [, cb ] )

Create a notification for one user

Arguments

  • editor : ( Object required ): The sending editor
    • editor.id : ( String|Number required ): a unique identifier of the notification creator
    • editor.firstname : ( String optional ): The first name of the creator
    • editor.lastname : ( String optional ): The last name of the creator
    • editor.email : ( String optional ): The email of the creator
  • message : ( Object required ): The message data
    • message.type : ( String required ): The notification type. This is a key to be able to generate different notification contents
    • message.user : ( String|Number required ): The id of the user that will receive this message
    • message.high : ( Boolean optional; default = false ): This flag marks this notification as high prio. So mails will send immediately and users with sendInterval = "p" will alos get a mail.
    • message.additional : ( Object optional ): An object you could use to place custom data. This cwill be passed to the hook getContent
  • cb : ( Function optional ): A optional callback method. Callback arguments: function( err, nid ){}

Return

( Null|Error ): Null on success or a validation error.

.createMulti( editor, message [, cb ] )

Create a notification for multiple users

Arguments

  • editor : ( Object required ): The sending editor
    • editor.id : ( String|Number required ): a unique identifier of the notification creator
    • editor.firstname : ( String optional ): The first name of the creator
    • editor.lastname : ( String optional ): The last name of the creator
    • editor.email : ( String optional ): The email of the creatore
  • message : ( Object required ): The message data
    • message.type : ( String required ): The notification type. This is a key to be able to generate different notification contents
    • message.users : ( Array required ): An Array of user ids that will receive this notification.
    • message.high : ( Boolean optional; default = false ): This flag marks this notification as high prio. So mails will send immediately and users with sendInterval = "p" will alos get a mail.
    • message.additional : ( Object optional; default = {} ): An object you could use to place custom data. This will be passed to the hook getContent
  • cb : ( Function optional ): A optional callback method. Callback arguments: function( err ){}

Return

( Null|Error ): Null on success or a validation error.

.getRsmqWorker()

Helper method to get internal used instance

Return

( RSMQWorker ): The internal rsmq-worker instance.

.getRsmq()

Helper method to get internal used instance

Return

( RedisSMQ ): The internal rsmq instance.

.getRedis()

Helper method to get internal used instance

Return

( RedisClient ): The internal redis instance.

Example

This is a example implementation. It's up to you to implement the DB read and Write methods and do the notification and mail sending.

    var RedisNotifications = require( "redis-notifications" );

    var nf = new RedisNotifications();

    // REQUIRED EVENT LISTENERS
    // listen to errors
    nf.on( "error", function( err ){
        console.error( err, err.stack );
    });

    // Hock to read details of an user
    nf.on( "readUser", function( user_id, cb ){

        // here you have to query your database and return a valid user with at least these fields
        var user = {
            // required fields
            id: user_id,                                // unique user id
            firstname: "John",          
            email: "john.do@mail.com",
            timezone: "CET",                        // a moment-timezone valid timezone
            sendInterval: "i",                      // when to send a mail 

            // optional fields
            lastname: "Do",             

            // custom fields
            custom_lang: "DE"                       // it is possible to add custom fields
        };
        cb( null, user );
    });

    // Hook to generate the message content for the notification and the mail
    nf.on( "getContent", function( type, user, editor, additional, cb ){

        // here you have to generate your message by type. Usually you would use a template-engine
        
        var content = {
            // required fields
            subject: "This is my message subject",
            body: "Lorem ipsum dolor ...",          

            // custom fields
            custom_field: additional.custom_key,    // it is possible to add custom fields to the content
            custom_lang: user.custom_lang           // reuse the custom field from user
        };
        cb( null, content );
    });

    // Hook to write/send the notification to the user. Is is done immediately on every create
    nf.on( "createNotification", function( user, editor, message, cb ){

        // here you have to write the notification to your db and/or send it immediately to the user

        cb( null );
    });

    // Hook to send a report to a user.
    // This is only done if `sendInterval` is `d{time}`, `i` or `p`
    // Only on `d{time}` a report is generated witch could contain more than one message
    nf.on( "sendMail", function( user, messages, isReport, cb ){

        // here you have to do create of the mail content and mail send it.

        cb( null );
    });

    // INIT
    // you have to initialize the module until the required listeners has been added
    nf.init();

    // METHODS

    // define the data of the editor
    var editor = {
        // required fields
        id: "ABCDE",

        // optional fields
        firstname: "William",
        lastname: "Creator",
        email: "william.create@example.com",

        // custom fields
        custom_lang: "DE"
    };


    // create a notification for multiple users without callback
    var errCrM = nf.createMulti( editor, {
        type: "notification_type",                  // A type to differ the content in the `getContent` hook
        users: [ 123, 456, 789 ],                   // An array of user that will receive this notification
        high: true                                  // A flag to define this notification as high prio.
    });
    if( errCrM ){
        console.error( errCrM );
    }
    // High means:
    // - This message will be send by mail immediately.
    // - Users with `sendInterval = "p"` (only high prio) will also get this notification.

    // create a notification to a single user
    nf.create( editor, {
        type: "notification_type",                  // A type to differ the content in the `getContent` hook
        user: 123,                                  // The user id that will receive this notification
        high: false,                                // A flag to define this notification as high prio.
        additional: {
            custom_icon: "info"                     // additional data that later can be used with in the `getContent` hook
        }
    }, function( err, msgid ){
        if( err ){
            console.error( err );
        }
    });

Todos

  • Tests
  • add sendInterval variant to send the report weekly and/or monthly.

Release History

Version Date Description
0.2.1 2016-10-27 Small bugfix with default value (Thanks to Anton Rau for #3). Updated dependencies
0.2.0 2016-07-18 Updated dev env and dependencies
0.1.1 2015-01-30 Logo update
0.1.0 2015-01-30 Added docs and optimized code and API
0.0.2 2015-01-29 moved schema to extra module obj-schema
0.0.1 2015-01-29 Initial version. No tests and docs until now!

NPM

Initially Generated with generator-mpnodemodule

Other projects

Name Description
rsmq A really simple message queue based on Redis
rsmq-worker Helper to simply implement a worker RSMQ ( Redis Simple Message Queue ).
node-cache Simple and fast NodeJS internal caching. Node internal in memory cache like memcached.
obj-schema Simple module to validate an object by a predefined schema
redis-sessions An advanced session store for NodeJS and Redis
connect-redis-sessions A connect or express middleware to simply use the redis sessions. With redis sessions you can handle multiple sessions per user_id.
systemhealth Node module to run simple custom checks for your machine or it's connections. It will use redis-heartbeat to send the current state to redis.
task-queue-worker A powerful tool for background processing of tasks that are run by making standard http requests.
soyer Soyer is small lib for serverside use of Google Closure Templates with node.js.
grunt-soy-compile Compile Goggle Closure Templates ( SOY ) templates inclding the handling of XLIFF language files.
backlunr A solution to bring Backbone Collections together with the browser fulltext search engine Lunr.js

The MIT License (MIT)

Copyright © 2015 Mathias Peter, http://www.tcs.de

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

A redis based notification engine. It implements the rsmq-worker to safely create notifications and recurring reports

Resources

License

Stars

Watchers

Forks

Packages

No packages published