Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Send Emails With Mailgun Using NativeScript And Angular

TwitterFacebookRedditLinkedInHacker News

Sending emails from your mobile application is often a critical aspect. For example, what if you want to be able to collect user feedback, wouldn’t email be one of the better solutions? Now let’s add to this scenario and say that the user doesn’t have email configured on their mobile device. How does the user send emails to you from your application? This is where the Mailgun API comes into play.

The Mailgun API is a service, which includes a free tier, for sending emails via a RESTful API. No need for users to configure their email client and no need to maintain an email inbox. It is great for getting the job done.

Not too long ago I wrote about using the Mailgun API in a vanilla NativeScript application. One of my subscribers recently requested information on how to accomplish this task using Angular in a NativeScript application and I thought it would make a perfect tutorial.

Before continuing through this tutorial you will need to have created a free Mailgun account. With this account you have access to a Mailgun URL and a Mailgun API key. These two strings are critical when it comes to sending emails in your application.

To make things easy to understand, we’re going to start a fresh NativeScript Angular project. From the Command Prompt (Windows) or Terminal (Linux and Mac), execute the following:

tns create MailgunProject --ng
cd MailgunProject
tns platform add ios
tns platform add android

The --ng tag in the above indicates we are creating an Angular TypeScript project. While I’ve added the iOS build platform, if you’re not using a Mac you won’t actually be able to build for iOS.

We’re going to spend all of our time in three particular files. We’re going to include various dependencies in the project’s app/main.ts file, the email form UI in the project’s app/app.component.html file, and the Mailgun logic in the project’s app/app.component.ts file.

The NativeScript Angular and TypeScript Logic

Starting with the app/main.ts file, open it and include the following TypeScript code:

import { platformNativeScriptDynamic, NativeScriptModule } from "nativescript-angular/platform";
import { NativeScriptHttpModule } from "nativescript-angular/http";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
import { NgModule } from "@angular/core";
import { AppComponent } from "./app.component";

@NgModule({
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    imports: [
        NativeScriptModule,
        NativeScriptFormsModule,
        NativeScriptHttpModule
    ],
})
class AppComponentModule {}

platformNativeScriptDynamic().bootstrapModule(AppComponentModule);

In reality, I’ve only included two things that are different from the default template. The goal here was to include the NativeScriptFormsModule and the NativeScriptHttpModule so that we can make HTTP requests and bind data to UI input fields.

Now we can focus on the bulk of our application. Open the project’s app/app.component.ts file and include the following TypeScript code:

import { Component } from "@angular/core";
import { Http, Headers, RequestOptions } from "@angular/http";
import "rxjs/Rx";

@Component({
    selector: "my-app",
    templateUrl: "app.component.html",
})
export class AppComponent {

    public recipient: string;
    public subject: string;
    public message: string;
    private mailgunUrl: string = "MAILGUN_URL_HERE";
    private apiKey: string = "BASE64_API_KEY_HERE";

    public constructor(private http: Http) {

    }

    public send() {
        if(this.recipient && this.subject && this.message) {
            let headers = new Headers(
                {
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Authorization": "Basic " + this.apiKey
                }
            );
            let options = new RequestOptions({ headers: headers });
            let body = "from=test@example.com&to=" + this.recipient + "&subject=" + this.subject + "&text=" + this.message;
            this.http.post("https://api.mailgun.net/v3/" + this.mailgunUrl + "/messages", body, options)
                .map(result => result.json())
                .do(result => console.log("RESULT: ", JSON.stringify(result)))
                .subscribe(result => {
                    console.log("SENT!");
                    this.recipient = "";
                    this.subject = "";
                    this.message = "";
                }, error => {
                    console.log(error);
                });
        }
    }

}

There is a lot going on in the above code so we’re going to break it down piece by piece.

import { Component } from "@angular/core";
import { Http, Headers, RequestOptions } from "@angular/http";
import "rxjs/Rx";

