YouTube Icon

Code Playground.

How to Send emails with EmberJS, Amazon SES And Firebase

CFG

How to Send emails with EmberJS, Amazon SES And Firebase

There is a need to build client side only (front end) applications. Tools like Ember CLI, Create react app, Angular 2 CLI make it very easy to bootstrap a JavaScript app in just a few minutes and start building features.

The challenge arises when you need to add a piece of server side logic, like sending emails, uploading files, authentication, or storing some data to the database. In most cases, it doesn’t make sense to add a full blown server, which requires to be maintained and setup . All you want is one or two server side features, right? ????

Firebase can solve that problem (partially). It adds missing server side components to your front-end application without managing a server. Think of it as a NoSQL database with built-in API and some extra features like analytics, hosting and authentication.

All examples here are for Ember.js, since that’s the project I was working on when I had the need to add a contact form. But it can be applied to any front end framework where the server is not available or cost effective.

The goal

When the user submits a form on a website, it saves the submitted data in the database for future reference and sends an email notification to the website admin containing all the submitted values. This is a simple feature, which comes for free with any CMS or server side framework (WordPress, Ruby on Rails, etc). But this simple feature requires a server. And we don’t want to add server…

The solution

We are combining Firebase and AWS simple email service (SES). For low traffic websites?—?free tier on both services will last you a long time. When the user submits a form?—?we send an email and save it to the database in parallel.

Here is an implementation for firebase. Add EmberFire to your project. After adding API keys to enviroment.js, you can start using firebase in your code. Let’s say we have contact.js controller, which handles the form’s “submit” action.

actions: {
  sendContactForm() {
    // Getting input values. 
    // TODO: add validation before trying to save the values.
    const submittedForm = {
      name: this.get('name'),
      email: this.get('email'),
      company: this.get('company'),
      phone: this.get('phone'),
      message: this.get('message'),
      timestamp: new Date().getTime()
+   };
      
    // Save the submitted form to our database
+   const newContact = this.store.createRecord('contact', submittedForm);
+   newContact.save().then(function(res) {
      // display success or fail message to the user after saving the values to DB
    });
  }
}

That’s all you need to do to save ANY data to Firebase using EmberFire adapter. Pretty easy.

Now, in an ideal world, Firebase would trigger some kind of event and send out an email notifying our admin that the record has been created. But it’s not yet supported. We can use Amazon SES instead for this.

1. Sign up for an Amazon account

2. Verify the email address (check your email and click the link). Pay attention to the region, verification, prices and limits that are region specific.

3. By default, the basic account is in sandbox mode. Which means you can only send test emails to verified emails. Request a limit increase in order to be able to send emails en masse. Here is a more detailed documentation. I got mine approved to 50K emails per day within 24 hours (thanks Amazon)

4. Add AWS npm package npm install aws-sdk -s, and then add ember-browserify so we can access the npm package in the browser.

Here is the full contact.js controller:

import Ember from 'ember';
// because it's loading through browserify, we're preficing it with npm:
import AWS from 'npm:aws-sdk'
// It's recommended to keep all your API keys in the environment.js file
// and pass them through environment variables
import config from '../config/environment';

const ses = new AWS.SES({
  apiVersion: '2010-12-01',
  accessKeyId: config.aws.accessKeyId,
  "secretAccessKey": config.aws.secretAccessKey,
  "region": "us-east-1",
});

export default Ember.Controller.extend({
  actions: {
    sendContact() {
      
      // Grab submitted values
      const submittedForm = {
        name: this.get('name'),
        email: this.get('email'),
        company: this.get('company'),
        phone: this.get('phone'),
        message: this.get('message'),
        timestamp: new Date().getTime()
      };
      
      // Prepare values to send with email
      const emailParams = {
        Destination: { ToAddresses: [ 'EcmaStack <hello@ecmastack.com>' ] },
        Message: {
          Body: { Text: {
            Data: `${submittedForm.name} asks ${submittedForm.message}. You can contact them by email ${submittedForm.email} or phone ${submittedForm.phone}`,
            Charset: 'UTF-8' } },
          Subject: { Data: 'Contact Form', Charset: 'UTF-8' }
        },
        ReplyToAddresses: [submittedForm.email],
        Source: `${submittedForm.name} <hello@ecmastack.com>`, // this has to be verified email in SES
      };
      
      // Save the submitted form to Firebase
      const newContact = this.store.createRecord('contact', submittedForm);
      newContact.save().then(function(res) {});

      // Send submitted for as email using AWS SES
      // TODO: handle the error and failure with user friendly messages
      ses.sendEmail(emailParams, function(error, data) {
        if (error) {
           // handle error
        } else {
           // handle success
        }
      });

    }
  }
});

By combining PaaS like AWS, Firebase and others we can pick and choose what server side features we want to bring to our front end applications without maintaining the servers.




CFG