Parse + Mailgun

I had to deploy some application logic to Parse for a startup I was helping. Parse is handling their backend and we decided to use Mailgun for the sending of emails. Parse has a nice Cloud Code facility where you can write Javascrpit functions to automate certain actions.

Before I could do anything, I had to install the parse binary. Here was what they had on their documentation.

$ curl -s https://www.parse.com/downloads/cloud_code/installer.sh | sudo /bin/bash

Not curl | sudo /bin/bash again. I guess it really has become a norm. There are perfectly working package managers in all Linux distributions which should be used instead. It’s non-ideal from a maintainability and security point of view.

After downloading the installer.sh to see what was actually happening, I noticed that they pulled the binary straight from their download directory https://www.parse.com/downloads/cloud_code/parse, followed by the usual administration of making it executable.

With the Parse binary on hand, I started to get to work. It was my first time dealing with Parse and I had to look at the documentation every step of the way.

$ parse new <module name>

Generates 3 folders. cloud, config and public. In the cloud folder, there was a Javascript file main.js where the code would be located. I found that this was creating a new module for use with a new instance. In my case, there was already existing code in Parse and I needed to pull the existing Cloud Code to my local machine. After looking really hard on the documentations and searching for solutions, I couldn’t find any way to pull the existing code down to my local machine.

Parse isn’t a very good name for searching any documentation. Results were not what I wanted. I figured that since I was creating a new module, it shouldn’t affect the current existing code. I continued to write the function in main.js and deployed it. To my horror, it had overwritten the existing codebase with the code I just wrote. Luckily, I had another window open on the page showing the old version that I could manually copy onto my local machine. There should be a better way for dealing with this.

I found out there was a help forum that made looking stuff up so much easier. They addressed the issue of importing Cloud Code to a new machine. And it wasn’t possible at this point in time. There were comments on how it would overwrite the existing code with the newly deployed version. I wished I had found that out earlier.

After sifting through all the documentations and forum posts regarding Mailgun, I realised that I only had to write my own modules if I needed the other features of Mailgun as Parse’s default mailgun module can only send emails. With that knowledge, I could start my implementation.

Here’s what I did for a quick drop-in implementation for an API endpoint that your program can hit for sending a pre-defined email.

var Mailgun = require('mailgun');
Mailgun.initialize('<Your Mailgun domain>', '<Your Mailgun API key>');

Parse.Cloud.define("sendEmail", function(request, response) {
  Mailgun.sendEmail({
    to: request.params.email,
    from: "My Awesome Name <my@awesome.email>",
    subject: "Hello World!",
    text: "Hello from Parse/Mailgun!\n\nIt's awesome!"
  }, {
    success: function(httpResponse) {
      console.log(httpResponse);
      response.success("Email sent!");
    },
    error: function(httpResponse) {
      console.error(httpResponse);
      response.error("Uh oh, something went wrong");
    }
  });
});

You can hit this REST API endpoint with any programming language. Here’s an example with a curl request.

$ curl -X POST \
  -H "X-Parse-Application-Id: <Your Parse application ID>" \
  -H "X-Parse-REST-API-Key: <Your Parse REST API key>" \  
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{ "email": "recipient@email.com" }' \  
  https://api.parse.com/1/functions/sendEmail

Now for my particular implementation, I wanted to send an onboarding email immediately after a user registers. Parse has an afterSave() function that comes in useful. After looking for a while, I found that Parse.Object has a method called existed() which returns false in the afterSave() when the object was just created. This helps in checking if the save action is indeed operating on a new user.

var Mailgun = require('mailgun');
Mailgun.initialize('<Your Mailgun domain>', '<Your Mailgun API key>');

Parse.Cloud.afterSave("UsersTable", function(request) {
  // This function runs on INSERT and DELETE operations.
  // Check to ensure account is new.
  if (!request.object.existed()) {
    var emails = request.object.get("account");
    var name = request.object.get("name");
    Mailgun.sendEmail({
      to: emails[0],
      from: "My Awesome Name <my@awesome.email>",
      subject: "Hello World!",
      text: "Hello " + name + ",\n\n Welcome to my new app!"
    }, {
      success: function(httpResponse) {
        console.log(httpResponse);
        console.log("Email sent to " + emails[0]);
      },
      error: function(httpResponse) {
        console.error(httpResponse);
        console.error("Uh oh, something went wrong");
      }
    });
  }
});

Now that we have our Cloud Code in place, any user that registers in our app will be sent our onboarding email. I found this method to be extremely useful for introducing yourself, as well as orientating the user to the app.

Some relevant links:

Stanley Tan
@stnly