Search code examples
pythonemailsmtptwistedmime

How can I get email.utils.formataddr to show a sender name with twisted.mail.smtp.sendmail?


When I use the standard smtplib.SMTP.sendmail function, I can call it using email.utils.formataddr(senderName, local-part@domain) as the from_addr to show the sender's name in an email client.

When I use twisted.mail.smtp.sendmail to do the same, instead of senderName showing up, I get local-part.

So far I've only tested this in Gmail, but since that's what my company uses, it's part of my requirement.

I've tried sending the formatted address via twisted.mail.smtp.sendmail and get a parse error.

I've used twisted.mail.smtp.quoteaddr, but discovered that just strips the formatted name and address back down to the address. No parsing error though.

        #print('populate the message')
        msg = MIMEMultipart('alternative')
        msg["Subject"] = 'A Subject'
        msg["From"] = email.utils.formataddr(('Sender Name', 'noreply@example.com'))
        msg["Reply-to"] = 'noreply@example.com'
        msg["To"] = 'recipient@example.com'
        content = MIMEText("Hey, what's up?" ,"html")
        msg.attach(content)
        msg_timeout = round(float(30))

        # create the sender and send it
        result = twisted.mail.smtp.sendmail("mail-sc", msg["From"], msg["To"].split(","), msg,
                     port=25, requireAuthentication=False)

getting this error Failure: twisted.mail._except.AddressError: Parse error at ' ' of ('"Sender Name" ', [' ', '<','noreply', '@','sender', '.','com', '>'])


Solution

  • There is more than one standard and syntax for "email addresses". The standard and syntax for the address used by SMTP is (currently) RFC 5321. This is the kind of address you pass to twisted.mail.smtp.sendmail. The standard and syntax for the address used by MIME is (currently) RFC 5322. This is the kind of address you put into a MIME message for the sender, recipient, cc, etc.

    RFC 5321 addresses don't have a sender name component. RFC 5322 addresses do. I expect that email.utils.formataddr is returning a valid RFC 5322 address and it is correct to put this into msg["From"]. However, you must pass RFC 5321 addresses to twisted.mail.smtp.sendmail. Roughly, these are in the format noreply@example.com.