tc-agent / tools /email_tool.py
togitoon's picture
Improve the promt for sending email always
186f97f
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
from strands import tool
from config.settings import settings
from typing import Dict, Union
import logging
logger = logging.getLogger(__name__)
@tool(
name="send_notification_email",
description="Sends HTML email notifications about Topcoder challenges to registered users"
)
def send_email(to: str, html_content: str, subject: str) -> Dict[str, Union[str, list]]:
"""Send an email notification about relevant Topcoder challenges using SendGrid.
This tool handles the complete email delivery process including validation,
formatting, and error handling. It uses the configured SendGrid API to send
HTML-formatted challenge notifications to registered users.
Args:
to: The recipient's email address (must be a valid email format)
html_content: The HTML-formatted content of the email notification
subject: The subject line for the email notification
Returns:
Dictionary with status and content indicating success or failure details
"""
logger.info(f"Attempting to send email to {to} with subject: '{subject}'")
# Validate required configuration
if not settings.SENDGRID_API_KEY:
error_msg = "SENDGRID_API_KEY environment variable is not set. Please configure SendGrid API key."
logger.error(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg}
]
}
if not settings.SENDGRID_FROM_EMAIL:
error_msg = "SENDGRID_FROM_EMAIL is not configured. Please set the sender email address."
logger.error(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg}
]
}
# Validate input parameters
if not to or "@" not in to:
error_msg = f"Invalid recipient email address: {to}"
logger.error(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg}
]
}
if not html_content.strip():
error_msg = "Email content cannot be empty"
logger.error(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg}
]
}
if not subject.strip():
error_msg = "Email subject cannot be empty"
logger.error(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg}
]
}
# Construct the email message
try:
message = Mail(
from_email=settings.SENDGRID_FROM_EMAIL,
to_emails=to,
subject=subject,
html_content=html_content
)
except Exception as e:
error_msg = f"Failed to construct email message: {str(e)}"
logger.error(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg}
]
}
# Send the email via SendGrid API
try:
sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
response = sg.send(message)
# Check response status
if response.status_code in [200, 201, 202]:
success_msg = f"Email sent successfully to {to}"
logger.info(f"{success_msg}. SendGrid status: {response.status_code}")
return {
"status": "success",
"content": [
{"text": success_msg},
{"json": {
"recipient": to,
"subject": subject,
"status_code": response.status_code,
"message_id": response.headers.get("X-Message-Id", "N/A")
}}
]
}
else:
error_msg = f"SendGrid returned unexpected status code: {response.status_code}"
logger.warning(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg},
{"json": {"status_code": response.status_code, "response_body": str(response.body)}}
]
}
except Exception as e:
error_msg = f"Error sending email to {to}: {str(e)}"
logger.error(error_msg)
return {
"status": "error",
"content": [
{"text": error_msg}
]
}