import smtplib
import pandas as pd
import time
import openpyxl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import formataddr
import streamlit as st
import os
import base64
# Set Streamlit app title and page configuration
st.set_page_config(page_title="Email Sender and Tracker", layout="wide")
# Email Sender Function
def send_email(server, sender_email, sender_password, receiver_email, subject, email_content):
message = MIMEMultipart()
message["From"] = formataddr(("AI Consultant", sender_email))
message["To"] = receiver_email
message["Subject"] = subject
email_content_formatted = email_content.replace("\n", "
")
html_content = f"""
{email_content_formatted}
"""
# Attach the logo image
logo_path = "AIConsultantBlackSmall.png"
with open(logo_path, "rb") as logo_file:
logo_image = MIMEImage(logo_file.read())
logo_image.add_header("Content-ID", "")
message.attach(logo_image)
message.attach(MIMEText(html_content, "html"))
email_message = message.as_string().encode("utf-8")
try:
server.sendmail(sender_email, receiver_email, email_message)
return True
except smtplib.SMTPException:
return False
# Main Function
def main():
st.title("Email Sender and Tracker")
# Sidebar Inputs
sender_email = st.sidebar.text_input("Your Email")
sender_password = st.sidebar.text_input("Your Email Password", type="password")
subject = st.sidebar.text_input("Subject")
email_content = st.sidebar.text_area("Email Content", height=400)
# Recipients File Selection
recipients_file_path = st.sidebar.file_uploader("Select Excel file with recipient emails", type=["xlsx", "xls"])
# Send Button
if st.sidebar.button("Send"):
if not sender_email or not sender_password or not subject or not email_content:
st.warning("Incomplete Information. Please fill in all the required fields.")
elif not recipients_file_path:
st.warning("Missing Recipients File. Please select an Excel file with recipient emails.")
else:
st.info("Sending emails...")
df = pd.read_excel(recipients_file_path)
receiver_emails = df.iloc[:, 0].tolist()
successful_emails = []
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
try:
server.login(sender_email, sender_password)
except smtplib.SMTPAuthenticationError:
st.error("Authentication Failed. Username and password not accepted.")
return
progress_bar = st.progress(0)
progress_text = st.empty()
for i, receiver_email in enumerate(receiver_emails[:1000], 1): # Send at most 200 emails from the list
if send_email(server, sender_email, sender_password, receiver_email, subject, email_content):
successful_emails.append(receiver_email)
time.sleep(0.1) # Delay between sending emails
progress_bar.progress(i / 1000)
progress_text.text(f"Sending email {i}")
st.success("Emails sent successfully!")
# Save Successful Emails
if successful_emails:
try:
workbook = openpyxl.Workbook()
worksheet = workbook.active
for email in successful_emails:
worksheet.append([email])
# Specify the custom file name
custom_file_name = "successful_emails.xlsx"
excel_file_path = custom_file_name
workbook.save(excel_file_path)
workbook.close()
# Get the absolute file path
absolute_file_path = os.path.abspath(excel_file_path)
# Rename the file
new_file_name = "successful_emails.xlsx"
os.rename(absolute_file_path, new_file_name)
st.info(f"Successful emails saved to Excel file: {new_file_name}")
# Add button to save or download the Excel file
download_button_str = create_download_button(new_file_name, new_file_name)
st.markdown(download_button_str, unsafe_allow_html=True)
except Exception as e:
st.error(f"Error saving successful emails: {str(e)}")
else:
st.warning("No successful emails to save.")
# Helper function to create download button HTML string
def create_download_button(file_path, file_name):
button_str = f'Download Successful Emails'
return button_str
# Helper function to encode the file to base64
def get_base64_encoded(file_path):
with open(file_path, "rb") as file:
encoded = base64.b64encode(file.read()).decode()
return encoded
# Run the Streamlit app
if __name__ == "__main__":
main()