Introduction

Today we will learn how to create and use a MESG service that send email using SendGrid.

You can access the final version of the source code on GitHub.

You can find a more advanced and maintained version of this service here: Service Email SendGrid.

If you haven't installed MESG SDK yet, follow this guide.

MESG services are composed of two different parts:

  • Tasks: actions that your service will execute
  • Events: data that your service provides

For this step of this tutorial, we will only focus on tasks.

Create the MESG service

It's time to create our MESG Service. First, open a terminal in your development folder and run the following command:

mesg-cli service:init ./service-email-sendgrid-tuto

Then, select the Javascript template.

The command should have created a service-email-sendgrid-tuto folder containing the boilerplate files for the service. Leave these files intact; we'll return to them a bit later in this tutorial.

You should see a mesg.yml and a Dockerfile in your service folder which are the fundamental parts of every MESG service.

  • mesg.yml: A file that contains all of the metadata of your Service. It gives some global descriptions but also includes the tasks and events that the Service can provide.
  • Dockerfile: A file that describes your Docker container and configures the environment for your service to run inside.

Send emails through a task

Configure your task

Let's define the task we want to create in the mesg.yml file.

First, clean the mesg.yml file, keeping only the keys: name, sid and description. Change their value to look like this:

name: Send Email with SendGrid Tutorial
sid: service-email-sendgrid-tuto
description: Send Email with SendGrid

Add the key configuration, containing the key env, containing the env SENDGRID_API_KEY like this:

configuration:
  env:
    - SENDGRID_API_KEY=

This env variable will contain the required SendGrid API Key.

And add a new task called send to tasks section which will be responsible for sending an email based on the following inputs:

  • from: the account to send the email from
  • to: the recipient of the email
  • subject: the subject of the email
  • text: the text of the email

Also this Service's task will return a status as outputs:

  • status: status of the sent email

To add this information into your Service, add the following definition in the mesg.yml file:

tasks:
  send:
    inputs:
      from:
        type: String
      to:
        type: String
      subject:
        type: String
      text:
        type: String
    outputs:
      status:
        type: Number

The content of mesg.yml should look like:

name: Send Email with SendGrid Tutorial
sid: service-email-sendgrid-tuto
description: Send Email with Sendgrid
configuration:
  env:
    - SENDGRID_API_KEY=
tasks:
  send:
    inputs:
      from:
        type: String
      to:
        type: String
      subject:
        type: String
      text:
        type: String
    outputs:
      status:
        type: Number

Code the task

The next step is to code your Service. To do this, you can use any language that you want. For this tutorial we will use Javascript.

Open index.js and replace taskX words to send and remove emitEvent line since it'll not be used in this tutorial.

Your index.js should look similar to this:

const Service = require('@mesg/service')
const mesg = new Service()

mesg.listenTask({
  send: require('./tasks/send')
})
  .on('error', (error) => console.error(error))

With this code, the service will start listening execution requests for send task from MESG Engine and execute the handler to create and submit a result.

To create a handler for the send task, rename tasks/taskX.js to tasks/send.js and replace its content with the following code:

module.exports = (inputs) => {
  console.log('New send task received')
  // TODO later
}

This is a basic skeleton for a Service, but now we need to actually code the emails with SendGrid. For this, we will use the SendGrid library.

npm install --save @sendgrid/mail

Then require it in send.js:

const sendgrid = require('@sendgrid/mail')

Then, pass the content of the env variable SENDGRID_API_KEY to SendGrid:

sendgrid.setApiKey(process.env.SENDGRID_API_KEY)

We had a TODO in our handler for send task, let's code the business logic using the SendGrid library we just imported.

module.exports = async (inputs) => {
  console.log('New send task received')
  // Sends an email with the inputs
  const result = await sendgrid.send({
    from: inputs.from,
    to: inputs.to,
    subject: inputs.subject,
    text: inputs.text
  })
  // Return the success output
  return {
    status: result[0].statusCode
  }
}

This code sends an email with the inputs defined in the mesg.yml and returns the status code.

Now your final Service code should look like this:

index.js

const Service = require('@mesg/service')
const mesg = new Service()

mesg.listenTask({
  send: require('./tasks/send')
})
  .on('error', (error) => console.error(error))

tasks/send.js

const sendgrid = require('@sendgrid/mail')
sendgrid.setApiKey(process.env.SENDGRID_API_KEY)

module.exports = async (inputs) => {
  console.log('New send task received')
  // Sends an email with the inputs
  const result = await sendgrid.send({
    from: inputs.from,
    to: inputs.to,
    subject: inputs.subject,
    text: inputs.text
  })
  // Return the success output
  return {
    status: result[0].statusCode
  }
}

Your Service is now ready for the second step.

Testing

Make sure MESG Engine is running:

mesg-cli daemon:start

Let's create a test file to test the send task. Create a test.json file with all the inputs needed for the task.

{
  "from": "sender@domain.tld",
  "to": "__YOUR_EMAIL__",
  "subject": "Test email",
  "text": "Hello world from MESG Service"
}
WARNING

Replace the __YOUR_EMAIL__ with your own email to test it. Don't worry, this is only done locally. We will not collect it 😀

Now time to test it.

You now need to get your own private SendGrid API key. You can create it here: https://app.sendgrid.com/settings/api_keys.

Let's start the service by running the command:

mesg-cli service:dev --env SENDGRID_API_KEY=__CHANGE_WITH_YOUR_SENDGRID_API_KEY__

Replace __CHANGE_WITH_YOUR_SENDGRID_API_KEY__ by the SendGrid API Key.

Wait for the service to start and then in an other terminal (make sure to point the terminal in the service folder), execute the following command:

mesg-cli service:execute service-email-sendgrid-tuto send --json test.json

The send task will be executed and you should have the result with status 202 in the console and your precious email in your mailbox.

Stop the service by pressing ctrl + c in the terminal.

Congratulations! 🎉

Get some rest now, you've done a good job creating your first service with MESG. Of course you can always create more complicated services. Make sure to check out the documentation for more details.