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:
Published on 22 Nov 2013 by Stanley Tan