😀

PythonでGmailを自動送信する方法

2022/06/11に公開

最近、Pythonを始めるにあたり、自動化してみたかったGmailの送信処理の実装を行いました。
まだまだPython初心者に自分にとっては、学びになる点が多かったので共有したいと思います。

実装

実装は、多くの記事にあるように、PythonのデフォルトのライブラリであるsmtplibMIMETextemail.mime.textを使用して行います。

mailer.py
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のパスワードを記述していた箇所のコードに記述する必要があります。
スクリーンショット 2022-06-11 19.34.32.png

参考文献

.env ファイルで環境変数を設定する (python-dotenv)

Pythonでメール(gmail)を送信できない場合の解決法

21.17. smtplib --- SMTP プロトコルクライアント

email.mime: メールと MIME オブジェクトを一から作成

Discussion