thinkwelldesigns thinkwelldesigns - 2 months ago 6
Python Question

Reliably force Return-Path with Python

I'm a Python junior, so keep that in mind. In a Python script, I need to set a Return-Path address that is different than the sender's address. (I'm using Gmail as SMTP server.)

I've done lots of searching on this question and found plenty of "answers", but no solutions. I tried this link Setting Return-Path with Python sendmail for a MIME message but it's not working for me at all. I can change the "To:" address that the email recipient sees, but when they click "Reply", it's back to the sending email address again.

This is the function that I'm trying to write. It works well enough, except that I need to force a different Return-Path.

#!/usr/bin/python
import smtplib
import os

from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import sap_mailserverdata as sf

def send_mail(sent_to, subject, body_text, sent_from_addr='', sent_from_name='', files=[], cc=[], bcc=[]):
"""Send emails with or without attachments."""
assert type(sent_to)==list
assert type(files)==list
assert type(cc)==list
assert type(bcc)==list

message = MIMEMultipart()
message['From'] = sent_from_addr
message['To'] = COMMASPACE.join(sent_to)
message['Date'] = formatdate(localtime=True)
message['Subject'] = subject
message['Cc'] = COMMASPACE.join(cc)
message.preamble = 'You need a MIME enabled mail reader to see this message.\n'

message.attach(MIMEText(body_text, 'html'))

for f in files:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(f, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
message.attach(part)

addresses = []
for x in sent_to:
addresses.append(x)
for x in cc:
addresses.append(x)
for x in bcc:
addresses.append(x)

mail_server = smtplib.SMTP(sf.server, sf.server_port)
mail_server.ehlo()
mail_server.set_debuglevel(1)
mail_server.starttls()
mail_server.login(sf.username, sf.password)
mail_server.sendmail(sent_from_addr, addresses, message.as_string())
mail_server.quit()


What am I missing with this function to be able to reliably specify a different replyto Return-Path?

Answer

Reply-to and return path are two distinct beasts. See the RFC.

You can set Reply-to with:

msg['reply-to'] = 'smith@acme.com'

The return-path is set by the MTA to the address that receives bounces. It is controlled by the server administrator, so unless you work for Google I don't think this is under your control.

Most of the time one is after "Reply-to"; if you really need to change the return path you must use a SMTP server under your control and google for how to do this for the specific MTA you are using - many will have a white list of users and/or hosts that can override the return path.

Comments