Send Automated Emails (smtplib & Python) Through Lambda
Tags: python, lambda, tutorial, codenewbie
Published: 2023-08-18 20:14:51

Hello there! I am so happy you're here and found my blog. I am new to the tech world and this is my very first project in AWS. It is a lovely beginner project especially if you have some Python skills up your sleeve, if not that's okay I will be sharing my code! This project took me through a whirlwind from CRON expressions to environmental variables- which are all new to me- and I am here to show you how I used them! I chose to set up an 8 a.m. email every Monday with some Monday Motivational Quotes. I've heard Lambda is an awesome, highly-used tool so what better way to learn it than to dive right in with a project? Lambda has a very generous free tier (1 million requests per month) and is relatively inexpensive so it is a good platform to play around with and discover the wonders of AWS.

I will admit this project took me longer than I would like to admit and so I would like to get this disclaimer out of the way: 

**This project, while run through Lambda, WILL NOT send emails to popular mail providers**

I learned this the hard way. I learned that because of previous spam abuse sent from EC2 instances, popular mail providers block emails coming from EC2 instances. However, AWS offers Simple Email Service to fix this issue, which is a fully managed service. Before learning this, I spent hours (and hours) of fixing my code, researching, watching youtube videos, reading the entire lambda documentation (ouch), reading through StackOverflows, and starting all over a few times, but I could not figure out why my code wasn't sending the emails even though it was running the tests perfectly. It was my first time on Lambda, so I didn't know if it was something in my code or a setting messed up or what: but I finally came across this blog @ [https://ivhani.medium.com/sending-an-email-with-aws-lamda-function-python-c4533aabf4af](url)
and Ivhani Maselesele explained this problem perfectly. So, I switched the receiving email in my code to my aol account and ran the test again and heard the ping of joy, the email was finally in my inbox. Thank you Ivhani!! 
If you are confused, don't worry I will explain what I am talking about when we get to that part. So, with that out of the way.. let's get started!

**1. Setting Up the Main Code**

I have been following along with Udemy's course "100 Days of Code: The Complete Python Pro Bootcamp for 2023" taught by Dr. Angela Yu. I originally got this course to supplement the "Python For Everybody" taught by Charles R. Severance (a really great, free course taught by an amazing instructor). I was only going to do a few days of the 100 Days of Code course, however I have been going consistently and am on day 32 and LOVE IT. It makes coding so fun and it is truly rewarding to see what you can create. Dr. Angela is amazing!! (DISCLAIMER: if you are interested in this course, they have REALLY great sales on Udemy and you shouldn't have to pay full price for anything)

With that being said, I got the Monday Motivation project idea from Dr. Angela. I challenge myself everyday by writing the code by myself and struggle through it(even if it takes more than 1 day) and only watch the videos for help, but the "quotes.txt" file is from Dr.Angela.

Below is my code before doing anything in AWS Lambda. This will send you an email with a quote from a file called "quotes.txt" if the day is equal to 1 (it is Tuesday, see 1e for notes about this).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bo5ee6td8cbb2ri89qau.png)

Noteworthy mentions:

a. I put "XXXXX" where it was my sensitive information and you should add your own sending email and receiving email should you wish to do this project. 


b. It is very important you recognize the password on line 6 is not your password to get into your email(most likely won't work), it is an _APP password_. This is because by default Gmail and other popular providers and picky about who can access your account, so if you want Python to send emails through your email account you have to set up an app password. I used a Gmail account on line 5 that I made just for this project, and I will show you how to set up an app password through Gmail. You can do this with other emails, it just might look a little different.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zff8celyi9uj477zaxtu.png)
At the top right, click your picture/ icon then click "Manage Your Google Account"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmfg4oe3hcen5lowsb65.png)
Then, click on Security then 2-Step Verification. Once you set up your 2-step Verification, click on 2-Step Verification again and scroll down until you see "App Passwords"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jajiswh12tavyofkk2ct.png)
Click on App Passwords. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5jieem381ck6f7jshtlm.png)
For Select App, choose other

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhe7vmxmb7yccq0w75h9.png)
Then name it anything you want, I chose MondayMotivation. Then click generate, and your app password should pop up. Copy this and insert this into line 6 of code.


c. On line 16, where I have "smtp.gmail.com", if you are using another email provider for your sender email (line 5), just google the smtp for that email provider and insert it there. (Just a funny mention- I was confused at first and thought the smtp was for the RECEIVING email so I set up all these for and in statements for another project with different email recipients and it took me hours figuring out why only Gmail was working and if @aol and @me etc didn't work for this project, I switched the port and added smtp_ssl too and realized... the 'smtp.gmail.com' is for the SENDING email aka I don't need to change it for each receiving email... facepalm)


d. This code as well as the final ending code is on my Github (link at bottom of page)


e. This is also important- I wrote the code assuming the code can run every day at 8 a.m. but will only send an email if it is Monday. That is why you see : if day_of_week == 1: ...
For reference:
0= Monday
6= Sunday
I tested this on different days, so you will see different numbers throughout this blog. Be sure whatever day of the week it is when you're doing this, you put it so you can test it and have that statement be true so it will send an email. I'll remind you at the end to change it back to Monday when we are all done.


