John Harlan, 11 months ago
Here is a basic Ruby on Rails application demonstrating exactly how to receive emails from an Amazon Web Services (AWS) Lambda process. This method works for any Rails app where you want users to be able to send emails into your Rails app.
We will begin with getting all the pieces in place in our AWS account for receiving emails, storing them in an S3 bucket, and setting up a Lambda function to post to our new Rails app.
First, you will need to create a standard S3 bucket with a custom configuration for SES to store emails. You can do this by:
You also have the option to save and test the function, which will be helpful in making sure everything is working in production once you get your Rails app deployed.
Setup the domain for which you want to receive email. CrateBind typically uses a subdomain so that it doesn't interfere with our normal company email @cratebind.com.
Next, you should also update your DNS record to point the subdomain MX records to SES. The Value field depends on the AWS region in which your SES domain was set up. For our account, we are using us-west-2 so our MX records would be as follows:
Lastly, you will create a new default rule in SES for how to process incoming messages.
Also, here are some additional instructions on setting up SES to receive emails if you get stuck: AWS SES Email Receiving Tutorial.
Create a basic model and controller that will receive the post response from AWS Lambda and save the email in the database.
We will use Webmock and stub data to test that we have the correct controller and model actions in place to process the data we receive from AWS Lambda. Our basic setup will be for our AWS Lambda function to store the incoming message in our S3 bucket and then post the message id to our Rails app. So, we will first build a class method in our Email model that takes the message_id and pulls the email from the S3 bucket, saving it to our database. We have created a example message that represents the text file saved by AWS SES to S3 and we will write a test that stubs this message from the get request to our S3 bucket in spec/models/email_spec.rb. This is the Webmock setting to stub the request to S3:
And this is the model method that we have built to handle the incoming messages:
Next, we will build a test to spec the controller action that receives the POST from AWS Lambda, validating the token and passing the message_id to the model method we just built and tested. The controller action looks like this. You obviously will want to create a different token than just 'test_token' and you will want to set it as an ENV variable.