How I created a Photo Booth with AWS Serverless
Tags: aws, showdev, serverless
Published: 2021-07-08 22:29:36

## Intro

This is how I built a photo booth application with AWS Serverless services.

Once user capture an image and provide an email, background of the image is removed and new background applied and watermark with timestamp will be added. Then the image will be emailed to the given email address.

Below tools and technologies are used to built this.

Backend:
* AWS Lambda with runtime Node.js
* Step Function
* S3
* SES
* [remove.bg API](https://www.remove.bg/api)

Frontend:
* [VueJS](https://vuejs.org/)
* [vue-web-cam plugin](https://www.npmjs.com/package/vue-web-cam)
* Hosted on [Amplify web hosting](https://aws.amazon.com/amplify/hosting)

IAC:
* [Serverless Framework](https://www.serverless.com/)


## Architecture

![Serverless PhotoBooth Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/07pwh3dzxz8lfhpyx9py.png)


## How It Works

1. In the frontend VueJS app (hosted in Amplify), first a image will be captured with the email address. 

2. Then the app will request for pre-signed url.

3. Captured image will be uploaded to S3 with the pre-signed url and the email address as a meta data.

4. Once the image is uploaded, Init lambda function will be triggered to initialise step function execution.

5. Within the Step Function execution, first the background of the image will be removed. For this, I use remove.bg external service.

6. Then, a new background will be applied to the image. This background must be in the 'backgrounds' path of the S3 bucket.

7. As the next step, watermark will be added with the timestamp.

8. Finally, the image will be sent to the given email address using AWS Simple Email Service (SES).

![Steps](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oensram3ngm5h4lv24ja.png)


## How to set up

### Prerequisites
* AWS cli
* Serverless Framework cli
* yarn & jq installed
* Create a free account at [remove.bg](https://www.remove.bg/api) and generate a API token.
* Set up and verified SES send email address

#### Deployment

1. Clone the repository: [https://github.com/pubudusj/photo-booth](https://github.com/pubudusj/photo-booth)

2. Copy `.env.example` to `.env` and fill in with the appropriate values.

3. Run 
```
make install && make deploy
```

This will create the backend stack and make the frontend deployment bundle ready.

#### Frontend

1. Once step 3 above is finished, you can deploy the frontend code in `frontend/dist/frontend.zip` easily with Amplify web hosting. Of course if you use amplify, you can configure your own custom domain quite easily as well.

2. If you need to run the frontend in local, navigate to frontend directory and run `yarn run serve`

#### To Delete the stack

To remove the backend, run `make down`.

** Make sure the s3 directory created in the stack is empty before run this command.

## Demo
You may check the live demo at [https://photobooth.pubudu.dev](https://photobooth.pubudu.dev)

## Key points/Lessons learnt

1. Here I used remove.bg external tool to remove background, because it doesn't need for example green background to extract the foreground objects. I don't have any affiliation with this service and there are lot of other alternatives as well. Please select any service you prefer and you will need to modify the `removeBackground` lambda accordingly.

2. I have used Step Functions general workflows here, but using express workflow also a good option.


3. I have NOT implemented any error handling in this project since this is just a POC, but in general, you need to address failure scenarios. Refer error handling with Step Functions [here](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html).

4. This is the first time I used [Serverless Optimize Plugin](https://www.npmjs.com/package/serverless-plugin-optimize) and surprised how easy it is to bundle the packages only relevant to each lambda functions.

5. As the email service, I have used AWS's own Simple Email Service (SES). However, you need to first verify your sending email address in order to send emails to any address. This can be done with a support request. Optionally you can use any other email service provider and you have to modify the `sendEmail` lambda accordingly.

6. In this project, I don't use any database to record the data that goes through the system. I use s3 object meta data to record the email address entered by user to send out the email. 

7. vue-web-cam is simply awesome plugin for VueJS to get camera input into your application. You have option to select the preferred video source if you have multiple.

## Feedback
Your valuable feedback on this project is mostly welcome! I would like you to play around with this and if you have any questions or general comments, please reach out to me via [LinkedIn](https://www.linkedin.com/in/pubudusj/), [Twitter](https://twitter.com/pubudusj) or [Github](https://github.com/pubudusj).

Keep building, keep sharing!

** _Cover Photo by <a href="https://unsplash.com/@grievek1610begur?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Kevin Grieve</a> on <a href="https://unsplash.com/s/photos/photo-booth?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>_