Spaces:
Running
Running
| 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"""<div> | |
| <h1>Fraud detected!</h1> | |
| <ul> | |
| <li>Transaction number: {transaction_number}</li> | |
| <li>Fraud score: {fraud_score}</li> | |
| <li>Model version: {model_version}</li> | |
| </ul> | |
| <p>Please check the transaction.</p> | |
| </div>""" | |
| 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() |