GIANT Stories at MongoDB

Sending Email From Your Frontend Application Using MongoDB Stitch and AWS SES

Aydrian Howard

mongodb

Email is king of communication. Most grandparents have an email account, so if you are looking for a communication channel with the most coverage, it’s going to be email. But sending an email from an application is not fun. Many transactional email services, for security reasons, will not allow you to make a request to their APIs from a front end application. This requires you to support a backend application to handle these transactions. If you are looking to host a simple Contact Form or share content from your website, setting up a Node.js application, configuring REST routes with Express.js, and deploying that somewhere would be overkill.

The built-in AWS service from MongoDB Stitch makes it easy to send a transactional email using the Simple Email Service (SES). Just add the AWS service, configure SES, and use the Stitch client to execute the AWS SES request right from your React.js application. I created the following function in a recent Stitchcraft live coding session on my Twitch channel.

share = async (entry, email) => {
  const args = {
    Destination: {
      ToAddresses: [email]
    },
    Message: {
      Body: {
        Html: {
          Charset: 'UTF-8',
          Data: `
              <h1>Enjoy this pic!</h1>
              <img src="${entry.url}" />
              `
        }
      },
      Subject: {
        Charset: 'UTF-8',
        Data: `Picture shared by ${entry.owner_name}`
      }
    },
    Source: 'picstream@ses.aydrian.me'
  }

  const request = new AwsRequest.Builder()
    .withService('ses')
    .withAction('SendEmail')
    .withRegion('us-east-1')
    .withArgs(args)
    .build()

  return this.aws.execute(request)
}

With these few lines of code, I was able to take an image, stored in S3 and email it to the specified email. Wasn’t able to see it live? Watch the recording on YouTube with the Github repo in the description. Follow me on Twitch to join me and ask questions live.

-Aydrian Howard
Developer Advocate
NYC
@aydrianh

Reacting to Auth Events using Stitch Triggers

Aydrian Howard

mongodb

MongoDB Stitch makes it easy to add authentication to your application. Several authentication providers are available to be configured using the Stitch Admin Console. Recently, authorization triggers were added to Stitch. Functions can now be executed based on authorization events such as user creation, deletion, and login.

During my Stitchcraft live coding sessions, I’ve been creating an Instagram-like application that uses Google Authentication. The Google authentication provider can be configured to return metadata with the authenticated user. I set up my provider to retrieve the user’s email, name, and profile picture. This works well as long as only the authenticated users need to see it. If you want other users to be able to access this data, you’re going to have to write it to a collection. Before authorization triggers, this could have been an arduous task.

Now it’s as simple as executing a function to perform an insert on the CREATE operation. Because I wanted to also ensure that the data in this collection stayed up-to-date, I created authorization triggers for CREATE and LOGIN and pointed them to a single upsert function as seen below.

exports = function(authEvent) {
  const mongodb = context.services.get("mongodb-atlas");
  const users = mongodb.db('data').collection('users');

  const { user, time } = authEvent;

  const newUser = {
    user_id: user.id,
    last_login: time,
    full_name: user.data.name,
    first_name: user.data.first_name,
    last_name: user.data.last_name,
    email: user.data.email,
    picture: user.data.picture
  };

  return users.updateOne({user_id: user.id}, newUser, {upsert: true});
};

During the last Stitchcraft session, I set up this authorization trigger and a database trigger that watched for changes to the full_name field. Check out the recording with the GitHub repo linked in the description. Follow me on Twitch and be notified of future Stitchcraft live coding sessions.

-Aydrian Howard
Developer Advocate
NYC
@aydrianh

Creating your first Stitch app? Start with one of the Stitch tutorials.

Want to learn more about MongoDB Stitch? Read the white paper.

Handling Files using MongoDB Stitch and AWS S3

Aydrian Howard

mongodb

MongoDB is the best way to work with data. As developers, we are faced with design decisions about data storage. For small pieces of data, it’s often an easy decision. Storing all of Shakespeare’s works, all 38 plays, 154 sonnets, and poems takes up 5.6MB of space in plain text. That’s simple to handle in MongoDB. What happens, however, when we want to include rich information with images, audio, and video? We can certainly store that information inside the database, but another approach is to leverage cloud data storage. Services such as AWS S3 allow you to store and retrieve any amount of data stored in buckets and you can store references in your MongoDB database.

With a built-in AWS Service, MongoDB Stitch provides the means to easily update and track files uploaded to an S3 bucket without having to write any backend code. In a recent Stitchcraft live coding session on my Twitch channel, I demonstrated how to upload a file to S3 and record it in a collection directly from a React.js application. After I added an AWS Service (which just required putting in IAM credentials) to my Stitch application and set up my S3 Bucket, I only needed to add the following code to my React.js application to handle uploading my file from a file input control:


handleFileUpload(file) {
 if (!file) {
   return
 }

 const key = `${this.client.auth.user.id}-${file.name}`
 const bucket = 'stitchcraft-picstream'
 const url = `http://${bucket}.s3.amazonaws.com/${encodeURIComponent(key)}`

 return convertImageToBSONBinaryObject(file)
   .then(result => {
     // AWS S3 Request
     const args = {
       ACL: 'public-read',
       Bucket: bucket,
       ContentType: file.type,
       Key: key,
       Body: result
     }

     const request = new AwsRequest.Builder()
       .withService('s3')
       .withAction('PutObject')
       .withRegion('us-east-1')
       .withArgs(args)
       .build()

     return this.aws.execute(request)
   })
   .then(result => {
     // MongoDB Request
     const picstream = this.mongodb.db('data').collection('picstream')
     return picstream.insertOne({
       owner_id: this.client.auth.user.id,
       url,
       file: {
         name: file.name,
         type: file.type
       },
       ETag: result.ETag,
       ts: new Date()
     })
   })
   .then(result => {
     // Update UI
     this.getEntries()
   })
   .catch(console.error)
}

To watch me put it all together, check out the recording of the Stitchcraft live coding session and check out the link to the GitHub repo in the description. Be sure to follow me on Twitch and tune in for future Stitchcraft live coding sessions.

-Aydrian Howard
@aydrianh
Developer Advocate
NYC