CloudMailin provides a complete email API allowing you to send and receive email from your application.

When you provision the CloudMailin Add-on you will be automatically given an email address (or you can bring your own domain) to send email to. Any email sent to that address will be sent to your application via HTTP POST as JSON or multipart/form-data.

CloudMailin also offers transactional email sending via SMTP or a REST API for reliable, scalable and secure email delivery on the Heroku platform.

With a complete dashboard and message history you'll never be left wondering what happened to an email again. CloudMailin works with any language or framework and is the perfect solution for any email needs.

Provisioning the add-on

CloudMailin can be attached to a Heroku application via the CLI:

callout A list of all plans available can be found here.

$ heroku addons:create cloudmailin --target=https://yourapp.herokuapp.com/incoming_messages
Creating cloudmailin on sharp-mountain-4005... free
Your add-on has been provisioned successfully

note You don't need to set the target here but it will speed up the process of provisioning the correct URL for HTTP POSTs.

After you provision CloudMailin, the CLOUDMAILIN_FORWARD_ADDRESS config var is available in your app's configuration. It contains the email address that you can send to. You'll also be given your SMTP credentials as a CLOUDMAILIN_SMTP_URL which you can use to send email via SMTP:

$ heroku config
=== sharp-mountain-4005 Config Vars

CLOUDMAILIN_FORWARD_ADDRESS:         123456abc@cloudmailin.net
CLOUDMAILIN_SMTP_URL:                smtp://usr:pswd@host.name.example.net:587?starttls=true

After you install CloudMailin, your application should be configured to fully integrate with the add-on.

Dashboard, Monitoring and logging

CloudMailin provides a dashboard allowing you to view the full history of all emails sent or received by your application within Heroku. You can also setup your own domain, configure emails and/or attachments to be sent directly to Cloud Storage such as AWS S3.

You can either access the dashboard via the the CLI with the following command:

$ heroku addons:open cloudmailin
Opening cloudmailin for sharp-mountain-4005

or by visiting the Heroku Dashboard and selecting the application in question. Select CloudMailin from the Add-ons menu.

Receiving Email with Heroku

CloudMaillin will send all email to your application as an HTTP POST in either JSON or multipart/form-data format.

The full details can be found in the documentation:

An example POST looks like the following:

{
  "headers": {
    "return_path": "from@example.com",
    "received": [
      "by 10.52.90.229 with SMTP id bz5cs75582vdb; Mon, 16 Jan 2012 09:00:07 -0800",
      "by 10.216.131.153 with SMTP id m25mr5479776wei.9.1326733205283; Mon, 16 Jan 2012 09:00:05 -0800",
      "from mail-wi0-f170.google.com (mail-wi0-f170.google.com [209.85.212.170]) by mx.google.com with ESMTPS id u74si9614172weq.62.2012.01.16.09.00.04 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 16 Jan 2012 09:00:04 -0800"
    ],
    "date": "Mon, 16 Jan 2012 17:00:01 +0000",
    "from": "Message Sender <sender@example.com>",
    "to": "Message Recipient<to@example.co.uk>",
    "message_id": "<4F145791.8040802@example.com>",
    "subject": "Test Subject",
    "mime_version": "1.0",
    "content_type": "multipart/alternative; boundary=------------090409040602000601080801",
    "delivered_to": "to@example.com",
    "received_spf": "neutral (google.com: 10.0.10.1 is neither permitted nor denied by best guess record for domain of from@example.com) client-ip=10.0.10.1;",
    "authentication_results": "mx.google.com; spf=neutral (google.com: 10.0.10.1 is neither permitted nor denied by best guess record for domain of from@example.com) smtp.mail=from@example.com",
    "user_agent": "Postbox 3.0.2 (Macintosh/20111203)"
  },
  "envelope": {
    "to": "to@example.com",
    "from": "from@example.com",
    "helo_domain": "localhost",
    "remote_ip": "127.0.0.1",
    "recipients": [
      "to@example.com",
      "another@example.com"
    ],
    "spf": {
      "result": "pass",
      "domain": "example.com"
    },
    "tls": true,
  },
  "plain": "Test with HTML.",
  "html": "<html><head>\n<meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-1\"></head><body\n bgcolor=\"#FFFFFF\" text=\"#000000\">\nTest with <span style=\"font-weight: bold;\">HTML</span>.<br>\n</body>\n</html>",
  "reply_plain": "Message reply if found.",
  "attachments": [
    {
      "content": "dGVzdGZpbGU=",
      "file_name": "file.txt",
      "content_type": "text/plain",
      "size": 8,
      "disposition": "attachment"
    },
    {
      "content": "dGVzdGZpbGU=",
      "file_name": "file.txt",
      "content_type": "text/plain",
      "size": 8,
      "disposition": "attachment"
    }
  ]
}

Adding code to receive emails:

Examples of how to receive email in various languages can be found in the CloudMailin documentation.

Although there are examples in the documentation, we'll include a Node JS (Typescript) example here to show how easily you can access the email:

import express from "express";
import { IncomingMail, MessageClient, Message } from "cloudmailin";

const app = express();
app.use(express.json());
const port = 6001;

