import json from datetime import date, datetime from email.mime.application import MIMEApplication import requests from aws_lambda_powertools import Logger from aws_lambda_powertools.shared.json_encoder import Encoder from aws_lambda_powertools.utilities.data_classes import ( EventBridgeEvent, event_source, ) from aws_lambda_powertools.utilities.typing import LambdaContext from layercake.dateutils import now from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair from layercake.email_ import Message from boto3clients import dynamodb_client, sesv2_client from config import ( CERT_REPORTING_URI, EMAIL_SENDER, ENROLLMENT_TABLE, PAPERFORGE_API, USER_TABLE, ) SUBJECT = 'Certificados que vencerão em {month} na EDUSEG®' REPLY_TO = ('Carolina Brand', 'carolina@somosbeta.com.br') BCC = [ 'sergio@somosbeta.com.br', 'carolina@somosbeta.com.br', 'tiago@somosbeta.com.br', ] MESSAGE = """ Oi, tudo bem?

Em anexo você encontra os certificados que vencerão em {month}.

Qualquer dúvida, estamos à disposição. """ logger = Logger(__name__) enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client) user_layer = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client) @event_source(data_class=EventBridgeEvent) @logger.inject_lambda_context def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: old_image = event.detail['old_image'] # Key pattern `CERT#REPORTING#ORG#{org_id}` *_, org_id = old_image['id'].split('#') event_name = old_image['sk'] target_month = old_image['target_month'] pretty_month = _monthfmt(datetime.strptime(target_month, '%Y-%m').date()) now_ = now() r = enrollment_layer.collection.query( KeyPair( pk=old_image['id'], sk=f'MONTH#{target_month}#ENROLLMENT', ), limit=150, ) json_data = json.dumps( { 'template_uri': CERT_REPORTING_URI, 'args': { 'month': pretty_month, 'items': r['items'], }, }, cls=Encoder, ) # Send template URI and data to Paperforge API to generate a PDF r = requests.post(PAPERFORGE_API, data=json_data) r.raise_for_status() emailmsg = Message( from_=EMAIL_SENDER, to=_get_admin_emails(org_id), reply_to=REPLY_TO, bcc=BCC, subject=SUBJECT.format(month=pretty_month), ) emailmsg.add_alternative(MESSAGE.format(month=pretty_month)) attachment = MIMEApplication(r.content) attachment.add_header( 'Content-Disposition', 'attachment', filename=f'{target_month}.pdf', ) emailmsg.attach(attachment) try: sesv2_client.send_email( Content={ 'Raw': { 'Data': emailmsg.as_bytes(), }, } ) enrollment_layer.put_item( item={ 'id': old_image['id'], 'sk': f'{event_name}#EXECUTED', 'created_at': now_, } ) logger.info('Email sent') except Exception as exc: logger.exception(exc) enrollment_layer.put_item( item={ 'id': old_image['id'], 'sk': f'{event_name}#FAILED', 'created_at': now_, } ) return False else: return True def _get_admin_emails(org_id: str) -> list[tuple[str, str]]: # Post-migration: rename `admins` to `ADMIN` r = user_layer.collection.query(KeyPair(org_id, 'admins')) return [(x['name'], x['email']) for x in r['items']] def _monthfmt(dt: date) -> str: months = [ 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro', ] return f'{months[dt.month - 1]} de {dt.year}'