参考資料
フォルダ構成
(やりたい事)
複数のメールをまとめて送信する
・メール本文にしようする文章はテキストファイルに保存
・顧客の名前やメールアドレスはExcelファイルから参照
・添付ファイルはフォルダに保存しておく
・該当する顧客にメール送信するプログラムを作成する!!
メール送信工程
①メール送付リストを作成 | フォルダーから請求書のPDFファイルを1つ取得する |
---|---|
(PDFファイルごとに繰り返す) | 顧客IDをPDFファイル名から把握する |
該当する顧客データをファイル「顧客マスタ」から検索 | |
メール送付リストに「顧客データ」と「PDFファイル」を登録 | |
②メールを一斉送信 | SMTPサーバーに接続 |
(メール送付リストの顧客ごとに繰り返す) | メッセージを準備 |
件名、メールアドレスを設定 | |
メール本文を追加 | |
添付ファイルにPDFファイルを追加 | |
メッセージを送信 | |
SMTPサーバーと接続を閉じる |
メールを送信するには「メール送付リスト」に登録した顧客を1つずつ取り出して、顧客ごとにメッセージデータを作成する
メッセージデータには、まず件名とメールアドレスを設定し、本文を追加して。請求書のPDFファイルを添付ファイルとして加えて送信する
メール送付リストの作成
次のように[顧客データ、請求書PDFファイルのパス]を要素に持つリストにする
このようにリストを作成すれば、顧客データの中のメールアドレスに、PDFファイルを添付して、メール送信すれば良いので、一斉に送信する処理を作りやすくなる
mailing_list = [ [[顧客ID, 顧客名,部署名,担当者名,メールアドレス,・・・], 請求書PDFファイルパス], [[顧客ID, 顧客名,部署名,担当者名,メールアドレス,・・・], 請求書PDFファイルパス], ・・・ ]
・最初に必要なモジュールを全てインポートしておく
openpyxl | Excelファイルの読み込み |
---|---|
Path | フォルダ内のファイル検索 |
smtplib | SMTPサーバーと更新する |
MIMEMultipart | メッセージを作成する |
MIMEText | 本文を作成する |
MIMEApplication | 添付ファイルを作成する |
sys | プログラムを中止する |
import sys import openpyxl from pathlib import Path import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication # 顧客マスタの読み込み wb_master = openpyxl.load_workbook("顧客マスタ.xlsx") ws_master = wb_master["Sheet1"] customer_list = [] for row in ws_master.iter_rows(min_row=2): if row[0].value is None: break value_list = [] for c in row: value_list.append(c.value) customer_list.append(value_list) # 請求書PDFのフォルダー pdf_dir = "請求書PDF_202007" # メーリングリスト mailing_list = [] # フォルダーから請求書のPDFファイルを1つずつ取得する for invoice in Path(pdf_dir).glob("*.pdf"): # 「顧客ID」 は、 PDFファイルの拡張子を除いた部分 customer_id = invoice.stem # 該当する顧客データを「顧客マスタ」から検索 for customer in customer_list: if customer_id == customer[0]: # メーリングリストに「顧客データ」と # 「PDFファイル」のパスを追加 mailing_list.append([customer, invoice]) # 顧客ID、顧客名、メールアドレス、 # PDFファイルのパスを表示 print(customer[0], customer[1], customer[4], invoice)
結果
(検索)
⇨PDFファイルが対象なので、glob()の括弧の中には「*.pdf」を指定して、拡張子でファイルを検索
(取得)
⇨取得したPDFを送信する顧客はファイル名が顧客IDとなっている。拡張子を除いた顧客IDの部分はstemで取得できる
(送信リストに追加)
検索した顧客データは送付する請求書のPDFファイルのパスと一緒にメール送信リストに追加。これから送付する顧客とPDFファイルが確認できるようprint()で表示
メールを一斉に送信
間違えて送信しないようにテストをする
プログラムにテストモードを追加する
変数test_modeがTrieの場合は自分のアドレス宛てに送信するようにする
※テストモードではtest、本番モードではrealと入力してもらうようにするが、本番モードのreal以外が入力された場合はテストモードにする
また、テストモードの切り替えはinput()を用いて、画面から行うようにする
次に送信を開始する前に、どちらのモードが設定されているかを明示して送信しても大丈夫かを確認する
input()を用いて、続行して送信する場合はyes、中止する場合はnoを入力してもらい、入力した値がyes以外の場合は、sys.exit()でプログラムを中止する
プログラムを続行する場合は、メッセージの送信に備えて、メール本文をmail_body.txtから読み込んでおく
# モード選択 print() # 1行空ける mode = input("モード選択(テスト=test、本番=real):") # 本番以外はテスト if mode != "real": test_mode = True else: test_mode = False # 送信確認 if test_mode: result = input("テストモードで自分宛てに送信します(続行=yes、中止=no):") else: result = input("本番モードで送信します(続行=yes、中止=no):") # 続行以外は中止 if result != "yes": print("プログラムを中止します") sys.exit() # メール本文をファイルから読み込んでおく text = open("mail_body.txt", encoding="utf-8") body_temp = text.read() text.close()
▼結果
プログラムを実行すると次のように画面モードを選択できる。
ここでは、送信するかどうかの確認でNoを入力して、プログラムを中止している
・SMTPサーバに接続したら、メール送信リストの顧客への送信を始める。メール送付リストの1件文のデータは[顧客データ, 請求書PDFファイルのパス]のようなリストになっている。
⇨そこでメール送信リストをリープして一つの要素を変数dataに代入してインデックスを用いてdata[0]で顧客データ、data[1]で請求書PDFファイルのパスを取得する
⇨この顧客データから顧客メールアドレスを取得して、件名や自分のアドレスと一緒にメッセージ設定する。
さらに、会社名や担当者名も取得して、メール本文にformat()で埋め込む。
・添付ファイルのデータは請求書PDFファイルのパスにあるPDFファイルからバイナリで読み取る
※ここでヘッダーにふあするファイル名には、パスに.nameをつけて「フォルダーを除いたファイル名」を指定する
・メール本文と添付ファイルの追加が終わったら、メッセージをsend_message()で送信する。
・送信中は進捗がわかるように、print()で送信している顧客IDと会社名を表示
・リストの全ての顧客に送信を完了したら、最後にSMTPサーバーとの接続を閉じる
▼全てのコード(mail_invice_sender.py)
# モード選択 print() # 1行空ける mode = input("モード選択(テスト=test、本番=real):") # 本番以外はテスト if mode != "real": test_mode = True else: test_mode = False # 送信確認 if test_mode: result = input("テストモードで自分宛てに送信します(続行=yes、中止=no):") else: result = input("本番モードで送信します(続行=yes、中止=no):") # 続行以外は中止 if result != "yes": print("プログラムを中止します") sys.exit() # メール本文をファイルから読み込んでおく text = open("mail_body.txt", encoding="utf-8") body_temp = text.read() text.close()
▼結果(失敗!)
なぜ!ここまできて😭
Emailポリシーに引っかかったらしいです💦
解決できなかったので、ここまでにしましょうw
Pythonで自動送信するときに気をつけること
メール送信を自動化するときには「送信ミス」と「迷惑メールに間違われること」に特に気をつけないといけない。
まずはテストモードを実装して、自分のアドレス宛てにテストで送信して、本文と添付ファイルの内容を確認できるようにする
また、本当に一斉送信を開始しても大丈夫か、一時停止して確認するステップも実装する
さらに、送信中は進捗がわかるように、送信している相手をprint()で随時表示し、送信中にミスに気がついた場合は、キー「Ctrl+C」を押すことで強制終了できる。
今回はここまで🌸
それではまた!
sunoでした
コメント