Pythonからsendmail経由でメールを送信する
質問
SMTP 経由ではなく、sendmail 経由でメールを送信したい場合、このプロセスをカプセル化する Python のライブラリはありますか?
さらに良いことに、「sendmail 対 smtp」の選択全体を抽象化する優れたライブラリはありますか?
このスクリプトは多数の UNIX ホストで実行しますが、そのうちの一部だけが localhost:25; でリッスンしています。これらのいくつかは組み込みシステムの一部であり、SMTP を受け入れるように設定できません。
グッド プラクティスの一環として、ヘッダー インジェクションの脆弱性自体をライブラリに対処させたいと考えています。そのため、文字列をダンプするだけです。 popen('/usr/bin/sendmail', 'w')
私が望むよりも少し金属に近いです。
答えが「ライブラリを書きに行く」であるなら、それで構いません ;-)
解決
ヘッダー挿入はメールの送信方法の要素ではなく、メールの構築方法の要素です。チェックしてください Eメール パッケージ化して、それを使用してメールを作成し、シリアル化し、送信します。 /usr/sbin/sendmail
を使用して サブプロセス モジュール:
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
p.communicate(msg.as_string())
他のヒント
これは、UNIX の sendmail を使用してメールを配信する単純な Python 関数です。
def sendMail():
sendmail_location = "/usr/sbin/sendmail" # sendmail location
p = os.popen("%s -t" % sendmail_location, "w")
p.write("From: %s\n" % "from@somewhere.com")
p.write("To: %s\n" % "to@somewhereelse.com")
p.write("Subject: thesubject\n")
p.write("\n") # blank line separating headers from body
p.write("body of the mail")
status = p.close()
if status != 0:
print "Sendmail exit status", status
Jim の答えは Python 3.4 では機能しませんでした。さらに追加する必要がありました universal_newlines=True
に対する議論 subrocess.Popen()
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "me@example.com"
msg["To"] = "you@example.com"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True)
p.communicate(msg.as_string())
なしで universal_newlines=True
分かりました
TypeError: 'str' does not support the buffer interface
os.popen を使用して Python から sendmail コマンドを使用するのが非常に一般的です。
個人的には、自分で書いたものではないスクリプトについては、SMTP プロトコルを使用する方が良いと思います。Windows 上で実行するために、たとえば sendmail クローンをインストールする必要がないからです。
同じことを探していたところ、Python Web サイトで良い例を見つけました。 http://docs.python.org/2/library/email-examples.html
言及されたサイトから:
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.mime.text import MIMEText
# Open a plain text file for reading. For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(fp.read())
fp.close()
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()
これには、「localhost」での接続を受け入れるように sendmail/mailx が正しく設定されている必要があることに注意してください。これは私の Mac、Ubuntu、Redhat サーバーでデフォルトで機能しますが、問題が発生したかどうかを再確認することをお勧めします。
最も簡単な答えは smtplib です。ドキュメントは見つかります。 ここ.
あなたがする必要があるのは、localhost からの接続を受け入れるようにローカルの sendmail を設定することだけです。これはおそらくデフォルトですでに行われています。確かに、転送には引き続き SMTP を使用しますが、それはローカルの sendmail であり、基本的にコマンドライン ツールを使用するのと同じです。