参考資料
フォルダ構成
(やりたい事)
複数のメールをまとめて送信する

・メール本文にしようする文章はテキストファイルに保存
・顧客の名前やメールアドレスは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でした

コメント