Click here to Skip to main content
15,881,413 members
Articles / Hosted Services / Serverless

Serverless Experiments with Google Cloud Platform: Part 2

Rate me:
Please Sign up or sign in to vote.
4.67/5 (2 votes)
1 Jul 2017CPOL3 min read 9.6K  
Sending and receiving emails in cloud Functions

6. Email Service

From Part 1, you should know that Google Cloud Platform (GCP) Functions are pieces of code called when something happened. For various smaller tasks, you do not need to pay for own full-time server.

Problem of email sending looks like choosing one of the many Node.JS modules can do it (just search for 'send email nodejs'). Or maybe learning about something like Gmail API, I have also never tried.

But having no permanently running email server, who will receive email? Fortunately, there are various services that can do it instead of us. Get into k Email/SMS on https://elements.heroku.com/addons to see some.

Because of single registration, I choose Mailgun, which can both send and receive.

Actually, processing of ten thousand (maybe thousands https://www.mailgun.com/google with GCP) of emails is free. If you do not need your own email domain (do not try to conquest the whole gmail.com by Mailgun), it means when you are satisfied with something like sandbox1234567890abcdefghijklmnopqrst.mailgun.org, because of using emails just like occasional transformation medium between your services or few authorized email recipients, than you do not need to pay anything.

Registration needs just phone able to receive SMS and account works without entering any Payment Method with some limitations. It is possible to set Payment Method later in account settings.

To make it clear, Mailgun is a service for sending and receiving. It does not store emails permanently, anyway it allows temporary storage.

6.1. Send Email

Being registered, enter your Mailgun dashboard.

At the bottom, you will see your sandbox Domain Name (similar to sandbox1234567890abcdefghijklmnopqrst.mailgun.org). Clicking on it appears API Base URL (something like this) and API Key (say key-abcdefghijklmnopqrst1234567890).

API Key equals to Secret API Key visible at the right side of dashboard home page.

Sandbox domains are restricted to authorized recipients only. Using button get into Authorized Recipients here and Invite new one. Recipient must react to invitation email with Agree link, so start experiments with your own email. Assume it is yourname@gmail.com.

Switch to GCP console here and in Cloud Functions, create a new one with http trigger (more details are available in Part 1).

Do not forget in index.js to enter your email, API key and API Base URL.

JavaScript
/**
 * sends email using mailgun's https api
 *
 * @param {!Object} req Cloud Function request context.
 * @param {!Object} res Cloud Function response context.
 */
exports.sendEmailFunction = function sendEmailFunction(req, res) {
    
//based on https://github.com/shz/node-mailgun/blob/master/mailgun.js
//https://documentation.mailgun.com/quickstart-sending.html#send-via-api
var request = require("request");

var mailgunapiKey = new Buffer('api:' + "key-abcdefghijklmnopqrst1234567890").toString('base64');

var mailFormData = {
    from: "mailgun@mailgun.org",
    to: "yourname@gmail.com",
    subject: "sendEmailFunction",
    text: "Hallo from cloud"
  };
  
request({
  uri: "https://api.mailgun.net/v3/sandbox1234567890abcdefghijklmnopqrst.mailgun.org/messages",
  headers: {'User-Agent': 'request',
            'Authorization': 'Basic ' + mailgunapiKey,
           },
  method: "POST",
  form: mailFormData,
}, function(error, response, body) {
            res.status(200).send('Success: ' + error + "&" + response.statusCode + "&" + body + ' end');
});
  
};

Of course, mailFormData's members could be filled from variables, even such received in req (where script's caller must support it).

JavaScript
subject: req.body.subject,

Remember that because of require("request") inside script, you need to add request to package.json's dependencies.

6.2. Receive Email

With services like Mailgun, receiving is easy. Receving new incoming email, it will call your Function. You must define which Function will be called by which email.

In your Mailgun dashboard get into Routes. There Create Route, for begin the simplest it could be.

In Expression type, choose Catch All. It means that every incoming email (actually anything sent to your info@sandbox1234567890abcdefghijklmnopqrst.mailgun.org, contact@sandbox1234567890abcdefghijklmnopqrst.mailgun.org, etc.) will be handled by this Route.

From Actions, choose Forward and enter URL triggering your GCP Function, like this.

Because this is the only Route we create, it does not matter if you will select to Stop the processing of emails fitting to defined filter (Catch All) or not.

How could GCP receiveEmailFunction look like?

JavaScript
/**
 * Receive email from Mailgun.
 *
 * @param {!Object} req Cloud Function request context.
 * @param {!Object} res Cloud Function response context.
 */
exports.receiveEmailFunction = function receiveEmailFunction(req, res) {
//https://documentation.mailgun.com/user_manual.html#routes
  if (req.body.subject === undefined) {
    // This is an error case, as "subject" is required.
    res.status(400).send('No subject defined!');
  } else {
    // Everything is okay.
    console.log(req.body['body-plain']);
    res.status(200).send('Success: ' + req.body['body-plain']);
  }
};

Take this just like a simple example. Even when email has empty title, there is no reason that Function called by Mailgun will have req.body.subject undefined.

Note that compared to sending, there are different names of emails parts. The same plain body text is once text, once body-plain. Because of hyphen character inside name, it must be accessed using brackets.

Received email body is pre-parsed in more ways, have a look near body-plain here.

Now send email (from your yourname@gmail.com) to sandbox (something like whatever@sandbox1234567890abcdefghijklmnopqrst.mailgun.org) and voilà: for sender, nothing visible happens.

To be sure that email was received, have a look at logs on Mailgun here and (after a minute) on GCP here (in Functions, open your Function and click right-top VIEW LOGS).


End of Part Two. In the third part, I plan to connect Functions with other web services.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Slovakia Slovakia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --