Listening to SES events

alt text

You will require the following AWS permissions:

  • lambda:AddPermission
  • s3:CreateBucket
  • lambda:CreateEventSourceMapping

 

Step 1: Create new lambda function

First, create a lambda function that will receive notifications about received emails, handler.js:

module.exports.emailReceived = (event, context, callback) => {
  console.log('EVENT', JSON.stringify(event));
  callback(null);
}

and serverless.yml:

functions:
  emailReceived:
    handler: handler.emailReceived

Now, we need to set up AWS SES service to save the emails we receive on particular domain. Note, that you need to own a domain name or subdomain and set your MX records to AWS. If you don't know what are MX records, check Wikipedia article and stackoverflow answer.

 

Step 2: Verify the new domain

Head to AWS SES service and verify a new domain if you haven't verified it yet. Amazon will walk you through what records are needed to be added for your domain in Route 53. new domain

Step 3: Create a new rule set

In the Rule Set section in AWS SES, Create a new Rule. Specify an email, for example test-email@your-domain.com new rule

Now, create two actions. One action should save all the new emails to S3 email bucket. You can create a new bucket for that. Second rule should invoke our newly created lambda - emaiReceived.

new action

In order to test that the lambda is actually invoked, you can use Dumptruck.

Launch it and send some dummy email to newly created email listener. Here is the sample output of what you'll see in dumptruck:

{
  "Records": [
    {
      "eventSource": "aws:ses",
      "eventVersion": "1.0",
      "ses": {
        "mail": {
          "timestamp": "2017-07-25T14:27:30.615Z",
          "source": "your-personal-email@gmail.com",
          "messageId": "xxxxxxxxxxxxxxxxxxxxxxxxx",
          "destination": [
            "test-email@your-domain.com"
          ],
          "headersTruncated": false,
          "headers": [
            // email headers here
          ],
        },
        "receipt": {
          "timestamp": "2017-07-25T14:27:30.615Z",
          "processingTimeMillis": 766,
          "recipients": [
            "test-email@your-domain.com"
          ],
          "spamVerdict": {
            "status": "PASS"
          },
          "virusVerdict": {
            "status": "PASS"
          },
          "spfVerdict": {
            "status": "PASS"
          },
          "dkimVerdict": {
            "status": "GRAY"
          },
          "action": {
            "type": "Lambda",
            "functionArn": "arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:serverless-hello-world-dev-emailReceived",
            "invocationType": "Event"
          }
        }
      }
    }
  ]
}

Note, that in Lambda function, you'll not find the email content itself. However, you can find the email topic in headers and also you can use ses.mail.messageId to retrieve the email file from emails folder. The link to the email file will be https://s3.amazonaws.com/YOUR_NEWLY_CREATED_BUCKET_NAME/emails/{Records[0].ses.mail.messageId}

Amazon SES provides you the raw, unmodified email, which is typically in Multipurpose Internet Mail Extensions (MIME) format.

If you need to get attachments from the file, you need to parse it yourself with your lambda. The specification of this format can be found here.