htmlamazon-web-servicesemailencodingutf

Why does my html email appear differently when sent by AWS SES?


I've been working on some custom html email templates. I'm having some trouble with my emails appearing differently when they are sent by different email services. I'm using AWS SES to send these emails to clients.

I've been using Postdrop to send test emails while I've been creating the template. Now that the AWS SES environment has been set up for my application, I can now send emails using the html template. The problem I'm getting is that when I send emails using AWS, the emails look different than they do when sent by Postdrop, even when viewing the email from the same email client.

I used a code checker to see how what the email client was receiving was different for each email sender, and they seem almost exactly the same, except for some Unicode(I think it's Unicode?) differences. The only differences I noted was that SES adds =E2=80=8B between certain sections of code, while Postdrop adds an empty line in place of that, and a short section of code where Postdrop included =2E at the start of some of the classes, where SES did not(This is the "External Class" section shown in the picture.) It seems like these are related to tab or end-line characters, but I'm not sure. There is other Unicode code used as well, but both emails use the same code in those sections.

Here is an example of the input code:

enter image description here

And here is what I'm getting from the different email senders:

enter image description here

These slight differences are causing the email sent by SES to appear incorrectly. Specifically, some of the media queries aren't working(while some still do), and there is additional spacing at the top.

In the header of the emails, both say they are being encoded by UTF-8, although the way it's phrased is slightly different.

Postdrop appears like this:

Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable

and SES appears like this:

Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

Not sure if that would affect anything. What is causing this issue, and how do I fix it?

Edit

Here is the code for the Lambda function that tells SES to send the email, but some of the identifying stuff(specific email addresses, amazon region, and file structure) have been removed just for safety:

import boto3
import logging
import os
import sys
from emailbody import body
from emailbodytext import bodytext
from botocore.exceptions import ClientError

def send_email(recipients):
    SENDER = "" # must be verified in AWS SES Email
    RECIPIENTS = recipients # must be verified in AWS SES Email

    AWS_REGION = ""

    # Create a new SES resource and specify a region.
    client = boto3.client('ses',region_name=AWS_REGION)

    # Try to send the email.
    try:
        #Provide the contents of the email.
        response = client.send_templated_email(
            Destination={
                'ToAddresses': RECIPIENTS,
            },
            Template='TemplateName',
            TemplateData = "{}",
            Source=SENDER
        )
    # Display an error if something goes wrong. 
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        print("Email sent! Message ID:"),
        print(response['MessageId'])

def delete_email_template(templateToDelete):
    
    AWS_REGION = ""
    
    # Create a new SES resource and specify a region.
    client = boto3.client('ses',region_name=AWS_REGION)
    
    # Try to get the email template.
    try:
        #Provide the contents of the email.
        response = client.delete_template(
            TemplateName=templateToDelete
        )
        return response

    # Display an error if something goes wrong. 
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        print(response['MessageId'])

def create_email_template():

    AWS_REGION = ""

    #The name for the template
    TEMPLATENAME = "Test"
    
    # The subject line for the email.
    SUBJECT = "Test Email"
    
    #The email body
    EMAILBODY = body
    
    #The email text
    BODYTEXT = bodytext
    
    # Create a new SES resource and specify a region.
    client = boto3.client('ses',region_name=AWS_REGION)

    #Provide the contents of the email.
    response = client.create_template(
        Template={
            'TemplateName': TEMPLATENAME,
            'SubjectPart': SUBJECT,
            'TextPart': BODYTEXT,
            'HtmlPart': EMAILBODY
        }
    )


def lambda_handler(event, context):
    emails = ['', '']
    create_email_template()
    send_email(emails)
    delete_email_template("Test")

Solution

  • I found the answer to the problem today, and it's a silly one. The issue has nothing to do with the code or AWS. The non-ASCII characters that are being added are from Slack! Apparently if you copy html from Slack's code viewer directly, it adds additional characters for styling, which also happen to be non-ASCII characters. That explains why the emails were showing up incorrectly, as well as why it appeared that it was an encoding issue.

    Thank you to everyone for all the additional contextual information.

    I'm sure I'm not the only one that this Slack issue has affected, so I will let Slack know about this bug.

    UPDATE: I contacted Slack and they already have this on the list of bugs to squash so hopefully a fix will come soon.