Search code examples
pythongmail-apiemail-headers

Problem sending utf-8 display name in Gmail API


So I have a function which I use to send emails through Gmail API:

def send_email(payload, messagesubject, sendtoaddresses, key_file_path: str, subject: str):
    messagedraft = MIMEText(payload, "plain")
    mailservice = build_mail_service(key_file_path, subject)
    messagedraft["From"] = f"Display name <{subject}>"
    messagedraft["Subject"] = messagesubject
    for address in sendtoaddresses.split(","):
        if "To" in messagedraft:
            del messagedraft["To"]
        messagedraft["To"] = address
        message = {"raw": urlsafe_b64encode(messagedraft.as_bytes()).decode()}
        mailservice.users().messages().send(userId="me", body=message).execute()

And everything works well aside from the fact that if the "Display name" in the "From" field has a utf-8 character it gets omitted and only the email address shows up in the header.

I've tried various encoding settings found throughout the internet and stackoverflow but nothing has fixed it. The only thing that works is when I change the utf-8 character into ascii

I'm trying to understand why this problem shows up and how I can fix this behaviour.


Solution

  • While inspecting the documentation linked by tripleee Problem sending utf-8 display name in Gmail API I was struck by a new idea and replaced MIMEText class with EmailMessage class. Below is the solution that worked for me for future reference.

    def send_email(payload, messagesubject, sendtoaddresses, key_file_path: str, subject: str):
        messagedraft = EmailMessage()
        messagedraft.set_payload(payload)
        mailservice = build_mail_service(key_file_path, subject)
        messagedraft.add_header("From", f"Display name <{subject}>")
        messagedraft.add_header("Subject", messagesubject)
        messagedraft.add_header("To", "")
        for address in sendtoaddresses.split(","):
            messagedraft.replace_header("To", address)
            message = {"raw": urlsafe_b64encode(messagedraft.as_bytes()).decode()}
            mailservice.users().messages().send(userId="me", body=message).execute()