Automating Email Sending with CloudWatch Events: Let Your Subscribers Choose the Time of Day They Receive Emails

Ram Potham
2 min readDec 29, 2022

--

Sending emails manually can be time-consuming and error-prone, especially if you have a large volume of emails to send. Fortunately, with the help of CloudWatch Events, you can automate the process of sending emails and let your subscribers choose the time of day they receive them.

Note this article follows from Automating Email Sending with Google Sheets, so please read that first!

When subscribers are added, a preference for their time will be noted so they will be added to a specific topic. You can also record this information in a DynamoDB or a similar service, but this article goes over how to use contact lists.

The lambda that adds emails to the contact list should be updated with:

time = int(event["queryStringParameters"]["time"])
topic = "Topic"+str(time % 12)

So the topic will include the hour of time they want emails to be sent.

Also, when emails are inserted into the queue, they must be filtered so that only emails with a preference of that time will be inserted:

topic = "Topic"+str(time % 12)
contact_list = ses.list_contacts(
ContactListName = "ContactList",
Filter = {
"FilteredStatus": "OPT_IN",
"TopicFilter": {
"TopicName": topic,
"UseDefaultIfPreferenceUnavailable": False
}
})

The event bridge rule should also be updated so that the lambda is executed at all possible times subscribers want their emails to be sent.

If you are doing this, I’d recommend creating another rule that can be cased on to increase the counter in the google sheets so that if you want an email to be sent to each subscriber every hour and the counter should increase by 1 every day, one rule would manage each.

You can do this by adding another rule as a trigger to the lambda that manages the google sheets that executes every day and the lambda only updates the counter when this rule is triggered.

I did this with the following code:

if (!event["update"]) {
const update = await sheets.spreadsheets.values.update({
auth: authToken,
spreadsheetId,
range: "Sheet1!F1",
valueInputOption: "USER_ENTERED",
resource: {
range: "Sheet1!F1",
majorDimension: "ROWS",
values: [[counter + 1]],
},
});
}

Where the update parameter is only set when the lambda is invoked and not set when the event bridge rule is triggered. So, invoking the lambda is updated to:

lambda_payload = {"update":"false"}
invoke_response = lambda_client.invoke(FunctionName=functionName,
InvocationType='RequestResponse',
Payload=bytes(json.dumps(lambda_payload),encoding='utf-8'))

Feel free to use your own implementation, but with this, subscribers can finally choose when they want emails to be sent!

Here is an implementation I’ve created.

--

--

Ram Potham

Founder. AWS certified expert. Web3 enthusiast. Yoga Teacher. Artificial Intelligence student at Carnegie Mellon University.