import os import logging import smtplib import requests from datetime import datetime from email.message import EmailMessage from src.repository.common import get_session from src.repository.transaction_repo import fetch_transaction from dotenv import load_dotenv # Configure logging logger = logging.getLogger(__name__) # Load environment variables load_dotenv() SMTP_SERVER = os.getenv("SMTP_SERVER") SMTP_PORT = os.getenv("SMTP_PORT") SENDER_EMAIL = os.getenv("SENDER_EMAIL") RECEIVER_EMAIL = os.getenv("RECEIVER_EMAIL") SENDER_PASSWORD = os.getenv("SENDER_PASSWORD") BREVO_API_KEY = os.getenv("BREVO_API_KEY") B_USE_BREVO = os.getenv("USE_BREVO", "False").lower() == "true" and BREVO_API_KEY is not None # ------------------------------------------------------------------------------ def send_notification(transaction_id: int): """ Send a notification email when a transaction is detected as fraudulent. """ logger.info("Sending notification email...") # Fetch the transaction details from the database with get_session() as session: transaction = fetch_transaction(session, transaction_id) if transaction is None: logger.error(f"Transaction {transaction_id} not found") return if transaction.fraud_details.notification_sent: logger.info(f"Notification already sent for transaction {transaction_id}") return if not B_USE_BREVO: _send_with_smtp_server( transaction_number=transaction.transaction_number, fraud_score=transaction.fraud_details.fraud_score, model_version=transaction.fraud_details.model_version, ) else: # Alternatively, you can use Brevo (formerly Sendinblue) to send the email _send_with_brevo( transaction_number=transaction.transaction_number, fraud_score=transaction.fraud_details.fraud_score, model_version=transaction.fraud_details.model_version, ) logger.info("Email sent!") # Update the transaction details in the database transaction.fraud_details.notification_sent = True transaction.fraud_details.notification_recipients = RECEIVER_EMAIL transaction.fraud_details.notification_datetime = datetime.now() session.commit() def _build_notification_body( transaction_number: str, fraud_score: float, model_version: str, ) -> str: """ Build the body of the notification email. """ logger.debug("Building notification email body...") # Create the email body email_body = f"""

Fraud detected!

Please check the transaction.

""" return email_body def _send_with_smtp_server(transaction_number: str, fraud_score: float, model_version: str): # Create the email email_body = _build_notification_body( transaction_number=transaction_number, fraud_score=fraud_score, model_version=model_version, ) msg = EmailMessage() msg["Subject"] = "Fraud detected!" msg["From"] = SENDER_EMAIL msg["To"] = RECEIVER_EMAIL msg.set_content(email_body) # Send the email logger.debug(f"Connecting to SMTP server {SMTP_SERVER} using port {SMTP_PORT}...") with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server: server.starttls() # Secure the connection server.login(SENDER_EMAIL, SENDER_PASSWORD) server.send_message(msg) def _send_with_brevo(transaction_number: str, fraud_score: float, model_version: str): url = "https://api.brevo.com/v3/smtp/email" email_body = _build_notification_body( transaction_number=transaction_number, fraud_score=fraud_score, model_version=model_version, ) headers = { "accept": "application/json", "api-key": BREVO_API_KEY, "content-type": "application/json" } data = { "sender": {"name": "Fraud Detection Service", "email": SENDER_EMAIL}, "to": [{"email": RECEIVER_EMAIL}], "subject": "Fraud detected!", "htmlContent": email_body, } response = requests.post(url, headers=headers, json=data) response.raise_for_status()