Implementation of a notification system using AWS part 2 - Lambda function and AWS SES setup
INTRODUCTION In this post, we'll continue from where we left off and set up a Lambda function to process messages from the SQS queue and send emails using Amazon SES. Resources to be created Lambda AWS SES Step 1 Create a lambda function that consumes the messages from the sqs queue, processes it and send it to the receiver's email address or send it to a dead letter queue when faced with a problem. Choose Author from scratch Enter the function name emailNotificationFunction Under runtime, choose python from the dropdown list Then click on create function. This will automatically create an IAM role. Follow the steps below to see the role created and to also update the policy to what is required. Click on the function you just created to see the overview. Scroll down a bit, click on the configuration tab. On the left pane, click on permissions. Locate the execution role and click on the link under the role name to take you to the role created. You will see a policy name that starts with AWSLambdaBasicExecutionRole-. Edit it with the permission below and save it. { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:REGION:ACCOUNT_ID:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:REGION:ACCOUNT_ID:log-group:/aws/lambda/emailNotificationFunction:*" ] }, { "Effect": "Allow", "Action": [ "sqs:ReceiveMessage", "sqs:GetQueueAttributes", "sqs:DeleteMessage" ], "Resource": [ "arn:aws:sqs:REGION:ACCOUNT_ID:emailNotificationQueue" ] }, { "Effect": "Allow", "Action": "ses:SendEmail", "Resource": "*" } ] } Leave everything else as it is. We will update it later. Check the images below for pictorial reference EMAIL SETUP The next thing we will doing is to setup the email address that our notification will go to. Once you have your email address handy, head over to the step below to verify your email address. SUBSCRIPTION Subscribe lambda to SQS Click on the sqs queue you created, scroll down a bit and click on the lambda triggers tab. Click on configure lambda function trigger, choose your lambda function from the drop down or type in the lambda arn and click on save. See images below for reference LAMBDA FUNCTION LOGIC Step One: Write the code to process messages from the SQS queue and send emails using SES. Step Two: Deploy the function and test it to ensure it works correctly. Example lambda logic import json import logging import boto3 from botocore.exceptions import ClientError # Set up logging logger = logging.getLogger() logger.setLevel(logging.INFO) # Initialize SES client ses_client = boto3.client('ses', region_name='REGION-NAME') # Replace 'REGION-NAME' with the AWS region where SES is available SENDER = "Your Name " # Replace with your sender email CHARSET = "UTF-8" def send_email(to_email, subject, body): try: response = ses_client.send_email( Destination={ 'ToAddresses': [ to_email, ], }, Message={ 'Body': { 'Text': { 'Charset': CHARSET, 'Data': body, }, }, 'Subject': { 'Charset': CHARSET, 'Data': subject, }, }, Source=SENDER, ) except ClientError as e: logger.error(f"Failed to send email: {e.response['Error']['Message']}") return False else: logger.info(f"Email sent! Message ID: {response['MessageId']}") return True def process_message(message_body): try: msg = json.loads(message_body) except json.JSONDecodeError: logger.error(f"Failed to decode message: {message_body}") return try: message = json.loads(msg.get('Message')) except json.JSONDecodeError: logger.error(f"Failed to decode message: {msg.get('Message')}") return print(message) event_type = message.get('eventType') if event_type == 'UserRegistration': user_name = message.get('userName') email = message.get('email') if user_name and email: subject = "Welcome to Our Service!" body = f"Hello {user_name},\n\nThank you for registering with us.\n\nBest regards,\nYour Company" send_email(email, subject, body) else: logger.error(f"Missing userName or email in message: {message}")

INTRODUCTION
In this post, we'll continue from where we left off and set up a Lambda function to process messages from the SQS queue and send emails using Amazon SES.
Resources to be created
Lambda
AWS SES
Step 1
Create a lambda function that consumes the messages from the sqs queue, processes it and send it to the receiver's email address or send it to a dead letter queue when faced with a problem.
- Choose
Author from scratch
- Enter the function name
emailNotificationFunction
- Under
runtime
, choosepython
from the dropdown list - Then click on create function. This will automatically create an IAM role. Follow the steps below to see the role created and to also update the policy to what is required.
- Click on the function you just created to see the overview. Scroll down a bit, click on the configuration tab.
- On the left pane, click on permissions. Locate the execution role and click on the link under the role name to take you to the role created.
- You will see a policy name that starts with
AWSLambdaBasicExecutionRole-
. Edit it with the permission below and save it.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:REGION:ACCOUNT_ID:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:REGION:ACCOUNT_ID:log-group:/aws/lambda/emailNotificationFunction:*"
]
},
{
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:GetQueueAttributes",
"sqs:DeleteMessage"
],
"Resource": [
"arn:aws:sqs:REGION:ACCOUNT_ID:emailNotificationQueue"
]
},
{
"Effect": "Allow",
"Action": "ses:SendEmail",
"Resource": "*"
}
]
}
Leave everything else as it is. We will update it later.
Check the images below for pictorial reference
EMAIL SETUP
The next thing we will doing is to setup the email address that our notification will go to. Once you have your email address handy, head over to the step below to verify your email address.
SUBSCRIPTION
Subscribe lambda to SQS
- Click on the sqs queue you created, scroll down a bit and click on the lambda triggers tab.
- Click on configure lambda function trigger, choose your lambda function from the drop down or type in the lambda arn and click on save. See images below for reference
LAMBDA FUNCTION LOGIC
Step One: Write the code to process messages from the SQS queue and send emails using SES.
Step Two: Deploy the function and test it to ensure it works correctly.
Example lambda logic
import json
import logging
import boto3
from botocore.exceptions import ClientError
# Set up logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Initialize SES client
ses_client = boto3.client('ses', region_name='REGION-NAME') # Replace 'REGION-NAME' with the AWS region where SES is available
SENDER = "Your Name " # Replace with your sender email
CHARSET = "UTF-8"
def send_email(to_email, subject, body):
try:
response = ses_client.send_email(
Destination={
'ToAddresses': [
to_email,
],
},
Message={
'Body': {
'Text': {
'Charset': CHARSET,
'Data': body,
},
},
'Subject': {
'Charset': CHARSET,
'Data': subject,
},
},
Source=SENDER,
)
except ClientError as e:
logger.error(f"Failed to send email: {e.response['Error']['Message']}")
return False
else:
logger.info(f"Email sent! Message ID: {response['MessageId']}")
return True
def process_message(message_body):
try:
msg = json.loads(message_body)
except json.JSONDecodeError:
logger.error(f"Failed to decode message: {message_body}")
return
try:
message = json.loads(msg.get('Message'))
except json.JSONDecodeError:
logger.error(f"Failed to decode message: {msg.get('Message')}")
return
print(message)
event_type = message.get('eventType')
if event_type == 'UserRegistration':
user_name = message.get('userName')
email = message.get('email')
if user_name and email:
subject = "Welcome to Our Service!"
body = f"Hello {user_name},\n\nThank you for registering with us.\n\nBest regards,\nYour Company"
send_email(email, subject, body)
else:
logger.error(f"Missing userName or email in message: {message}")
else:
logger.warning(f"Unknown event type: {event_type}")
raise ValueError("Unknown EventType")
def lambda_handler(event, context):
for record in event['Records']:
message_body = record['body']
logger.info(f"Received message: {message_body}")
process_message(message_body)
return {
'statusCode': 200,
'body': json.dumps('Messages processed successfully!')
}
CONCLUSION
By following these steps, you've successfully created a Lambda function and set up Amazon SES to send email notifications. Your system is now ready to process messages and send emails based on the notifications received.