前提:2系(2.7)
Pythonで作ったバッチ処理の通知用にメール送信処理を作ってみたら、思った送信先に送信されなかったという話。
やったこと
smtplibのsendmail関数を使って、以下の要領で複数の送信先に対してメール送信しようとしていた。
cset = 'utf-8'
msg = MIMEMultipart()
msg["Subject"] = subject
msg["From"] = from_addr_name+"<"+from_addr+">"
msg["To"] = to_addr # 複数送信先の場合は,区切りで入力されていることを期待
msg["Cc"] = cc_addr # 複数送信先の場合は,区切りで入力されていることを期待
msg["Date"] = formatdate()
body = MIMEText(body.encode("utf-8"), 'plain', 'utf-8')
msg.attach(body)
# 送信処理
smtp = smtplib.SMTP(smtp_server)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(login_id, login_password)
smtp.sendmail(from_addr, to_addr+cc_addr, msg.as_string())
smtp.close()
間違ってた
上記だととりあえずメールは送信されるのだが、Toの先頭にしかメールが送信されていなかった。
テスト/調査の感じだと、msg["To"] やmsg["Cc"]に設定したものはメール文面の表示にしか使用されていない模様。
で、実際の送信先についてはsendmail()の第二引数にリストで渡すことで複数送信先に送信できるようになっている模様。
つまり
sendToList=to_addr.split(',')+cc_addr.split(',')
smtp.sendmail(from_addr, sendToList, msg.as_string())
のようにしてあげる必要があった。
msgはカンマ区切りでもいいけど、sendmailはリストじゃないとダメってめんどくさい仕様だな。
※ちなみに後から考えると
仮にカンマ区切りで複数に送信できるとしても
smtp.sendmail(from_addr, to_addr+cc_addr, msg.as_string())
だとToの最後とCcの先頭がカンマで区切られていないのでどちらにしてもダメだったような気がする。
参考
サンプル
ConfigParserを使ってsetting.iniファイルから設定情報を取得。
ファイルの添付などは無し。
# -*- coding: utf-8 -*-
import smtplib
from email.Utils import formatdate
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
class SendMail(object):
# メールの作成
@staticmethod
def SendMessage(subject, body):
import ConfigParser
inifile = ConfigParser.SafeConfigParser()
inifile.read('./setting.ini')
# 設定ファイル内でメール送信実施の制御を行えるようにしている。
if inifile.get('Debug', 'SendFlg') == "False":
print("[Debug Mode] No Send Mail")
return
from_addr=inifile.get('Address', 'fromAddress')
from_addr_name = inifile.get('Address', 'fromAddressName')
to_addr = inifile.get('Address', 'toAddress') # 複数送信先の場合は,区切りで入力されていることを期待
cc_addr = inifile.get('Address', 'ccAddress') # 複数送信先の場合は,区切りで入力されていることを期待
# SMTP
smtp_server = inifile.get('Address', 'SMTP_SERVER')
login_id = inifile.get('Address', 'fromAddress') # 送信元アドレスでログインすることになる
login_password = inifile.get('Address', 'SMTP_Pass')
cset = 'utf-8'
msg = MIMEMultipart()
msg["Subject"] = subject
msg["From"] = from_addr_name+"<"+from_addr+">"
msg["To"] = to_addr
msg["Cc"] = cc_addr
msg["Date"] = formatdate()
body = MIMEText(body.encode("utf-8"), 'plain', 'utf-8')
msg.attach(body)
# 送信処理
smtp = smtplib.SMTP(smtp_server)
smtp.ehlo()
smtp.starttls()
smtp.ehlo
smtp.login(login_id, login_password)
sendToList=to_addr.split(',')+cc_addr.split(',')
smtp.sendmail(from_addr, sendToList, msg.as_string())
smtp.close()
# smtp.quit()
添付ファイルも送りたかったら、msgにattachしてあげれば送れるはず。
追記
上記のサンプルを別の環境にもっていって、使ってみたら動かなくていくつか調整が必要だった。
まず、
- ログイン等が不要なSMTPサーバだった。
- SMTPサーバからのレスポンスがないコマンドがあった
ということで、いくつかの部分を適当にコメントアウトして使える状態にした。