EnhancedMail / app.py
adriiita's picture
Update app.py
0098a2b verified
raw
history blame
7.82 kB
import os
import gradio as gr
from groq import Groq
import pandas as pd
from datetime import datetime
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
import json
from pathlib import Path
from typing import Dict, List, Optional
def initialize_email_client():
sendgrid_key = os.environ.get("SENDGRID_API_KEY")
sender_email = os.environ.get("SENDER_EMAIL")
if not sendgrid_key or not sender_email:
print("Warning: SendGrid configuration missing. Email sending will be disabled.")
return None
try:
return SendGridAPIClient(api_key=sendgrid_key)
except Exception as e:
print(f"Error initializing SendGrid client: {e}")
return None
class UserProfile:
def __init__(self, storage_path: str = "profiles.xlsx"):
self.storage_path = storage_path
self._ensure_storage_exists()
def _ensure_storage_exists(self):
if not Path(self.storage_path).exists():
df = pd.DataFrame(columns=['user_id', 'name', 'industry', 'background', 'target_audience'])
df.to_excel(self.storage_path, index=False)
def save_profile(self, profile_data: Dict) -> bool:
try:
df = pd.read_excel(self.storage_path)
profile_data['user_id'] = len(df) + 1
df = pd.concat([df, pd.DataFrame([profile_data])], ignore_index=True)
df.to_excel(self.storage_path, index=False)
return True
except Exception as e:
print(f"Error saving profile: {e}")
return False
class EmailTemplate:
def __init__(self, templates_path: str = "templates.json"):
self.templates_path = templates_path
self._ensure_templates_exist()
def _ensure_templates_exist(self):
if not Path(self.templates_path).exists():
default_templates = {
"sales_pitch": {
"subject": "Innovative Solutions for {company}",
"body": "Dear {name},\n\nI hope this email finds you well..."
},
"job_application": {
"subject": "Experienced {role} Application",
"body": "Dear {hiring_manager},\n\nI am writing to express my interest..."
}
}
with open(self.templates_path, 'w') as f:
json.dump(default_templates, f)
def get_template(self, template_name: str) -> Dict:
with open(self.templates_path, 'r') as f:
templates = json.load(f)
return templates.get(template_name, {})
class EmailGenie:
def __init__(self):
self.client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
self.sendgrid_client = initialize_email_client()
self.sender_email = os.environ.get("SENDER_EMAIL")
self.user_profile = UserProfile()
self.email_template = EmailTemplate()
def structure_info(self, info: str) -> str:
prompt = f"Please structure and summarize the following information about a person or company: {info}"
chat_completion = self.client.chat.completions.create(
messages=[{"role": "user", "content": prompt}],
model="llama-3.1-8b-instant",
)
return chat_completion.choices[0].message.content
def generate_email(self, template_name: str, context: Dict) -> str:
template = self.email_template.get_template(template_name)
structured_info = self.structure_info(context.get('recipient_info', ''))
prompt = f"""
Using the following template and information, create a personalized email:
Template: {template}
Sender: {context['sender_name']}
Recipient: {context['recipient']}
Subject: {context['email_subject']}
Recipient Information: {structured_info}
"""
chat_completion = self.client.chat.completions.create(
messages=[{"role": "user", "content": prompt}],
model="llama-3.1-8b-instant",
)
return chat_completion.choices[0].message.content
def preview_email(self, email_content: str) -> str:
return f"=== Email Preview ===\n\n{email_content}"
def send_email(self, to_email: str, subject: str, content: str) -> tuple[bool, str]:
if not self.sendgrid_client or not self.sender_email:
return False, "Email sending is not configured"
message = Mail(
from_email=self.sender_email,
to_emails=to_email,
subject=subject,
plain_text_content=content
)
try:
self.sendgrid_client.send(message)
return True, "Email sent successfully"
except Exception as e:
return False, f"Error sending email: {e}"
def create_interface():
emailgenie = EmailGenie()
with gr.Blocks(title="EmailGenie") as demo:
gr.Markdown("# EmailGenie: AI-Powered Email Outreach")
with gr.Tab("Profile Setup"):
name_input = gr.Textbox(label="Full Name")
industry_input = gr.Textbox(label="Industry")
background_input = gr.Textbox(label="Professional Background")
target_input = gr.Textbox(label="Target Audience")
save_profile_btn = gr.Button("Save Profile")
with gr.Tab("Generate Email"):
template_dropdown = gr.Dropdown(
choices=["sales_pitch", "job_application"],
label="Select Template"
)
subject_input = gr.Textbox(label="Email Subject")
recipient_input = gr.Textbox(label="Recipient Name/Company")
recipient_info = gr.Textbox(label="Recipient Information")
generate_btn = gr.Button("Generate Email")
preview_output = gr.Textbox(label="Email Preview", lines=10)
with gr.Tab("Send Email"):
recipient_email = gr.Textbox(label="Recipient Email")
send_btn = gr.Button("Send Email")
status_output = gr.Textbox(label="Status")
def save_profile(name, industry, background, target):
profile_data = {
"name": name,
"industry": industry,
"background": background,
"target_audience": target
}
success = emailgenie.user_profile.save_profile(profile_data)
return "Profile saved successfully!" if success else "Error saving profile"
def generate_email_handler(template, subject, recipient, info):
context = {
"sender_name": "Your Name", # Could be fetched from profile
"email_subject": subject,
"recipient": recipient,
"recipient_info": info
}
email_content = emailgenie.generate_email(template, context)
return emailgenie.preview_email(email_content)
def send_email_handler(email, content):
success, message = emailgenie.send_email(email, "Your Subject", content)
return message
save_profile_btn.click(
save_profile,
inputs=[name_input, industry_input, background_input, target_input],
outputs=gr.Textbox(label="Status")
)
generate_btn.click(
generate_email_handler,
inputs=[template_dropdown, subject_input, recipient_input, recipient_info],
outputs=preview_output
)
send_btn.click(
send_email_handler,
inputs=[recipient_email, preview_output],
outputs=status_output
)
return demo
if __name__ == "__main__":
demo = create_interface()
demo.launch()