DEV Community

Cover image for Resilient e-mail sending in Meteor with Superface.ai
Jan Dvorak
Jan Dvorak

Posted on • Updated on

Resilient e-mail sending in Meteor with Superface.ai

Meteor 2.4 brought with it new feature version of the email package. v2.2 of email package added a function, Email.customTransport, that can override e-mail sending from Meteor app with the way you want it. This allows us to build resilient e-mail sending. Normally this would include a lot of logic and API calls to handle, but no longer! We have an elegant solution with Superface.ai

Superface is a start-up with a goal to simplify API integration and one of the solutions they came up with is target/source resiliency. This means that if one API end-point is dead it will automatically switch automatically to your backup one that you have configured without you needing to add any extra lines of code. You can read more details about this on their page or in their dev.to post about e-mail sending resiliency.

Here I'm going to show you how to combine Meteor's Email.customTransport with Superface.ai to make resilient e-mail sending for you Meteor app.

Pre-requisits

As a pre-requisits you will need to be on at least Meteor 2.4 and have configured two e-mail sending services to send from. In my case it is Mailgun and Sendgrid.

Prepare Superface.ai

Let's get started with Superface.ai! We start with adding their one-sdk to our project:

meteor npm install @superfaceai/one-sdk
Enter fullscreen mode Exit fullscreen mode

Next, we add the send-email capability:

npx @superfaceai/cli install communication/send-email -i
Enter fullscreen mode Exit fullscreen mode

Now you just follow the setup to select your primary and secondary e-mail services and add their keys. In case you want to add them manually later on you can use the following commands:

npx @superfaceai/cli configure mailgun --profile=communication/send-email
npx @superfaceai/cli configure sendgrid --profile=communication/send-email
Enter fullscreen mode Exit fullscreen mode

Now you will notice two new things in your project directory. First you have a new directory called superface. In it you will find all the superface settings, most notably in super.json and you can manually edit them if you know what you are doing.

Second is .env file has been either created or has new entries from the interactive setup. You can edit them if you need to.

Meteor code

Now that we have Superface all setup, it is time to plug it into our Meteor code. On your server go to the file where you are handling e-mail related stuff (or create a new file or add it to index.js in your server folder).

First things first, we need to import Meteor, our email packages and one-sdk from Superface:

import { Meteor } from 'meteor/meteor'
import { Email } from 'meteor/email'
import { SuperfaceClient } from '@superfaceai/one-sdk'
Enter fullscreen mode Exit fullscreen mode

Now let's create our Superface send function:

/**
 * Function to send e-mails via Superface
 * @type {object} data E-mail data from Email.customTransport
 * @returns {string} e-mail id
 */
const superfaceSendEmail = async (data) => {
  // Instanciate Superface client
  const superfaceClient = new SuperfaceClient()
  // Let's get the send email profile 
  const profile = await superfaceClient.getProfile('communication/send-email')
  // Perform the action
  const result = await profile.getUseCase('SendEmail').perform(data)
  // Get the result
  return result.unwrap()
}
Enter fullscreen mode Exit fullscreen mode

Meteor can be a bit iffy with async functions like this, so we better wrap it in Meteor.wrapAsync like this:

const superfaceSendEmail = Meteor.wrapAsync(async (data) => {
  const superfaceClient = new SuperfaceClient()
  try {
    const profile = await superfaceClient.getProfile('communication/send-email')
    const result = await profile.getUseCase('SendEmail').perform(data)
    return result.unwrap()
  } catch(e) {
    console.error(e)
  }
})
Enter fullscreen mode Exit fullscreen mode

Now we just need to hook it up to the e-mail package and we are all set:

Email.customTransport = (data) => {
  superfaceSendEmail(data)
}
Enter fullscreen mode Exit fullscreen mode

Profit?

Not quiet there yet. Since Superface expects that its settings will be available in the default location, it will get a nasty surprise when you run Meteor. Meteor builds separately for server and client and strange folders like superface in the root is not something that it will touch. So to get it on the server you will need to copy (or better, create create a symbolic link) in your private folder. This will then put the superface folder on the server under assets (assets/app/superface/). Now all that remains is to tell via env variable Superface where it should look for its settings:

SUPERFACE_PATH=assets/app/superface/super.json
Enter fullscreen mode Exit fullscreen mode

Note, you can setup dotenv package to get all this data from .env file that you place into your private folder. Install the dotenv package and then at the start of your server run: require('dotenv').config({ path: 'assets/app/.env' })
For Galaxy deployment you can put all your variables in Meteor settings under "galaxy.meteor.com".env in your Meteor settings.

Now, with all of that set you can enjoy Superface with Meteor!


If you like my work, please support me on GitHub Sponsors ❤️.

Discussion (0)