How to send email messages using AWS Simple Email Service?

Business photo created by creativeart - www.freepik.com


Business photo created by creativeart – www.freepik.com

Even after lowering the power consumption of our IoT device, we anticipated of course, that there will be a moment when the battery finally will need to be recharged/replaced.
How to remind the user about the task that he will have to perform in not that near future?
Since we are already sending data to AWS we decided to measure the battery level and send that info along. Then on AWS, we’ve set up a lambda function that analyses reported battery voltage, and if it drops below some predefined level, an automatic email notification is sent to a specified list of recipients.

So this post is about how to send automatic notification emails using AWS.

Setting up AWS SES (Simple Email Service)

To send an email from a specific address or domain first, this email/domain must be verified (if a domain has been verified all addresses from that domain are verified).
To verify – means to claim that the domain you wish to use for your email sender is actually yours. This involves generating a “Domain Verification Record” (we can think of it as a specific hash) for a specified domain on the SES side and pasting them on the domain’s DNS provider side. This is, of course, a mean to prevent misuse of the service.

Good step by step description on how to verify a domain in AWS SES console can be found here: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/verify-domain-procedure.html

Sending emails using AWS Lambda

How?

The following example will send a message with the subject “This is a test” to address “test@test.com”. The sender of this email will be visible as  “from@test.com”:

import boto3
client = boto3.client('ses')
client.send_email(
        Source=”from@test.com”,
        Destination={
            'ToAddresses': [“teset@test.com”],
        },
        Message={
            'Subject': {
                'Data': “This is a TEST”,
                'Charset': 'UTF-8'
            },
            'Body': {
                'Html': {
                    'Data': “This is a test body”,
                    'Charset': 'UTF-8'
                }
            }
        }
    )

This is a minimal example with at least one recipient, a subject, and a simple Html body.
More about send_email function parameters can be found here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ses.html#SES.Client.send_email

When?

Our lambda is triggered when an MQTT message is published to a specific topic. All data from this MQTT message is then processed by the function, battery voltage with it. 
Threshold levels and a list of email addresses that the notification will be sent to is stored in a database, and it is unique for every IoT device. This way we can easily manage a different group of devices in the same database.

Adding permissions

To successfully send an email, Lambda must be granted appropriate permissions. This policy example lists minimal permissions needed to send emails:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ses:SendEmail",
        "ses:SendRawEmail"
      ],
      "Resource": "*"
    }
  ]
}

Going out of the sandbox = sending to unverified email addresses

As a default, for all new accounts, SES enables sending emails only to verified addresses. This includes also some other limitations, like limiting the number of emails sent per day, etc.
To be able to send emails to unverified email addresses your account needs to be moved out of a sandbox. This process involves opening a case “SES Sending Limits Increase” in AWS Support Center. Processing the request may take up to 24 hours. During this time AWS Support Team verifies your request.
More information about this step: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html

Now we can safely leave our devices out in the field, and they will notify their owners when it is time to recharge!