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"""

{subject}

{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()