feat: sns webhook

feat: text content type handler
feat: email blocking table
This commit is contained in:
2025-05-16 18:19:14 +05:30
parent 30f51618fe
commit 205e423b56
11 changed files with 383 additions and 16 deletions
+37 -3
View File
@@ -1,15 +1,23 @@
from database import get_db
import json
import urllib.request
from sqlalchemy.orm import Session
from services.jwtService import create_jwt_token
from services.userServices import UserServices
from models import BlockedEmail
from utils.password_utils import verify_password
from schemas.CreateSchemas import UserCreate
from schemas.BaseSchemas import AuthBase
from exceptions.unauthorized_exception import UnauthorizedException
from database import get_db
class AuthService:
def __init__(self):
self.user_service = UserServices()
self.db = next(get_db())
def login(self, data: AuthBase) -> str:
# get user
@@ -39,4 +47,30 @@ class AuthService:
"clinicId": response.created_clinics[0].id
}
token = create_jwt_token(user)
return token
return token
def blockEmailSNS(self, body: str):
# confirm subscription
if body["Type"] == "SubscriptionConfirmation":
urllib.request.urlopen(body["SubscribeURL"])
# disable automatic unsubscribe confirmation by activating subscription again
elif body["Type"] == "UnsubscribeConfirmation":
urllib.request.urlopen(body["SubscribeURL"])
# handle bounce notifications only
elif body["Type"] == "Notification":
msg = json.loads(body["Message"])
# check if msg contains notificationType
if "notificationType" not in msg:
return
recepients = msg["bounce"]["bouncedRecipients"]
for recipient in recepients:
blockEmail = BlockedEmail(email=recipient["emailAddress"], reason=msg["notificationType"], severity=msg["bounce"]["bounceType"])
self.db.add(blockEmail)
self.db.commit()
return "OK"
+103
View File
@@ -0,0 +1,103 @@
import dotenv
import json
dotenv.load_dotenv()
import os
import boto3
from logging import getLogger
logger = getLogger(__name__)
class EmailService:
def __init__(self):
self.client = boto3.client(
"ses",
region_name=os.getenv("AWS_REGION"),
aws_access_key_id=os.getenv("AWS_ACCESS_KEY"),
aws_secret_access_key=os.getenv("AWS_SECRET_KEY"),
)
self.senderEmail = os.getenv("AWS_SENDER_EMAIL")
def createTemplate(self):
"""Create or update email templates"""
try:
otp_template = {
"TemplateName": "sendOTP",
"SubjectPart": "Your OTP for login is {{otp}}",
"HtmlPart": """
<p>Dear User,</p>
<p>Thank you for using our service. To complete your authentication, please use the following one-time password (OTP):</p>
<p>OTP: {{otp}}</p>
<p>This OTP is valid for 15 minutes. Do not share this OTP with anyone for security reasons. If you did not request this OTP, please ignore this email.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p>
""",
"TextPart": "Dear User, Thank you for using our service. To complete your authentication, please use the following one-time password (OTP): OTP: {{otp}} This OTP is valid for 15 minutes. Do not share this OTP with anyone for security reasons. If you did not request this OTP, please ignore this email. Thank you, Team 24x7 AIHR"
}
new_clinic_template = {
"TemplateName": "newClinic",
"SubjectPart": "New Clinic Added",
"HtmlPart": """
<p>Dear Admin,</p>
<p>A new clinic has been added to the system.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p>
""",
"TextPart": "Dear Admin, A new clinic has been added to the system. Thank you, Team 24x7 AIHR"
}
reject_clinic_template = {
"TemplateName": "rejectClinic",
"SubjectPart": "Clinic Rejected",
"HtmlPart": """
<p>Dear User,</p>
<p>Your clinic {{name}} has been rejected.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p>
""",
"TextPart": "Dear User, Your clinic {{name}} has been rejected. Thank you, Team 24x7 AIHR"
}
apporve_clinic_template = {
"TemplateName": "apporveClinic",
"SubjectPart": "Clinic Approved",
"HtmlPart": """
<p>Dear User,</p>
<p>Congratulations! Your clinic {{name}} has been approved.</p>
<p>Thank you,<br/>Team 24x7 AIHR</p>
""",
"TextPart": "Dear User, Congratulations! Your clinic {{name}} has been approved. Thank you, Team 24x7 AIHR"
}
self.client.create_template(Template=otp_template)
self.client.create_template(Template=new_clinic_template)
self.client.create_template(Template=reject_clinic_template)
self.client.create_template(Template=apporve_clinic_template)
except Exception as e:
logger.error(f"Failed to create template: {e}")
raise Exception("Failed to create template")
def send_email(self, template_name: str, to_address: str, template_data: dict):
"""Send an email using a template"""
try:
response = self.client.send_templated_email(
Source=self.senderEmail,
Destination={
'ToAddresses': [to_address]
},
Template=template_name,
TemplateData=json.dumps(template_data),
ReplyToAddresses=[self.senderEmail]
)
logger.info(f"Email sent to {to_address} successfully. MessageId: {response['MessageId']}")
return response
except Exception as e:
logger.error(f"Error sending email to {to_address}: {str(e)}")
raise
def send_otp_email(self, email: str, otp: str):
"""Send OTP email"""
return self.send_email(
template_name="sendOTP",
to_address=email,
template_data={"otp": otp, "email": email}
)