読者です 読者をやめる 読者になる 読者になる

pythonでメールを送信。。基本的な例 [ubuntu]

ウノウラボさんのpythonでメールを送るサンプル集を参考にしたのですが、自分の環境ではいまいち動かなかったところがあるので、基本的な例を修正してローカルから外部にメールを送るスプリクトを作成。

環境
Ubuntu 10.04
Python 2.6.5

以下、エラーとその修正です。

connect()がない

smtplib.SMTPServerDisconnected: please run connect() first

修正*1

 def send(from_addr, to_addr, msg):
     # SMTPの引数を省略した場合はlocalhost:25
     s = smtplib.SMTP()
+    s.connect() # 追加
     s.sendmail(from_addr, [to_addr], msg.as_string())
     s.close()

connection refused

socket.error: [Errno 111] Connection refused

対応:mailコマンドが無いのでインストールする。

sudo apt-get install mailutils

文法ミス

smtplib.SMTPSenderRefused: (501, '<root>: sender address must contain a domain', 'root')

対応:create_message()の第一引数には@とかドメインが必要。

-  from_addr = 'root'
+  from_addr = 'root@localhost'

外部にメールが飛ばない

Mailing to remote domains not supported

対応:eximの再構成*2

sudo dpkg-reconfigure exim4-config
> internet site; mail is sent and received directly using SMTP”を選択

で、できたスクリプトは次の通り。

# -*- coding: utf-8 -*-
import smtplib
from email.MIMEText import MIMEText
from email.Utils import formatdate

def create_message(from_addr, to_addr, subject, body):
    msg = MIMEText(body)
    msg['Subject'] = subject
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Date'] = formatdate()
    return msg

def send(from_addr, to_addr, msg):
    # SMTPの引数を省略した場合はlocalhost:25
    s = smtplib.SMTP()
    s.connect()
    s.sendmail(from_addr, [to_addr], msg.as_string())
    s.close()

if __name__ == '__main__':
    from_addr = 'root@localhost'
    to_addr = 'kmn23@example.com'
    msg = create_message(from_addr, to_addr, 'test subject', 'test body')
    send(from_addr, to_addr, msg)