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 🙏

© 2025 – Pkg Stats / Ryan Hefner

layer-webhooks-services-sendgrid

v0.9.3

Published

Sendgrid integration triggered by Layer Webhooks

Readme

Layer Webhooks Service - Sendgrid

npm version

This repository contains an integration between Layer messaging service and Sendgrid email service. It is designed to notify participants about unread messages by sending an email.

Setting up Sendgrid

The following actions are needed:

  1. Obtain an API key. This key is needed for the sendgridKey parameter. Your key should be configured to enable access to Parse Webhooks and Mail Send.
  2. Register a subdomain that you can map to mx.sendgrid.net. See https://sendgrid.com/docs/API_Reference/Webhooks/parse.html#-Setup for details. All emails sent to this subdomain will be received and processed by sendgrid.
  3. Register your webhook. Go to Settings => Inbound Parse, and add your registered subdomain as host, and this web server's url (ending typically with /new-mail) as the URL (e.g. 'https://mysampleco.com/new-mail')

The Full API

The following parameters are supported:

| Name | Required | Description | |-----------------------|-----------|-------------| | server | Yes | Server config | | server.app | Yes | An express server instance, listening using https protocol. | | server.sApp | No | An express server instance listening on a different port. Used when app is running on a self signed certificate; sendgrid webhooks won't use a self signed certificate, so a separate express server listening on a separate port must be provided in this case. | | server.url | Yes | URL that this server is on; omit paths. Used in combination with the path property to register your webhook. | | server.unreadMessagePath | No | Path that the express app will use to listen for unread message webhook requests. Customize if using multiple copies of this repo. | | sserver.emailReplyPath | No | Path that the express app will use to listen for new email webhook requests. | | layer | Yes | Layer config | | layer.webhookServices | Yes | An instance of Webhook Service Client | | layer.client | Yes | An instance of Layer Platform API Client | | layer.secret | Yes | Any unique string that nobody outside your company knows; used to validate webhook requests | | sendgrid | Yes | Sendgrid config | | sendgrid.key | Yes | Your sendgrid API Key | | sendgrid.emailDomain | Yes | Full hostname registered with sendgrid; all From fields will use this when sending emails. | | delay | Yes | How long to wait before checking for unread messages and notifiying users. Delays can be configured using a number representing miliseconds, or a string such as '10 minutes' or other strings parsable by ms | | identities | Yes | Function that looks up a user's info and returns the results via callback | | templates | No | Templates Object for the message, subject and sender | | name | No | Name to assign the webhook; needed if your using this repository for multiple webhooks. | | reportForStatus | No | Array of user states that justify notification; ['sent'] (Message could not be delivered yet); ['sent', 'delivered'] (Message is undelivered OR simply unread); ['delivered'] (Message is delivered but not read). Default is ['sent', 'delivered'] | | updateObject | No | Asynchronous callback for decorating the Message object being fed into the templates |

identities(userId, callback)

Layer's Webhooks do not provide key values needed to drive email services. In order to send users an email, An email address must be provided. The default behavior is to automatically get the address from the Layer's Identities service; however, this only works if you've actually registered your user's address there.

If you are not using the Layer Identities service and putting email addresses there, then provide a identities function when configuring this module. The identities function should return a User Object. Your User Object should provide name and email fields; other custom fields can be added and used from your templates.

function getMyIdentitiy(userId, callback) {
    // Lookup in a database or query a web service to get details of this user
    doLookup(userId, function(err, result) {
       callback(error, {
          email: result.myEmail,
          name: result.first_name + ' ' + result.last_name,
          misc: result.favorite_color
       });
    });
}

require('layer-webhooks-service-sendgrid')({
    identities: getMyIdentity,
    ...
});

updateObject(message, callback)

To add additional information to your Message object before its passed through your templates, you can add the optional updateObject parameter:

require('layer-webhooks-service-sendgrid')({
    ...,
    updateObject: function(message, callback) {
        message.fieldA = 'value A';
        callback(message);
    }
});

You can then have a template string that contains You have a <%= fieldA %> from <%= sender.name %>.

Templates

Templates use Underscore JS Templates. The following template parameters can be provided:

  • textTemplate: A text-only version of your email message
  • htmlTemplate: An html versin of your email message
  • subjectTemplate: The subject line for your email
  • fromNameTemplate: The display name for the sender, but NOT the email address of the sender of the email.

Each of these templates should expect to run on a Message Object as defined by the Layer Webhooks Docs.

In addition, the following properties will be added:

  • sender Object: This will be an object returned from Layer's Identity Service or an object you provide via an identities call on the sender of this Message.
  • recipient Object: This will be an object returned from Layer's Identity Service or an object you provide via an identities call on a single recipient
  • text String: This will extract any text/plain parts and concatenate their body's together into an easily accessed string

A typical template might look like:

{
    "textTemplate": "Hello <%= recipient.name %>;\n\nYou have an unread message from <%= sender.name %>:\n<%= text %>\n\nSincerely\nYour Bot",
    "htmlTemplate": "<body>Hello <%= recipient.name %>;<br/><br/>nYou have an unread message from <b><%= sender.name %></b>:<div><%= text %></div>Sincerely<br/>Your Bot</body>",
    "subject": "You have Failed! Failed, to read <%= text =>",
    "fromNameTemplate": "Lord <%= sender.name %> King of this Email"
}

Example

// Setup Redis and kue
var redis = require('redis').createClient(process.env.REDIS_URL);
var queue = require('kue').createQueue({
  jobEvents: false,
  redis: process.env.REDIS_URL
});

// Setup the Layer Platform API
var LayerClient = require('layer-api');
var layerClient = new LayerClient({
  token: process.env.LAYER_BEARER_TOKEN,
  appId: process.env.LAYER_APP_ID,
});

// Setup the Layer Webhooks Service
var LayerWebhooks = require('layer-webhooks-services');
var webhookServices = new LayerWebhooks({
  token: process.env.LAYER_BEARER_TOKEN,
  appId: process.env.LAYER_APP_ID,
  redis: redis
});

secureExpressApp.listen(PORT, function() {
    require('layer-webhooks-service-sendgrid')({
        server: {
            app: secureExpressApp,
            url: 'https://mydomain.com'
        },
        layer: {
            client: layerClient,
            webhookServices: webhookServices,
            secret: 'Lord of the Mog has jammed your radar'
        },
        sendgrid: {
            key: 'abcdef',
            emailDomain: 'my-mx-record.mycompany.com'
        },
        delay: '30 minutes',
        templates: {
            text: 'Yo <%= recipient.name %>! Read your Messages Dude!\n\n<%= sender.name %> said "<%= text %>" to you and you totatally ignored him!'
        }
    });
});