fraud-detection-service-api / src /service /notification_service.py
SlimG's picture
improve logging
3dea1ba
raw
history blame
4.58 kB
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()