npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rokot-notification

v3.0.2

Published

Rokot - [Rocketmakers](http://www.rocketmakers.com/) TypeScript NodeJs Platform

Downloads

10

Readme

rokot-notification

Rokot - Rocketmakers TypeScript NodeJs Platform

Introduction

The Rokot Notification library provides a framework to create (JSON) Notification Messages and send them to users via a notification channel (email, apns and gcm 'out-the-box')

These notification messages are generally transcoded into some form of textual content (HTML/text), but could also directly contain the content to be sent

Core Components

INotification

The library is based around the core concept of a notification message (INotification)

This should represent the real life data behind the user notification

Each notification should have:

  1. a unique type (this is the key to indicate which handler will process the notification)
  2. a recipient to indicate the audience of the notification - which can be string values (for use in a single transport scenario), or transport keys {email:"[email protected]", apns:["ABC", "XYYZ"], gcm:"xds") to support multiple transports and multiple tokens
import {INotification} from "rokot-notification";

export interface ISampleTemplateNotification extends INotification {
  fail?: boolean;
}
const notification: ISampleTemplateNotification = {
  type: "sample-underscore-template-message",
  recipient: {
    email:"[email protected]"
  },
  fail: false
}

INotificationHandler

Each notification type requires a notification handler

The framework provides this handler with decorators to add functions to support:

  1. validating notifications before the transport method is called
  2. creating template content (html/text content via underscore templates)
  3. to pre cache the templates at startup (loading template content from disk/db early)
  4. to validate the template execution at startup with test case notifications you provide

A simple notification handler that just utilise the transport

import {notifications, INotification} from "rokot-notification";
import {INodemailerNotificationHandler, INodemailerNotificationTransport} from "rokot-notification/lib/nodemailer";

/** Define the shape of the Notification */
export interface ISimpleNotification extends INotification {
  html: string;
  text: string;
}

/**
Register this handler for the notification type via @notification.handler("simple")
NOTE: You dont need to export the notification handler
*/
@notifications.handler("simple")
class SimpleHandler implements INodemailerNotificationHandler<ISimpleNotification>{

  /**
  register the nodemailer transport function via @notifications.transport()
  */
  @notifications.transport()
  async nodemailer(notification: ISimpleNotification, transport: INodemailerNotificationTransport) {
    return await transport.send(notification.recipient, m => {
      m.from = transport.getFromAddress(notification)
      m.subject = `Simple Email`
      m.text = notification.text
      m.html = notification.html
    })
  }
}

Or a complete example showing usage of all the functions

import {notifications, UnderscoreFileSystemTemplateProcessorFactory, INotification} from "rokot-notification";
import {INodemailerNotificationHandler, INodemailerNotificationTransport} from "rokot-notification/lib/nodemailer";
import {ISampleTemplateNotification} from "./sampleTemplateNotification";
import {emailTo} from "../../settings";

/** The example templates processor factory */
const exampleTemplatesFactory = new UnderscoreFileSystemTemplateProcessorFactory("./source/test/examples/templates")

export const notificationType = "sample-underscore-template-message"

/** You dont need to export the notification handler*/
@notifications.handler(notificationType)
class TemplateHandler implements INodemailerNotificationHandler<ISampleTemplateNotification>{

  /** Validate the notification before its passed to the transport method */
  @notifications.validator()
  validate(notification: ISampleTemplateNotification){
    return Promise.resolve(notification);
  }

  /** Provides a sample notification that will be validated against any @notification.template() functions */
  @notifications.testCase()
  testMessage() : ISampleTemplateNotification{
    return {type: notificationType, recipient: {nodemailer: emailTo}, fail: true}
  }

  /** You can provide as many test cases as you like (to exercise the template generation) */
  @notifications.testCase()
  testMessage1() : ISampleTemplateNotification{
    return {type: notificationType, recipient: {nodemailer: emailTo}, fail: false}
  }

  /** You can also inspect which @notification.template() function is requesting the data */
  @notifications.testCase()
  testMessage2(template: string) : ISampleTemplateNotification{
    if (template === "text") {
      // dont use this for the 'text' template
      return
    }
    return {type: notificationType, recipient: {nodemailer: emailTo}}
  }

  /**
  Using Underscore templates loaded from a root folder
  These template providing function are pre-cached at startup to reduce runtime IO
  */
  @notifications.template()
  html(){
    return exampleTemplatesFactory.create<ISampleTemplateNotification>(`${notificationType}.html`)
  }

  /** Using Underscore templates loaded from a root folder */
  @notifications.template()
  text() {
    return exampleTemplatesFactory.create<ISampleTemplateNotification>(`${notificationType}.txt`)
  }

  /** the nodemailer transport function */
  @notifications.transport()
  async nodemailer(notification: ISampleTemplateNotification, transport: INodemailerNotificationTransport) {
    return await transport.send(notification.recipient, m => {
      m.from = transport.getFromAddress(notification)
      m.subject = `Template Email`
      // using templates.transform provides access to the pre-cached @notification.template() decorated function results
      m.text = notifications.transformTemplate(notification, this.text)
      m.html = notifications.transformTemplate(notification, this.html)
    })
  }
}

Or a notification handler using multiple transports

import {notifications, INotification} from "rokot-notification";
import {INodemailerNotificationHandler, INodemailerNotificationTransport} from "rokot-notification/lib/nodemailer";
import {IApnsNotificationHandler, IApnsNotificationTransport} from "rokot-notification/lib/apns";

export interface IMultipleNotification extends INotification {
  type: "sample-multi-channel-message"
  count: number;
}

@notifications.handler("sample-multi-channel-message")
class MultipleHandler implements IApnsNotificationHandler<IMultipleNotification>, INodemailerNotificationHandler<IMultipleNotification>{

  /** the apns transport function */
  @notifications.transport()
  async apns(notification: IMultipleNotification, transport: IApnsNotificationTransport) : Promise<any>{
    return await transport.send(notification.recipient, n => {
      n.body = `Count of ${notification.count}`
      n.topic = "<app package id>"
    })
  }

  /** the nodemailer transport function */
  @notifications.transport()
  async nodemailer(notification: IMultipleNotification, transport: INodemailerNotificationTransport) {
    return await transport.send(notification.recipient, m => {
      m.from = transport.getFromAddress(notification)
      m.subject = `Test Email`
      m.text = `Count of ${notification.count}`
      m.html = `Test HTML email`
    })
  }
}

NOTE: There are 3 core notification handlers avaiable 'out-the-box' IApnsNotificationHandler<TNotification>, IGcmNotificationHandler<TNotification> and INodemailerNotificationHandler<TNotification>

NotificationDispatcher

The framework provides a NotificationDispatcher to route notifications to their dispatch handler

You need to create your Application NotificationDispatcher and configuring which transports are used

import {NotificationDispatcherFactory} from "rokot-notification";
import {apnsInitializer, IApnsProviderOptions} from "rokot-notification/lib/apns";
import {sendgridInitializer,INodemailerSendgridOptions} from "rokot-notification/lib/nodemailer";
import {gcmInitializer,IGcmProviderOptions} from "rokot-notification/lib/gcm";
import {ConsoleLogger, Logger} from "rokot-log";

async function createDispatcher(nodemailerOptions: INodemailerSendgridOptions, apnsOptions: IApnsProviderOptions, gcmOptions: IGcmProviderOptions) {
  const logger = ConsoleLogger.create("test-multiple-message-dispatcher")
  const dispatcherFactory = new NotificationDispatcherFactory(logger)
  return await dispatcherFactory.createDispatcher(
    sendgridInitializer(logger, nodemailerOptions),
    gcmInitializer(logger, gcmOptions),
    apnsInitializer(logger, apnsOptions));
}

// createDispatcher({username:"sendgrid username", password:"send grid password"}, {token:{key:"/path/to.p8",keyId:"KEY_ID",teamId:"TEAM_ID"},production:false}, {apiKey:"<gcm api key>"})

NOTE: You can create your own MessageHandler for any kind of notification channel you like, or change the Nodemailer transport (from the 'out-the-box' sendgrid)

Notification Client Generation

You can create a typescript file in the root of your source and include the source below (modifying the paths to match your handler locations)

This code will inspect the source code and generate a Notifications client - exposing methods for each of the notification types

import {ConsoleLogger} from "rokot-log";
import {generateClient, getInterfaceFunctionName, getFolderFiles} from "rokot-notification/lib/client/generator";
const logger = ConsoleLogger.create("create notification client",{level:"info"})

/** Get all notification handler source files (all in a single folder) */
const files = getFolderFiles("./source/test/examples/handlers");

/** Generate a notification client */
generateClient(logger, files, "./source/test/examples/notifications.ts", {
  /** override the method naming function */
  functionName: getInterfaceFunctionName
})

Templates

HTML Template

<div>
Hello There <%= model.recipient.nodemailer || model.recipient.email || model.recipient %> (<%= model.type %>)
Process <%= model.fail ? "Failed" : "Ok" %>
</div>

Getting Started

Installation

Install via yarn

yarn add rokot-notification

Further Examples

Check out the examples in /package/source/test/examples to see various dispatcher configs and message handlers

Consumed Libraries

node-gcm

Android Push Notifications

apn

Apple Push Notifications

nodemailer

Email Notifications

nodemailer-sendgrid-transport

Email via sendgrid transport

rokot-test

The testing framework used within the Rokot Platform!