f. The disclaimer mentioned at the beginning has to do with _receiving_ emails once we get to Lambda. Through VSCode or Pycharm etc, you should be able to send to any email.


h. Although not necessary, I recommend running this code in your favorite IDE just to make sure your passwords and emails are working.



**2.Setting Up Lambda**

a. Go to the AWS Lambda page and click create function. 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/apg7yar82u83rswx1dma.png)
I chose "Author From Scratch", a function name of your choosing, then be sure to select Python(I chose the latest right now which is 3.10), and I left the architecture as x86_64 and clicked create function.


b. Now, your screen should look like below if you click on the lamdba_function.py.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5zh02a4zaxllzu7zxjt.png)
This file is important as we will be incorporating it into our MondayMotivation.py file, as seen below.


c. Update your MondayMotivation.py file with accordance to the lamda_function.py file:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kb6pqey3oqg5sf5ndlt.png)


d. Now, we will zip our file.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zf18gtr8df2ibk2lpro.png)
I have the MondayMotivation.py and quotes.txt in a folder named "Mondays" and I compressed that folder into a zip by right clicking on the folder and selecting compress.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gjmxrt378bonf1cuez6o.png)
You are then going to upload this zip file into AWS Lambda by clicking 'Upload from' then selecting .zip and uploading your zip file.

I then edited around the folders within lambda so I have below.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta4m64ra6h4apaah4e7g.png)


e. This part is important. Scroll down to RunTime settings and click edit. We need to edit the Handler name. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/99zyjwzdiwjyt2ky24nc.png)
My .py file name is MondayMotivation2 and the def function is called lambda_handler within my .py file, so that is why my Handler info is like that above. Edit depending on your function name and .py file name.



**3.Setting Up CloudWatch Events**

Finally, let's set up a trigger so that Lambda will run this code. I would like this code to only run Monday's at 8 A.M.


a. 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czd7pct0r61e8o1zjd90.png)
Click the add trigger button in the function overview.


b. 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jvdh13dyb6df37vh7ufj.png)
This is the information that I put in for my CloudWatch Event rule. This was my first time dealing with cron expressions so I was very confused and appalled at this notation with the question marks and asterisks, but this website explains cron expressions very well.[https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html](url)
Edit the cron expression to when you want it to run. (NOTE- if you want to do every day etc, make sure you edit "if day_of_week == .. code within your code to correspond) Click add and that's it!



**4.Extra- Environment variables**
This was my first instance of dealing with environment variables and I am very pleasantly surprised with how awesome they are, so I highly recommend you follow along and do this, it is simple and easy and makes your code more adaptable and flexible so you can quickly make changes and adjust your functions behavior without messing up the code. I used environment variables for: my email, app password, and receiving email. So for example, if I wanted to change my receiving email, I would change it through the environment variables tab and not have to touch my function code. It is a good habit to get into, so let's get started. 


a. Click on the configuration tab, then click on environment variables and hit edit. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6sgna7u3ydqgat0g0ab.png)


b. Click add environment variables and add 3. I added it for my sender email, receiving email, and app password that was on my MondayMotivation2.py file. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uol7bcrj1bwz39yj4ma4.png)
 

c. Click save.


d. Now, go back to code, and we are going to edit our code within here to reflect our environment variables. Make sure to click deploy changes when done!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8pep6ucva8igtd1t0md.png)
I edited line line 7, 8, and 22 as well as added in line 4. REMEMBER- put a receiving email thats not popular(i.e. gmail won't work as the receiving email, but works great for the sending email. Aol works, check bottom of page for temporary email link that works)

Perfect, now you don't have sensitive information on the front of your Lambda.



**5.Time To Run**
We will now set up a test event and run our code through Lambda.


a. Set up a test by clicking the blue test box
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcrlg0s3c923yzugdpr7.png)
I kept everything the same and just added a name. Click save.


b. Before clicking test, remember to have the day_of_week == to the day it is today. (see 1e)


c. Click test, and you should get a succeeded status in the execution results tab like below with a "Hello From Lambda" and a nice motivational quote in your email. Once you're done, switch the day_of_week back equal to 0 (Monday) and deploy your changes and you're good to go!

REMEMBER: It only works for receiving emails that still allow this. It did not work for my gmail but it worked for my aol account, but this could change. If you are getting a successful execution but no email, your email provider probably blocked it. You can use a website such as [https://internxt.com/temporary-email](url) , where you can get temporary access to an email and inbox and I have found this works as of now.


And that is it! I added the before code(without the Lambda function incorporation and environment variables- as it is seen in step 1), the final code, and the quotes.txt file into a GitHub repository @ [https://github.com/andreapeterson/AWSLambda-SMTPLIB-Python](url)

Good luck! Let me know if you try it.

For an extra challenge: Have Lambda run code that will run once a day and send an email if it is someones birthday. I uploaded my code to the same Github repository. Hint: this might be useful if you plan to use Pandas:[https://stackoverflow.com/questions/63421063/unable-to-import-pandas-in-aws-lambda-layer](url)