PythonでGmailを自動送信する方法
最近、Pythonを始めるにあたり、自動化してみたかったGmailの送信処理の実装を行いました。
まだまだPython初心者に自分にとっては、学びになる点が多かったので共有したいと思います。
実装
実装は、多くの記事にあるように、Pythonのデフォルトのライブラリであるsmtplib
とMIMEText
のemail.mime.text
を使用して行います。
import smtplib
from email.mime.text import MIMEText
from dotenv import load_dotenv
import os
import csv
load_dotenv()
class Mailer:
"""メールを送信するクラス
"""
# 初期化
def __init__(self, addr_to, subject, body):
"""Mailerクラスのコンストラクタ
Args:
addr_to (_type_): 送信元先情報
subject (_type_): 件名
body (_type_): 本文
"""
# 送信元情報
self.password = os.getenv('PASSWORD')
self.addr_from = os.getenv('EMAIL')
# 送信先
self.addr_to = addr_to
# 文字コード
self.charset = "ISO-2022-JP"
# 件名
self.subject = subject
# 本文
self.body = body
def send(self):
"""メールを送信する処理
"""
# textのMIMEオブジェクトを作成する(メールの内容を作成する)
msg = MIMEText(self.body.encode(self.charset), 'plain', self.charset)
# 件名
msg['Subject'] = self.subject
# 送信元
msg['Form'] = self.addr_from
# 送信先
msg['To'] = self.addr_to
# gmailのsmtp経由で送信
# 587番ポートを使用して送信する
smtp = smtplib.SMTP('smtp.gmail.com', 587)
# EHLOを利用し、ESMTPサーバに身元を明かす
smtp.ehlo()
# TLSモードでSMTP接続する
smtp.starttls()
smtp.ehlo()
# SMTPサーバにログインする
smtp.login(self.addr_from, self.password)
# 指定したメールアドレスにメッセージを送信する
smtp.send_message(msg)
# サーバとの接続をクローズする
smtp.close()
def create_mail_body(full_name):
"""メール本文の内容を作成する処理"""
body = f"""
{full_name}様
お世話になっております。C-mindの柿です。
ことらのメールはPythonによるGmailのテスト送信になります。
よろしくお願いいたします。
-----------------------
パイソン 太郎
株式会社Test
Engineer
Email: {os.getenv('EMAIL')}
"""
return body
filename = './test.csv'
# CSVファイル読み込み
with open(filename, 'r') as f:
reader = csv.reader(f)
# 列名取得
header = next(reader)
for row in reader:
# CSVにあるデータのemail分メール送信する
# CSVからメール送信に必要な情報を抽出
# 名前
full_name = row[0]
# メールアドレス
email = row[1]
# メール内容
addr_to = email
# 件名
subject = "Pythonによるテストメール"
# 本文
body = create_mail_body(full_name)
# Mailerクラスのインスタンス生成
mailer = Mailer(addr_to, subject, body)
mailer.send()
初期情報として、送信元である自分のgmailアドレスとパスワードを設定します。
私の場合は、ライブラリとしてdotenv
をインストールして、環境変数を読み込み参照するようにしています。
dotenvを使用することで、.env
ファイルに環境変数を設定し、load_dotenv()関数
を使用することで環境変数を読み込むことができます。
参照する場合は、os
ライブラリのgetenv()関数
の引数に参照したい環境変数名を渡すことで値の参照が可能となります。
そして、メールに必要となる項目を設定します。
次に、メールを送信する処理ですが、MIMEText
のオブジェクトを作成し、実際にメールの内容となる部分を構築します。
# textのMIMEオブジェクトを作成する(メールの内容を作成する)
msg = MIMEText(self.body.encode(self.charset), 'plain', self.charset)
# 件名
msg['Subject'] = self.subject
# 送信元
msg['Form'] = self.addr_from
# 送信先
msg['To'] = self.addr_to
それをSMTP通信
を用いて送信するようSMTPの設定をしていきます。
# gmailのsmtp経由で送信
# 587番ポートを使用して送信する
smtp = smtplib.SMTP('smtp.gmail.com', 587)
# EHLOを利用し、ESMTPサーバに身元を明かす
smtp.ehlo()
# TLSモードでSMTP接続する
smtp.starttls()
smtp.ehlo()
# SMTPサーバにログインする
smtp.login(self.addr_from, self.password)
# 指定したメールアドレスにメッセージを送信する
smtp.send_message(msg)
# サーバとの接続をクローズする
smtp.close()
最後にCSVファイルから送信したいメールアドレスのデータ一覧を読み込み、Mailer
インスタンスを作成しsend()メソッドを呼び出し、メールを送信します。
filename = './test.csv'
# CSVファイル読み込み
with open(filename, 'r') as f:
reader = csv.reader(f)
# 列名取得
header = next(reader)
for row in reader:
# CSVにあるデータのemail分メール送信する
# CSVからメール送信に必要な情報を抽出
# 名前
full_name = row[0]
# メールアドレス
email = row[1]
# メール内容
addr_to = email
# 件名
subject = "Pythonによるテストメール"
# 本文
body = create_mail_body(full_name)
# Mailerクラスのインスタンス生成
mailer = Mailer(addr_to, subject, body)
mailer.send()
これでgmailの送信自動化を実装することができます。
補足
ここまで実装するとGoogle側から以下のセキュリティエラーが出ることがあります。
SMTPAuthenticationError:
(535, b'5.7.8 Username and Password not accepted.
Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials
・・・
)
上記エラーが発生した場合は、Googleのセキュリティの設定が必要になります。
具体的には、以下の2段階認証プロセスを「オン」にし、アプリパスワードの設定が必要となります。
また、アプリパスワードを設定したら、そのパスワードをPythonのパスワードを記述していた箇所のコードに記述する必要があります。
参考文献
・.env ファイルで環境変数を設定する (python-dotenv)
・Pythonでメール(gmail)を送信できない場合の解決法
Discussion