Pythonのsmtplibを使用したメール送信

# Pythonのsmtplibを使用したメール送信

##1. 環境
    - Windows7
    - Python2.7.13
   
##2. やりたいこと
    - pythonを使用してメールを送信する
    - 宛先,Ccに複数人設定する
    - zipファイルを添付する
    - 添付ファイル名に日本語を使用する


##3. プログラムコード

``` python
import os.path
import datetime
import smtplib
import codecs, collections
import tempfile
import zipfileJPN as zipfile
import unittest, time, re, os, sys,datetime, shutil
import MimeWriter, mimetools, base64, StringIO

from email import Encoders
from email.Utils import formatdate
from email.MIMEBase import MIMEBase
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

def create_message(from_addr, from_addr_name, to_addr, cc_addr, subject, body, mime, attach_file):

    zf = tempfile.TemporaryFile(prefix='mail', suffix='.zip')
    zip = zipfile.ZipFile(zf, 'w')
    files = os.listdir(attach_file['path'])
    for i in files:
        filename =""
        filename=i
        zip.write(attach_file['path']+"/"+(filename.decode("cp932")).encode("cp932"))
    zip.close()
    zf.seek(0)

    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)

    attachment = MIMEBase(mime['type'],mime['subtype'])
    attachment.set_payload(zf.read())
    Encoders.encode_base64(attachment)
    msg.attach(attachment)
    attachment.add_header("Content-Disposition","attachment", filename=attach_file['name'])
    return msg

def send(from_addr, to_addrs, cc_addrs, msg):
    smtp = smtplib.SMTP("localhost:host")#要変更
    smtp.sendmail(from_addr, to_addrs+cc_addrs, msg.as_string())
    smtp.close()

if __name__ == '__main__':
    from_addr="test@account.com"
    from_addr_name = "テスト"
    to_addr = "distination@account.com,distination2@account.com"
    cc_addr = "distination_cc@account.com,distination_cc2@account.com"
    subject = u"テスト"
    body = u"テスト"
    mime={'type':'application', 'subtype':'zip'}
    attach_file={'name':'FileName.zip', 'path':'D://test/File'}
    msg = create_message(from_addr, from_addr_name, to_addr, cc_addr, subject, body, mime, attach_file)
    send(from_addr,to_addr_list, cc_addr_list, msg)

```
##4. 説明

###1. pythonを使用してメールを送信する

 - pythonのsmtplibを使用してメール送信を行った。
 - smtp = smtplib.SMTP("localhost:host")にsmtpサーバ名、ホスト記載
 - smtp.sendmail(送信メールアドレス,宛先メールアドレス,メールの中身)を記載し、送信することでメールを送ることができる


``` python 
def send(from_addr, to_addrs, cc_addrs, msg):
    smtp = smtplib.SMTP("localhost:host")#要変更
    smtp.sendmail(from_addr, to_addrs+cc_addrs, msg.as_string())
    smtp.close()
```


###2. 宛先,Ccに複数人設定する
- smtp.sendmail(from_addr, to_addrs+cc_addrs, msg.as_string())のto_addrs+cc_addrsに文字列で"abc@account.com,def@acount.com,ghi@account.com"のように記載する（宛先名をコンマ区切りで羅列した文字列）
- 宛先を誤って記載すると先頭のみに送られることがあるので注意が必要

###3. zipファイルを添付する
   
- 対象のフォルダ内にあるファイルをzip形式で書き込む
- MIMEタイプを設定し、添付ファイルとして設定する
- あらかじめzipファイルを作成し、MIMEタイプをzipに設定し送信を行ったが、送信はできたが、ファイルが壊れてしまうことがある
 
```python
  zf = tempfile.TemporaryFile(prefix='mail', suffix='.zip')
    zip = zipfile.ZipFile(zf, 'w')
    files = os.listdir(attach_file['path'])
    for i in files:
        filename =""
        filename=i
        zip.write(attach_file['path']+"/"+(filename.decode("cp932")).encode("cp932"))
    zip.close()
    zf.seek(0)

```

###4. 添付ファイル名に日本語を使用する
- python2.7のzipfile.write(ファイルパス)関数はUTF-8変換されてしまうので、そのまま、日本語のファイル名を使用するとファイルを特定することができない。
- ライブラリを変更し、新ライブラリとして作成し、インポートすることで対応する
- C:\Python27\Libの中のzipfile.pyをコピーし、新しい名前のファイルとして作成し、utf-8をcp932(Windowsの日本語文字コード)に変更し保存する。

```
import zipfileJPN as zipfile
```
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/192308/052551e0-d758-5d91-399c-3683f80cd3f2.png)