PythonでOutlookメール送受信と受信メール管理の自動化

※記事内に広告が含まれる場合があります。
Pythonでメール送受信を自動化 テクノロジー
スポンサーリンク

Pythonを利用してMicrosoftのOutlook(365も)からメールを自動送信する方法とメール受信内容を自動的に取得し、一覧化やディレクトリに保存する方法のご紹介です。

・日次で大量にメールを送受信する必要がある。
・同じメール内容で宛先だけが違う。
・固定分のルーチン作業を自動化に置き換えたい

上記の手作業を実際のPythonコードをご紹介しながら解説致します。

スポンサーリンク

自動メール送受信の概要

PythonからOutlookを操作する

PythonからOutlookを操作する方法はいくつかありますが今回はライブラリのemail.messageを利用します。私が知っているなかで一番簡単で確実に動くのがemail.messageだからです。

メール送信 添付ファイルあり・なし

今回はメール送信時に添付ファイルがない&添付ファイルがあるの両方のパターンをご紹介します。

必要ライブラリのインストール

必要に応じてライブラリのインストールを行います。

pip install emailmessage
pip install secure-smtplib

もしpipでインストールできない場合proxyや証明書の問題がありますのでPythonのpip installが使えない時のプロキシとSSL無視の記事をご覧くださいませ。

Pythonから自動メール送信

outlookメール送信(添付ファイルなし)関数

まずはメール送信の関数共有です。

from email.message import EmailMessage
import smtplib

def EmaiSend(user,password_1,message_from,message_to,message_cc,message_subject,message_text):

    #認証定義とパスワード(Smtpサーバー接続)
    user=user
    password=password_1
    smtp = smtplib.SMTP("smtp.office365.com",ポート番号を入力)

    #メッセージ
    message = EmailMessage()
    message["From"] = message_from
    message["To"] = message_to
    message["Cc"] = message_cc
    message["Subject"] = message_subject
    message.set_content(message_text)
 
    #Smtpサーバー接続とメール送信
    smtp.ehlo()
    smtp.starttls()
    smtp.ehlo()
    smtp.login(user,password_1)
    smtp.send_message(message)
    smtp.quit()

    return

Pythonからoutlookメール送信

上記関数の変数を例をもちいて入力してみました。

#メール本文
message_text='''
この度は2つむじ次郎のブログへお越しいただきありがとうございます。
Pythonノウハウ共有はお役に立ててますでしょうか?
'''
#題名
message_subject="2つむじ次郎のブログ練馬ライフへようこそ"

#メールサーバー
user = "送信元のメールアドレス"
password_1= "パスワード入力" 大抵はwindowspass違う場合はメール設定を確認
message_from=user 
message_to ="toでの送り先記載"
message_cc="ccでの送り先記載"

#送り先を複数入れたい場合は"****","****"のようにカンマで区切る

変数定義ができたら関数を実行するとメール送信ができます。

EmaiSend(user,password_1,message_from,message_to,message_cc,message_subject,message_text)

宛先を変えながら同じ内容を送信したい場合はループ文で対応します。

for i in data:
    
    message_to = "送り先の変数をいれる i[?]"
    message_subject = "送り先の変数をいれる i[?]" 
    
    EmaiSend(user,password_1,message_from,message_to,message_cc,message_subject,message_text)

例えばエクセルやcsvファイルに宛先を入れてループするなどです。

上記を応用することで宛先だけでなくメール本文や題名などをエクセルで変えれば特定の相手に違うメッセージを送ることも可能ですので使う用途が広がると思いませんか?

自動メール送信(添付ファイルなし)関数

メールの添付用コード(追加部分)の部分らへんが添付ファイルロジックで追加したところです。

from email.message import EmailMessage
import smtplib

def EmaiSend(user,password_1,message_from,message_to,message_cc,message_subject,message_text,file,filename):

    #認証定義とパスワード(Smtpサーバー接続)
    user=user
    password=password_1
    smtp = smtplib.SMTP("smtp.office365.com",ポート番号を入力)

    #メッセージ
    message = EmailMessage()
    message["From"] = message_from
    message["To"] = message_to
    message["Cc"] = message_cc
    message["Subject"] = message_subject
    message.set_content(message_text)


    #メールの添付用コード(追加部分)
    #ファイルを指定
    attach_file={"name":filename,"path":file}
    #テキスト形式を指定
    mine = {"type":"text","subtype":"comma-separated-values"}
    file = open(attach_file["path","rb"])
    file_read = file.read()

    #条件指定
    message.add_attachment(file_read,maintype=mine["type"],subtype=mine["subtype"],filename=attach_file["name"])
    file.close()

 
    #Smtpサーバー接続とメール送信
    smtp.ehlo()
    smtp.starttls()
    smtp.ehlo()
    smtp.login(user,password_1)
    smtp.send_message(message)
    smtp.quit()

    return

