email_assistant / tools.py
abdullahtahir's picture
Update tools.py
1f873ae verified
import os
from typing import Type
from dotenv import load_dotenv
from pydantic import BaseModel, Field
from crewai.tools import BaseTool
# Try importing sendgrid with fallback
try:
import sendgrid
from sendgrid.helpers.mail import Mail
SENDGRID_AVAILABLE = True
print("βœ… SendGrid package imported successfully")
except ImportError:
SENDGRID_AVAILABLE = False
print("❌ SendGrid package not available - add 'sendgrid' to requirements.txt")
# Load environment variables
load_dotenv()
class SendEmailInput(BaseModel):
sender_email: str = Field(..., description="The email address of the visitor sending the message.")
subject: str = Field(..., description="A concise subject line for the email.")
body: str = Field(..., description="The main content of the email, formatted professionally.")
class SendEmailTool(BaseTool):
name: str = "SendEmailTool"
description: str = "Sends an email using the SendGrid API."
args_schema: Type[BaseModel] = SendEmailInput
def _run(self, sender_email: str, subject: str, body: str) -> str:
print("πŸš€ Starting SendGrid email process...")
# Check if sendgrid is available
if not SENDGRID_AVAILABLE:
return "❌ Error: SendGrid package not installed. Add 'sendgrid' to requirements.txt and redeploy."
# Get environment variables
api_key = os.getenv("SENDGRID_API_KEY") or os.environ.get("SENDGRID_API_KEY")
verified_sender = os.getenv("VERIFIED_SENDER_EMAIL") or os.environ.get("VERIFIED_SENDER_EMAIL")
receiver_email = os.getenv("RECEIVER_EMAIL") or os.environ.get("RECEIVER_EMAIL")
# Debug info
print(f"πŸ” Debug Info:")
print(f" - SendGrid API Key present: {bool(api_key)}")
print(f" - Verified sender present: {bool(verified_sender)}")
print(f" - Receiver email present: {bool(receiver_email)}")
print(f" - Contact sender: {sender_email}")
# Check required variables
if not api_key:
return "❌ Error: SENDGRID_API_KEY not found in environment variables."
if not verified_sender:
return "❌ Error: VERIFIED_SENDER_EMAIL not found in environment variables."
if not receiver_email:
return "❌ Error: RECEIVER_EMAIL not found in environment variables."
# Validate API key format
if not api_key.startswith('SG.'):
return f"❌ Error: Invalid SendGrid API key format. Should start with 'SG.' but starts with '{api_key[:5]}'."
try:
# Initialize SendGrid
sg = sendgrid.SendGridAPIClient(api_key=api_key)
print("βœ… SendGrid client initialized")
# Create HTML content (fix f-string backslash issue)
formatted_body = body.replace('\n', '<br>').replace(chr(10), '<br>')
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; }}
.header {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px; }}
.content {{ background: #f8f9fa; padding: 20px; border-radius: 8px; margin: 10px 0; }}
.message {{ background: white; padding: 15px; border-left: 4px solid #667eea; margin: 15px 0; }}
</style>
</head>
<body>
<div class="header">
<h1 style="margin: 0;">πŸ“§ New Portfolio Contact</h1>
</div>
<div class="content">
<p><strong>From:</strong> <a href="mailto:{sender_email}">{sender_email}</a></p>
<p><strong>Subject:</strong> {subject}</p>
<div class="message">
<h3>Message:</h3>
{formatted_body}
</div>
<hr>
<p style="color: #666; font-size: 12px;">
This message was sent through your portfolio contact form.<br>
Reply to this email to respond directly to {sender_email}
</p>
</div>
</body>
</html>
"""
# Create message
message = Mail(
from_email=verified_sender,
to_emails=receiver_email,
subject=f"Portfolio Contact: {subject}",
html_content=html_content
)
message.reply_to = sender_email
print(f"πŸ“§ Prepared email:")
print(f" - From: {verified_sender}")
print(f" - To: {receiver_email}")
print(f" - Reply-to: {sender_email}")
# Send email
print("πŸ“€ Sending via SendGrid...")
response = sg.send(message)
print(f"πŸ“¨ Response: Status {response.status_code}")
if response.status_code == 202:
return f"βœ… Email sent successfully via SendGrid! (Status: {response.status_code})"
elif response.status_code == 401:
return "❌ SendGrid Error: Invalid API key"
elif response.status_code == 403:
return "❌ SendGrid Error: Permission denied - check sender email verification"
else:
return f"⚠️ SendGrid Response: Status {response.status_code}"
except Exception as e:
error_msg = str(e)
print(f"❌ SendGrid Error: {type(e).__name__}: {error_msg}")
if "Unauthorized" in error_msg or "401" in error_msg:
return "❌ SendGrid: Invalid API key"
elif "Forbidden" in error_msg or "403" in error_msg:
return "❌ SendGrid: Sender email not verified or insufficient permissions"
else:
return f"❌ SendGrid Error: {error_msg}"