Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automated Email System #1439

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Email Automation Script

This Python script automates the process of sending personalized emails with attachments to multiple recipients. It reads recipient information from an Excel file and uses a Gmail account to send the emails.

## Prerequisites

1. Python 3.x installed on your system
2. A Gmail account with 2-Step Verification enabled
3. An App Password for your Gmail account

## Setup

### Gmail Account Configuration

1. **Enable 2-Step Verification**:
- Go to your [Google Account](https://myaccount.google.com/).
- Select "Security" from the left menu.
- Under "Signing in to Google," select "2-Step Verification" and follow the steps to turn it on.

2. **Create an App Password**:
- After enabling 2-Step Verification, go back to the [Security](https://myaccount.google.com/security) page.
- Under "Signing in to Google," select "App Passwords" (you may need to sign in again).
- At the bottom, choose "Select app" and pick "Mail" or "Other (Custom name)".
- Choose "Select device" and pick "Other (Custom name)".
- Enter a name for the app password (e.g., "Email Automation Script") and click "Generate".
- Google will display a 16-character app password. **Copy this password** as you'll need it for the `.env` file.

### Script Setup

1. Clone or download this repository to your local machine.

2. Install the required Python packages:
```
pip install pandas python-dotenv
```

3. Create a `.env` file in the same directory as the script and add the following parameters:

```
EMAIL=your_email@gmail.com
EMAIL_PASSWORD=your_app_password
SENDER_NAME=Your Name
RECEIVER_EMAIL_FILE=path/to/your/excel/file.xlsx
EMAIL_CONTENT_FILE=path/to/your/email_content.txt
ATTACHMENT_FILE=path/to/your/attachment.pdf
```

Replace the values with your actual information.

4. Prepare your Excel file (`RECEIVER_EMAIL_FILE`) with at least one column named 'Email' containing the recipient email addresses.

5. Create your email content file (`EMAIL_CONTENT_FILE`) with the body of your email.

6. Ensure your attachment file (`ATTACHMENT_FILE`) is in the specified location.

## Usage

Run the script using Python:

```
python email_automation_script.py
```

The script will send emails to all recipients listed in the Excel file and print the status of each email sent.

## Troubleshooting

- If you encounter a "Login Error," double-check that you're using the correct App Password in your `.env` file.
- Ensure all file paths in the `.env` file are correct and the files exist.
- If emails are not being sent, check your Gmail account for any security alerts or login attempt notifications.

## Security Note

Never share your `.env` file or commit it to version control systems. It contains sensitive information that should be kept private.
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import os
import smtplib
import pandas as pd
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from dotenv import load_dotenv
from email.utils import formataddr

# Load environment variables from .env file
load_dotenv()

# Read email content from file
def read_email_content(file_path):
try:
with open(file_path, 'r') as file:
return file.read()
except FileNotFoundError:
raise FileNotFoundError(f"Email content file not found: {file_path}")
except IOError:
raise IOError(f"Error reading email content file: {file_path}")

# Attach file to email
def attach_file(msg, file_path):
try:
with open(file_path, "rb") as attachment:
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', f'attachment; filename={os.path.basename(file_path)}')
msg.attach(part)
except FileNotFoundError:
raise FileNotFoundError(f"Attachment file not found: {file_path}")
except IOError:
raise IOError(f"Error reading attachment file: {file_path}")

# Main execution
try:
excel_file = os.getenv('RECEIVER_EMAIL_FILE')
df = pd.read_excel(excel_file)

email = os.getenv('EMAIL')
sender_name = os.getenv('SENDER_NAME')
password = os.getenv('EMAIL_PASSWORD')

if not password:
raise ValueError("Email password not found in environment variables")

sent_from = formataddr((sender_name, email))
subject = 'Research Internship Application'

# Read email content from file
email_content_file = os.getenv('EMAIL_CONTENT_FILE')
text = read_email_content(email_content_file)

file_path = os.getenv('ATTACHMENT_FILE')

smtpserver = smtplib.SMTP_SSL('smtp.gmail.com', 465)
smtpserver.ehlo()
smtpserver.login(email, password)

for index, row in df.iterrows():
try:
msg = MIMEMultipart()
sent_to = row['Email']

msg['From'] = sent_from
msg['To'] = sent_to
msg['Subject'] = subject

body = text

msg.attach(MIMEText(body, 'plain'))

attach_file(msg, file_path)

message = msg.as_string()

smtpserver.sendmail(email, sent_to, message)
print(f"Email sent successfully to {sent_to}")
except smtplib.SMTPException as e:
print(f"Failed to send email to {sent_to}. Error: {str(e)}")
except Exception as e:
print(f"An error occurred while processing email for {sent_to}. Error: {str(e)}")

except FileNotFoundError as e:
print(f"File not found error: {str(e)}")
except IOError as e:
print(f"IO error: {str(e)}")
except pd.errors.EmptyDataError:
print("The Excel file is empty.")
except Exception as e:
print(f"An unexpected error occurred: {str(e)}")
finally:
try:
smtpserver.quit()
except:
pass # If the server connection wasn't established, this will fail silently

print("Email sending process completed.")
Loading