Send Emails In An Ionic 2 App Via The Rackspace Mailgun API

Not too long ago I wrote about sending emails in an Ionic Framework app using the Rackspace Mailgun API.  To get you up to speed, I often get a lot of questions regarding how to send emails without opening the default mail application from within an Ionic Framework application.  There are a few things that could be done.  You can either spin up your own API server and send emails from your server via an HTTP request or you can make use of a service.

To compliment the previous post I wrote for Ionic Framework, I figured it would be a good idea to demonstrate how to use Mailgun in an Ionic 2 application.

Mailgun, for the most part, is free.  It will take a lot of emails before you enter the paid tier.  Regardless, you’ll need an account to follow along with this tutorial.

Let’s start by creating a new Ionic 2 project.  From the Command Prompt (Windows) or Terminal (Mac and Linux), execute the following:

A few important things to note here.  The first thing to note is the use of the --v2 tag.  This is an Ionic 2 project, and to create Ionic 2 projects, the appropriate Ionic CLI must be installed.  Finally, you must be using a Mac if you wish to add and build for the iOS platform.

This project uses no plugins or external dependencies.  This means we can start coding our application.

Coding the Mailgun Logic

Starting with the logic file, open your project’s app/pages/home/home.ts file and include the following code:

There is a lot going on in the above snippet so let’s break it down.

First you’ll notice the following imports:

The Mailgun API is accessed via HTTP requests.  To make HTTP requests we must include the appropriate Angular 2 dependencies.  More on HTTP requests can be seen in a previous post I wrote specifically on the topic.

Next we define our Mailgun domain URL and corresponding API key.  For prototyping I usually just use the sandbox domain and key, but it doesn’t cost any extra to use your own domain.  However, notice the following:

We are making use of the btoa function that will create a base64 encoded string.  Having a base64 encoded string is a requirement when using the authorization header of a request.

Finally we get into the heavy lifting.  The send function is where all the magic happens.

The send function expects an authorization header as well as a content type.  The Mailgun API expects form data to be sent, not JSON data.  This data is to be sent via a POST request.

Creating the Simple UI

This brings us into our UI.  To keep things simple our UI is just going to be a form that submits to the send function.  Open your project’s app/pages/home/home.html file and include the following code:

The above form has two standard text input fields for the recipient and subject.  There is a text area for the message body and a button for submitting the form data.  The input elements are all bound using an ngModel.  This allows us to pass the fields into the send function.

Give it a try, you should be able to send emails now via HTTP.

Conclusion

