この記事について
Python を使って Gmail 経由でメールを送信する方法をまとめました。
Google アカウント側で必要な設定と、Python でのメール送信コードを順に解説します。
準備
アプリパスワードを取得する
PythonプログラムからGmailでメールを送信するにはGoogleアカウント側でアプリパスワードを発行しておく必要があります。手順は次の通りです。
- Googleアカウントの「セキュリティとログイン」に移動する
- 2段階認証プロセスを有効化する
- 画面上部の検索バーで「アプリパスワード」と入力して、設定画面に移動する
- 任意のアプリ名を入力する
- 生成されたアプリパスワードを控えておく
環境変数を設定
パスワードや自分のメールアドレスを.envで管理するためにpython-dotenvをインストールします。
pip install python-dotenv
環境変数の設定ファイルとして.envファイルを作成します。
MY_MAIL_ADDRESS=<自分のメールアドレス>
APP_PASS=<控えておいたアプリパスワード>
SMTP_SERVER='smtp.gmail.com'
SMTP_PORT=465
SMTP_PORTについて
GoogleのドキュメントによるとGmailのSMTPサーバーのポートは465と587が利用できます。465はImplicit TLS用、587はSTARTTLS用(最初は平文で通信、その後TLSに切替)として利用します。暗号化方式によって後述のソースコードも変わるので注意してください。(ここでそれぞれについて解説しています。)
プログラムの作成
プログラム全体
ここでは、メールの作成から送信までを行うPythonプログラムの全体像を示します。dotenv以外はPythonの標準ライブラリを利用しています。プログラムの簡易さを優先してエラーハンドリングなどは省略しました。
import os
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from dotenv import load_dotenv
load_dotenv()
def create_message(to_email: str, subject: str, body: str) -> MIMEMultipart:
"""
multipart形式のMIMEメッセージを作成
Args:
to_email (str): 送信先メールアドレス
subject (str): メールの件名
body (str): メールの本文
Returns:
MIMEMultipart: 作成したメールメッセージ
"""
msg = MIMEMultipart() # 初期化
# メッセージを作成
msg['Subject'] = subject
msg['From'] = os.getenv('MY_MAIL_ADDRESS')
msg['To'] = to_email
msg.attach(MIMEText(body, 'plain'))
return msg
def send_email(msg: MIMEMultipart):
"""
SMTPサーバーを使用してメールを送信
Args:
msg (MIMEMultipart): 送信するメールメッセージ
"""
# SMTP_PORTが465の場合はsmtplib.SMTP_SSLを587の場合はsmtplib.SMTPを利用
# このコードは465(Implicit TLS)の場合
with smtplib.SMTP_SSL(os.getenv('SMTP_SERVER'), os.getenv('SMTP_PORT')) as server:
server.login(os.getenv('MY_MAIL_ADDRESS'), os.getenv('APP_PASS'))
server.send_message(msg)
if __name__ == '__main__':
to_email = '<送り先のメールアドレス>'
subject = 'Pythonによる自動送信テスト'
body = 'このメールはPythonから自動送信しています。'
# メッセージの作成
message = create_message(
to_email=to_email,
subject=subject,
body=body
)
# メールの送信
send_email(message)
envファイルの読み込み
from dotenv import load_dotenv
load_dotenv()
この部分の記述によって環境変数を設定で作成した.envファイルの内容を環境変数として利用できるようになります。以降はos.getenv()で環境変数を呼び出します。
メッセージ作成関数
メールのメッセージを作成する関数create_message()では、メッセージをMIME形式で作成します。今回は本文のみですが添付ファイルなどに対応しているmultipart形式で作成しています。
def create_message(to_email: str, subject: str, body: str) -> MIMEMultipart:
"""
multipart形式のMIMEメッセージを作成
Args:
to_email (str): 送信先メールアドレス
subject (str): メールの件名
body (str): メールの本文
Returns:
MIMEMultipart: 作成したメールメッセージ
"""
msg = MIMEMultipart() # 初期化
# メッセージを作成
msg['Subject'] = subject
msg['From'] = os.getenv('MY_MAIL_ADDRESS')
msg['To'] = to_email
msg.attach(MIMEText(body, 'plain'))
return msg
メール送信関数
メールを送信する関数send_email()では、SMTPサーバーに接続してcreate_message()で作成したメールを送信します。
def send_email(msg: MIMEMultipart):
"""
SMTPサーバーを使用してメールを送信
Args:
msg (MIMEMultipart): 送信するメールメッセージ
"""
# SMTP_PORTが465の場合はsmtplib.SMTP_SSLを587の場合はsmtplib.SMTPを利用
# このコードは465(Implicit TLS)の場合
with smtplib.SMTP_SSL(os.getenv('SMTP_SERVER'), os.getenv('SMTP_PORT')) as server:
server.login(os.getenv('MY_MAIL_ADDRESS'), os.getenv('APP_PASS'))
server.send_message(msg)
上記で述べたように、GMailのSMTPサーバーでは暗号方式としてImplicit TLS(ポート番号465)とSTARTTLS(ポート番号587)が利用可能で、暗号化方式によって呼び出すメソッドが異なることに注意してください。
STARTTLS利用版のコード
STARTTLSを使ってメールを送る場合は次のようにソースコードを書き替えます。その際に.envファイルのSMTP_PORTを587に変更してください。
def send_email(msg: MIMEMultipart):
"""
SMTPサーバーを使用してメールを送信
Args:
msg (MIMEMultipart): 送信するメールメッセージ
"""
# smtplib.SMTP_SSLではなくsmtplib.SMTPを利用
with smtplib.SMTP(os.getenv('SMTP_SERVER'), os.getenv('SMTP_PORT')) as server:
server.starttls() # 追加
server.login(os.getenv('MY_MAIL_ADDRESS'), os.getenv('APP_PASS'))
server.send_message(msg)
withブロックの部分について
smtplib.SMTP_SSL(もしくはsmtplib.SMTP)でwithブロックを利用することでブロック終了時にサーバーとの接続を自動で閉じることができます。手動で接続を閉じる場合はserver.quit()を利用します。
def send_email(msg: MIMEMultipart):
"""
SMTPサーバーを使用してメールを送信
Args:
msg (MIMEMultipart): 送信するメールメッセージ
"""
server = smtplib.SMTP_SSL(os.getenv('SMTP_SERVER'), int(os.getenv('SMTP_PORT')))
server.login(os.getenv('MY_MAIL_ADDRESS'), os.getenv('APP_PASS'))
server.send_message(msg)
server.quit() # サーバーとの接続を明示的に閉じる
最後に
今回はPythonを利用したメール送信について解説してみました。参考になれば幸いです。
参考資料
GmailのIMAP:https://developers.google.com/workspace/gmail/imap/imap-smtp?hl=ja