From ffa9565ab8aa540647b83319b0521cf768a512d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Rafael=20Siqueira?= Date: Wed, 3 Dec 2025 10:53:23 -0300 Subject: [PATCH] add check mx record --- .../app/events/batch/chunks_into_users.py | 1 - users-events/app/events/check_mx_record.py | 45 +++++++++++++++++++ users-events/template.yaml | 24 ++++++++++ .../tests/events/test_check_mx_record.py | 20 +++++++++ 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 users-events/app/events/check_mx_record.py create mode 100644 users-events/tests/events/test_check_mx_record.py diff --git a/users-events/app/events/batch/chunks_into_users.py b/users-events/app/events/batch/chunks_into_users.py index c3fb1ff..52c0eb9 100644 --- a/users-events/app/events/batch/chunks_into_users.py +++ b/users-events/app/events/batch/chunks_into_users.py @@ -152,7 +152,6 @@ def _create_user(rawuser: dict, context: dict) -> None: 'sk': f'emails#{user.email}', 'email_verified': False, 'email_primary': True, - 'mx_record_exists': False, 'created_at': now_, } ) diff --git a/users-events/app/events/check_mx_record.py b/users-events/app/events/check_mx_record.py new file mode 100644 index 0000000..682acd7 --- /dev/null +++ b/users-events/app/events/check_mx_record.py @@ -0,0 +1,45 @@ +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_classes import ( + EventBridgeEvent, + event_source, +) +from aws_lambda_powertools.utilities.typing import LambdaContext +from email_validator import EmailUndeliverableError, validate_email +from layercake.dateutils import now +from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair + +from boto3clients import dynamodb_client +from config import USER_TABLE + +logger = Logger(__name__) +dyn = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client) + + +@event_source(data_class=EventBridgeEvent) +@logger.inject_lambda_context +def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: + new_image = event.detail['new_image'] + # Post-migration (users): rename `emails` to `EMAIL` + email = new_image['sk'].removeprefix('emails#') + + return dyn.update_item( + key=KeyPair( + pk=new_image['id'], + sk=new_image['sk'], + ), + update_expr='SET mx_record_exists = :bool, \ + updated_at = :now', + expr_attr_values={ + ':bool': _mx_record_exists(email), + ':now': now(), + }, + ) + + +def _mx_record_exists(email: str) -> bool: + try: + validate_email(email, check_deliverability=True) + except EmailUndeliverableError: + return False + else: + return True diff --git a/users-events/template.yaml b/users-events/template.yaml index d68281f..19beb0b 100644 --- a/users-events/template.yaml +++ b/users-events/template.yaml @@ -221,3 +221,27 @@ Resources: - prefix: EMAIL_VERIFICATION# welcome: - exists: false + + EventCheckMxRecordFunction: + Type: AWS::Serverless::Function + Properties: + Handler: events.check_mx_record.lambda_handler + LoggingConfig: + LogGroup: !Ref EventLog + Timeout: 12 + Policies: + - DynamoDBCrudPolicy: + TableName: !Ref UserTable + Events: + DynamoDBEvent: + Type: EventBridgeRule + Properties: + Pattern: + resources: [!Ref UserTable] + detail-type: [INSERT] + detail: + new_image: + sk: + - prefix: emails# + mx_record_exists: + - exists: false diff --git a/users-events/tests/events/test_check_mx_record.py b/users-events/tests/events/test_check_mx_record.py new file mode 100644 index 0000000..12ea165 --- /dev/null +++ b/users-events/tests/events/test_check_mx_record.py @@ -0,0 +1,20 @@ +from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext +from layercake.dynamodb import DynamoDBPersistenceLayer + +import events.check_mx_record as app + + +def test_check_mx_record( + lambda_context: LambdaContext, + dynamodb_persistence_layer: DynamoDBPersistenceLayer, +): + event = { + 'detail': { + 'new_image': { + 'id': '123', + 'sk': 'emails#sergio@somosbeta.com.br', + }, + }, + } + + assert app.lambda_handler(event, lambda_context) # type: ignore