app.post("/incoming_mails/", (req, res) => {
  const mail = <IncomingMail>req.body;

  if (mail.envelope.to == 'postman@cloudmailin.net') {
    res.status(201).json({ status: `Thanks for sending: ${mail.plain}` });
    return;
  }

  res.status(401).json({ status: `Incorrect User ${mail.envelope.to}` });
});

Once that's deployed sending the above email to CLOUDMAILIIN_FORWARD_ADDRESS will post to /incoming_mails/ with the JSON above will return a 201 status code with the message Thanks for sending: Test with HTML..

This also shows the benefit of the CloudMailin HTTP Status Codes feature. If you return a 2xx status code the message will be accepted, however 4xx status codes will bounce messages and 5xx status codes will cause them to be retried at a later date.

Receiving email with attachments on Heroku

With CloudMailin attachments can either be sent as Base64 encoded strings or completely offloaded to Amazon S3. The full details can be found in the CloudMailin documentation.

Assuming we're working with the Base64 attachments you can access the attachments like this:

app.post("/incoming_mails", (req, res) => {
  const mail = <IncomingMail>req.body;

  const attachment = mail.attachments[0];

  if (attachment.content) {
    const data: Buffer = Buffer.from(attachment.content, 'base64');
    fs.writeFileSync(attachment.file_name, data);

    return res.status(201).json({ status: `wrote ${attachment.file_name}` });
  }
}

callout More examples can be found in the CloudMailin documentation.

Sending Email with Heroku

Sending with CloudMailin is easy. You can either use the SMTP credentials provided in the CLOUDMAILIN_SMTP_URL config var or use the REST API.

Sending email with SMTP

The SMTP credentials provided in the CLOUDMAILIN_SMTP_URL config var can be used directly to send emails with SMTP. The full details can be found in the CloudMailin send email via SMTP documentation.

In order to send with SMTP you'll need the following:

Field Description Example (from above URL)
Host Provided in the CLOUDMAILIN_SMTP_URL config var host.name.example.net
Port 587, 2525, 25 or allow the value to come from the CLOUDMAILIN_SMTP_URL config var 587
Username Provided in the CLOUDMAILIN_SMTP_URL config var usr
Password Provided in the CLOUDMAILIN_SMTP_URL config var pswd
Authentication CloudMailin supports plain, login which are both safe because the connection will be encrypted plain
StartTLS CloudMailin requires all connections issue the start TLS command after opening true

Since the default in Ruby is to use SMTP to send email we'll include an example from a Ruby on Rails app here:

# Add the config to an initializer config/initializers/cloudmailin.rb
smtp_url = URI.parse(ENV['CLOUDMAILIN_SMTP_URL'])
ActionMailer::Base.add_delivery_method :cloudmailin, Mail::SMTP,
  address: smtp_url.host,
  port: smtp_url.port,
  user_name: smtp_url.user,
  password: smtp_url.password,
  authentication: 'plain',
  enable_starttls_auto: true

# You can then set the delivery method in your environment config
# config/environments/production.rb
config.action_mailer.delivery_method = :cloudmailin

callout More examples can be found in the CloudMailin documentation.

Sending with the API

The SMTP credentials provided in the CLOUDMAILIN_SMTP_URL config var can be used to send email via SMTP. The full details can be found in the CloudMailin send Email via API Documentation.

However, here's a quick example of how to send an email with SMTP in Node JS (Typescript):

import { IncomingMail, MessageClient, Message } from "cloudmailin";

const app = express();
app.use(express.json());
const port = 6001;

if (!process.env.CLOUDMAILIN_SMTP_URL)
  throw new Error("Cloudmailin SMTP URL not set");

// Take the username and password from the SMTP URL in Environemtn Variables
const smtpURL = new URL(process.env.CLOUDMAILIN_SMTP_URL);
const user = smtpURL.username;
const password = smtpURL.password;

With Node the cloudmailin library will help you to send the email, however, this library simply makes an HTTP POST to the CloudMailin API. If you're not using the cloudmailin library you can make the HTTP POST yourself.

Simply make a POST request to the API URL:

POST: https://api.cloudmailin.com/api/v0.1/[SMTP_USERNAME]/messages

callout More details and examples∑ can be found in the CloudMailin send Email via API Documentation.

Migrating between plans

note CloudMailin plans can be upgraded or downgraded at any time without service interruption. However, Heroku will restart the app so you may need to take thisinto account when modifying plans.

Use the heroku addons:upgrade command to migrate to a new plan.

$ heroku addons:upgrade cloudmailin:corp2m
-----> Upgrading cloudmailin:newplan to sharp-mountain-4005... done, v18 ($499/mo)
       Your plan has been updated to: cloudmailin:corp2m

Removing the add-on

You can remove CloudMailin via the CLI:

warning This will destroy all associated data and cannot be undone!

$ heroku addons:destroy cloudmailin
-----> Removing cloudmailin from sharp-mountain-4005... done, v20 (free)

Before removing CloudMailin, ensure that you do not need any of the message history. You can retrive the message history archive from the dashboard before removing the add-on.

Support

All CloudMailin support and runtime issues should be submitted via one of the Heroku Support channels. Any non-support related issues or product feedback is welcome at CloudMailin Support.