ファイルpathとファイル名を指定すればメール送信が可能ですので変数を指定して実行すればメールが送られます。

Pythonでメールの開封&受信確認

メールを送信するだけでなく相手が受信や開封したのを確認したい場合のコードです。

#メールの開封確認
if disposition_notification_address and disposition_notification_address !="":
    message["Disposition-Notification-To"] = disposition_notification_address

コードに上記を追加すれば開封確認ができるようになります。

disposition_notification_addressは開封メールの送付先なので開封確認を見たい方のアドレスを指定してください。ほぼ自分になると思いますが。

Pythonで受信メールのデータ自動取得

受信メールのデータを自動取得するメリット

・とあるメールを受信したら次の自動作業をする
・受信メールに添付されているデータを違う場所に保管する
やろうと思えばでてきます。

本記事ではアウトルックメールの受信ディレクトリの特定サブディレクトリからデータを引っ張ってきて一覧化による可視化とデータの保存を行うコードをご紹介致します。

利用ライブラリ(win32com,subprocess)

Officeのoutlookメールの受信操作で使うライブラリです。必要に応じてinstall願います。

pip install pywin32
pip install subprocess

Pythonからメール受信するコード

対象のsubディレクトリの内容を取得(関数)

def target_inbox(account_name,sub_dir_nama):
    
    outlook = Dispatch("Ootlook.Application").GetNamespace("MAPI")

    accounts=outlook.Folders
    for account in accounts:

        #複数アカウントの中でどのアカウントを利用するのかaccount_nameの曖昧検索
        if re.findall(account_name,str(account )):
            folders=account.Folders

            #対象アカウント名の受信メール内のサブディレクトリを指定
            for folder in folders:
                if re.findall("受信トレイ",str(folder)):
                    inbox = folder.Folders(sub_dir_nama)
                    all_inbox = inbox.Items

    return all_inbox

テキストを保存するための関数

def text_save(textWrite,outpath):
    path_ = f"{outpath}.txt"

    try:
        with open(path_,"w") as file:
            file.write(textWrite)
    except UnicodeEncodeError:
        with open(path_,"w",encoding="utf-8",errors="replace") as file:
            file.write(textWrite)

メール内容の保存と変数へ格納

開封メールの結果が変数openedに。通常メール結果がrezultに。
テキストやファイルはtext_save(textWrite,outpath)を利用して保存。

form win32com.client import Dispatch
import subprocess

#メールソフトを立ち上げる
outloook_path = "outloookのpathを記載" #例:office15¥OUTLOOK.EXE
profile_name = "outlook"
subprocess.Popen([outloook_path ,"/profile",profile_name],shell=True)

#対象サブディレクトリの中身を抽出
account_name="メールの対象アカウントを入力"
sub_dir_nama="メールの対象アカウント名の受信ディレクトリ内のサブディレクトリ名を入力"
all_inbox = target_inbox(account_name,sub_dir_nama)

opened = []
rezult = []

#メール内容を取得していく
for mail in all_inbox:

    #開封メール判別
    #メールヘッダー取得
    header=mail.PropertyAccessor.GetProperty("http:schemas.microsoft.com/mapi/proptag/0x0077D001F")
    if "report-type=disposition-notification" in header:
        
        #送信元情報の入手
        from_ = [line for line header.split("/n") if line.startswith("From:")][0]
        date_ = [line for line header.split("/n") if line.startswith("Date:")][0]
        date_ = date_.replace("Date: ","")
        mail_subject=mail.subject
        mail_body=mail.body

        opened.append(from_,date_,mail_subject,mail_body)
    
        continue

    #送信先が自分ならデータ保存しない
    if mail.sendername =="自分のアドレス":
        continue

    #メール本文の保存
    mail_body=custom_encode(mail.body,encoding="utf-8")
    mail_subject = custom_encode(mail.subject,encoding="utf-8")

    #メール本文保存
    text_save(mail_body,outpath)

    #添付ファイル保存
    for attachment in mail.Attachments:
        attachment.SaveAsFile(outpath)

    #変数に保存
    rezult.append((mail.sendername,mail_body,mail_subject,mail_body)) 

最後に

Pythonからofficeソフトを操作するケースはいくつかありますので気になる方はPythonからAccess(アクセス)マクロを実行Pythonで大量エクセルに一括で自動パスワード設定する方法などあわせてご覧くださいませ。

また、gmailや他のメールにも今回の内容は応用できますので変数を変えて試してみるとよいかと思います。

最後に私がPythonの勉強をして入門者から中級者までにこの本1冊あれば習得できるおすすめ本記事も書いております【本1冊で】Python入門から中級までなれるおすすめ本ご興味がある方は御覧くださいませ。

タイトルとURLをコピーしました