We need to import Http along with Headers and RequestOptions because we’ll be making an HTTP post request to the Mailgun API. This request will require certain headers to be set, otherwise the request will be rejected by Mailgun. HTTP requests in Angular are not very powerful unless you include RxJS with them.

Inside our AppComponent class we have various private and public variables.

public recipient: string;
public subject: string;
public message: string;
private mailgunUrl: string = "MAILGUN_URL_HERE";
private apiKey: string = "BASE64_API_KEY_HERE";

The public variables will be bound to input fields within the application UI. What is most important here is the mailgunUrl and the apiKey variables. It is critical you get these correct. The URL and API key can be found in your Mailgun administrative dashboard. However, the API key must be formatted before it can be used.

When you obtain your API key it should look something like api:key-sdf7sfadyuhk where it starts with api:key- followed by some hash. Your entire key, including api:key- needs to be base64 encoded. You can encode the API key using the website Base64 Encode.

Before we can make HTTP requests, the Http component needs to be injected into the constructor method of the class.

Finally we have the send method:

public send() {
    if(this.recipient && this.subject && this.message) {
        let headers = new Headers(
            {
                "Content-Type": "application/x-www-form-urlencoded",
                "Authorization": "Basic " + this.apiKey
            }
        );
        let options = new RequestOptions({ headers: headers });
        let body = "from=test@example.com&to=" + this.recipient + "&subject=" + this.subject + "&text=" + this.message;
        this.http.post("https://api.mailgun.net/v3/" + this.mailgunUrl + "/messages", body, options)
            .map(result => result.json())
            .do(result => console.log("RESULT: ", JSON.stringify(result)))
            .subscribe(result => {
                console.log("SENT!");
                this.recipient = "";
                this.subject = "";
                this.message = "";
            }, error => {
                console.log(error);
            });
    }
}

Inside the send method we confirm that our form variables have data in them. If they have data we can define our request headers. Per the Mailgun API documentation we need to have an Authorization header and a Content-Type of x-www-form-urlencoded. Not my first choice since it is much easier to send data in JSON format, but it is out of our control.

Notice that the body of the request is ampersand delimited, not a JavaScript object. It is very important because we’re using x-www-form-urlencoded.

When we send the request, we can transform the response using RxJS and reset the form after subscribing to the observable created.

Now let’s focus on the UI of this application.

The NativeScript UI for the Mailgun Application

The UI we create will be very simple, but it will get the job done. It will make use of the NativeScript CSS theme that is provided in our application template to make it look more attractive.

Open the project’s app/app.component.html file and include the following XML markup:

<ActionBar title="Mailgun Example">
    <ActionItem text="Send" ios.position="right" (tap)="send()"></ActionItem>
</ActionBar>
<StackLayout class="form">
    <StackLayout class="input-field">
        <Label class="label" text="Recipient (To):"></Label>
        <TextField class="input input-border" [(ngModel)]="recipient" autoCapitalizationType="none"></TextField>
    </StackLayout>
    <StackLayout class="input-field">
        <Label class="label" text="Subject:"></Label>
        <TextField class="input input-border" [(ngModel)]="subject"></TextField>
    </StackLayout>
    <StackLayout class="input-field">
        <Label class="label" text="Subject:"></Label>
        <TextField class="input input-border" [(ngModel)]="message"></TextField>
    </StackLayout>
</StackLayout>

There are a few key things to note in the above XML markup.

Inside the action bar we have a button that when clicked will trigger the save method that is found in our TypeScript code. Each of the form inputs has a [(ngModel)] tag which creates a two way data binding with the public variables that we also defined in the TypeScript code. This allows us to accept user input via the form and manipulate the input via our TypeScript.

At this point the application should be ready to go.

Conclusion

You just saw how to use Mailgun to send transactional emails in a NativeScript application built with TypeScript and Angular. This is a great way to send emails within your application without requiring the user to have their own email account. This tutorial was a step up from my previous which used vanilla NativeScript and TypeScript.

Nic Raboy

Nic Raboy

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