You just saw how to send emails without opening an email client on the users device.  This could be useful for sending logs to the developer, or maybe a custom feedback form within the application.  Previously I wrote about how to use Mailgun in an Ionic Framework application, but this time we saw how with Ionic 2, Angular 2, and TypeScript.

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

  • This is great and all, but how are you getting around the CORS error Request header field Authorization is not allowed by Access-Control-Allow-Headers ?

    • You cannot run it via a web browser, with Ionic Serve, or with Ionic View. I’m not positive if it will work with Ionic Live-Reload. All of these methods don’t truly install the application to the device or simulator. When the application is compiled and installed, it doesn’t operate on localhost and thus does not suffer from CORS related issues.

      Does that clear things up?

  • any idea how to make ion-textarea auto grow?

    • I’m not sure you would want to have text areas that auto expand. Seems like better UI design if you define the sizing up front. I think that is how most apps do it.

  • I ended up packaging this in its own component, then including it in multiple pages:

    then in my other pages:

    Thanks again!

    • Actually, this seems to cause my pages to break. Any suggestions for injecting the Mailgun component into other components properly?

      • Any particular error? Instead of making a component I think you may want to make a service instead.

  • Bob Millan

    So this works great and all but i’ve run into an issue. When I install the app with a fresh build on android the initial request never gets received by mailgun. However when I reopen the app all the previous requests go through and get sent at once. Afterwards it starts working as it should. Any Idea what might be the cause of that?

    • Can you give me some information regarding your test environment? Emulators, devices, platform versions, etc? Any logs when it misbehaves?

  • arsene

    after creating Mailgun account, i see it desable? any idea? thanks

    • No idea what you’re trying to do or what problems you’re facing, if any. Please give more thorough comments.

  • Shamroz Warraich

    XMLHttpRequest cannot load https://api.mailgun.net/v3/sandboxfb8969c586644cf6b31528ecd7a557b2.mailgun.org/messages. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.

    home.ts:44 ERROR -> {“_body”:{“isTrusted”:true},”status”:200,”ok”:true,”statusText”:”Ok”,”headers”:{},”type”:3,”url”:null}
    facing this error any idea help….?

    • Are you trying to serve this application? You’ll probably get these problems while trying to serve, but you shouldn’t receive them on the device.

      • Shamroz Warraich

        also try on device but not work there… :/

      • Stevie Starosciak

        I’ve also tried this on a mobile device and have run into the same issue, except my error looks like:

        ERROR -> {“_body”:{“isTrusted”:true},”status”:0,”ok”:false,”statusText”:””,”headers”:{},”type”:3,”url”:null}

        • Jorge Reyes

          hi, did you solve this problem? Im also having this exact problem.

      • Serkan Ünal

        Hi Nick,
        Im getting same error when I deployed www folder on firebase hosting. I think its not related with serve or localhost.
        If would like you can debug it. Code debugging is enable. https://livelinksunal.firebaseapp.com/

        • I can’t help you with Firebase since I don’t use it. My code works for me. You might play around with Postman or Fiddler before bringing it into your app. If that fails, you might reach out to Mailgun support on using their APIs.

          Best,

  • Marius ‘Romania’ Talpos

    Is there anyway to in corporate a proxy to deal with CORS issues on local “ionic serve” testing?
    I tried adding “proxies”: [
    {
    “path”: “/email”,
    “proxyUrl”: “https://api.mailgun.net/v3/sandboxc9e010e60a8d409f8f780e5163d588e9.mailgun.org/messages”
    }
    ]
    to my ionic.config.json and my url in the request would be just “/email”.
    This however throws a 404 and says [ POST http://localhost:8100/email 404 (Not Found) ] in my browser console.
    Shouldn’t my proxy defined in the config file handle all requests to /email and then send the request to mailgun’s api?

    ill add my gist here for reference as well : https://gist.github.com/GeminiLegend/2b01e42fff6f1d26ebac444706691d50

    • That question is best suited for Mike from Ionic since I do not use Ionic Serve. I’ve looped him in per this Tweet:

      https://twitter.com/nraboy/status/768578537167073280

      • Marius ‘Romania’ Talpos

        How would attachments such as images and files be handled? like this?:
        this.http.request(new Request({
        method: RequestMethod.Post,
        url: this.mailgunUrl,
        body: “[email protected]&to=” + recipient + “&subject=” + subject + “&text=” + emailBody,
        headers: headers,
        attachments: supportingDocuments
        })).subscribe(……..

        the supportingDocuments var in this case would be an array with the path to each file inside the phone. ex.file://var/mobile/Containers/Data/Application/148770D1-6824-4A1C-ABF9-41E874B6161B/Documents/buisness_tax_return.jpg(this is the file name)

        • Being that we are using the REST API for the Mailgun service you would need to read their documentation for how to handle file data. Without having done this myself, you would probably need to use the file plugin to obtain the file data and then add it to one of the expected API parameters.

          In all honesty though, you probably shouldn’t attach files like this. Seems like it would eat up your users data real fast.

          • Marius ‘Romania’ Talpos

            I just ended up using the Cordova email composer plug in since it was very simple to use. And yes you’re right but that’s not really my call to make so ¯(ツ)/¯ .

    • Mike Hartington

      Proxies support should work fine for V2. Set up a simple express server and a proxy in the ionic.config.json file as a test

      https://gist.github.com/mhartington/e61d68aca91215528a95a61cd2d12c98

      Not sure on the specifics of this example though, but proxies do indeed work.

  • Adusumilli

    I have implemented the code and generated mailGun url and api key. while Ionic serve I’m getting the error after transpile started

    Error: listen EADDRINUSE 0.0.0.0:53703
    at Object.exports._errnoException (util.js:1026:11)
    at exports._exceptionWithHostPort (util.js:1049:20)
    at Server._listen2 (net.js:1257:14)
    at listen (net.js:1293:10)
    at net.js:1403:9
    at _combinedTickCallback (internal/process/next_tick.js:77:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
    at Module.runMain (module.js:606:11)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)

    Can I know why it is happening??? Thanks in advance

  • Guillermo Ochoa

    How can i attach emails with html????

  • wilson

    I am having the following problem when sending the post I get the answer comes with error:

    Request URL:https://api.mailgun.net/v3/selsunb.com.br/messages
    Request Method:POST
    Status Code:404 Not Found (from cache)
    Request Headers
    Provisional headers are shown
    Authorization: mykey
    Content-Type:application/x-www-form-urlencoded
    Origin:file://
    User-Agent:Mozilla/5.0 (Linux; Android 5.1.1; GT-I9082 Build/LMY49G) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36
    Form Dataview sourceview URL encoded
    from:[email protected]
    to:[email protected]
    subject:teste de mensagem
    text:mesagem de teste
    Response Headers
    Client-Via:shouldInterceptRequest

    • Is your authorization header correct? It shouldn’t just be your key.