import logging import os from email import charset from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import boto3 from jinja2 import Environment, FileSystemLoader logger = logging.getLogger(__name__) charset.add_charset("utf-8", charset.SHORTEST, "8bit") # type: ignore CHARSET = "utf-8" def send_email(template_file, template_params, email_params, attach_images=None): """Uses AWS Simple Email Service to send emails. Renders template file with given parameters, and uses params from email_params dict to set subject and recipient. You can change sender to whatever verified email we need (anything with @fansifter.com domain). Some template advice: - https://github.com/leemunroe/responsive-html-email-template See SES options here - https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ses.html """ current_path = os.path.dirname(__file__) env = Environment(loader=FileSystemLoader(f"{current_path}/templates")) template = env.get_template(template_file) html = template.render(**template_params) client = boto3.client("ses", region_name="eu-west-1") try: if attach_images: msg = MIMEMultipart("mixed") msg["Subject"] = email_params.get("subject") msg["From"] = email_params.get("sender") msg["To"] = email_params.get("recipients") msg_body = MIMEMultipart("alternative") htmlpart = MIMEText(html, "html", CHARSET) htmlpart.replace_header("Content-Transfer-Encoding", "8bit") msg_body.attach(htmlpart) msg.attach(msg_body) for img_props in attach_images: img = MIMEImage( open(f"{current_path}/templates/{img_props['name']}", "rb").read() ) img["Content-ID"] = f"<{img_props['cid']}>" msg.attach(img) response = client.send_raw_email( Source=email_params.get("sender"), ReturnPathArn="arn:aws:ses:eu-west-1:776891437216:identity/hello@fansifter.com", Destinations=[email_params.get("recipients")], RawMessage={ "Data": msg.as_string(), }, # ConfigurationSetName=CONFIGURATION_SET ) else: response = client.send_email( Destination={ "ToAddresses": [ email_params.get("recipients"), ], }, Message={ "Body": { "Html": { "Charset": CHARSET, "Data": html, }, # 'Text': { # 'Charset': CHARSET, # 'Data': non_html, # }, }, "Subject": { "Charset": CHARSET, "Data": email_params.get("subject"), }, }, Source=email_params.get("sender"), ReplyToAddresses=["hello@fansifter.com"], ReturnPath="hello@fansifter.com" # ConfigurationSetName=email_params.get('configuration_set'), ) except Exception as e: logger.error("EXCEPTION", exc_info=e) else: logger.info(f"Email sent! Message ID: {response['MessageId']}"), if __name__ == "__main__": template_file = "alliance_invite.html" template_params = {"invite_link": "https://fansifter.com"} email_params = { "sender": "FanSifter@fansifter.com", "recipients": "kasparg@gmail.com", "subject": "FanSifter Data Alliance Invitation!", } send_email(template_file, template_params, email_params)