【Python】Gmailでメールを送信する方法

今回はPythonを使ってGmailを送信する方法。
最近行ったことがなかったので改めて調べ直してみました。
数年前にやってた時は、以下の②のSMTPで行ってました。
その時はセキュリティ緩かったので、セキュリティ設定を変更することなく送信できてましたが、2020年9月現在ではセキュリティ設定を下げないと送れないようです。
なので、今回は①の方法を試してみます。

①Gmail APIを使う
【メリット】
・API経由でGmail独自の機能を使える
【デメリット】
・準備が面倒
②SMTPで送信する
【メリット】
・送信するだけなら比較的容易
【デメリット】
・セキュリティ設定を下げる必要がある

環境情報

・Python3.8
・pip
・Ubuntu 20.10(Docker)

Gmail APIでの事前準備作業

1.Google Cloud Platformでプロジェクトを作成

画像3

2.作成したプロジェクトでGmail APIを有効にする

画像4

3.OAuth同意画面を作成する

画像5

画像6

作成ボタンを押した後表示される画面で
・アプリケーション名に任意の名称を入力
・スコープを追加で次の7つのスコープを追加
 ../auth/gmail.insert
 ../auth/gmail.labels
 ../auth/gmail.send
 ../auth/gmail.compose
 ../auth/gmail.modify
 ../auth/gmail.metadata
 ../auth/gmail.readonly
を実施して保存ボタンを押下する。

4.認証情報を作成する
認証情報から「OAuth クライアント ID の作成」を選択。
アプリケーションの種類で「デスクトップアプリ」を選択。
名前は変更せずに作成ボタンを押下。
作成完了後に一覧からJSONファイルをダウンロード。

Google Clientのインストール

pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib

メールを送ってみる

test.py

# -*- coding: utf-8 -*-

import base64

from email.mime.text import MIMEText
from googleapiclient.discovery import build

def create_message(sender, to, subject, message_text):
   """Create a message for an email.

   Args:
       sender: Email address of the sender.
       to: Email address of the receiver.
       subject: The subject of the email message.
       message_text: The text of the email message.

   Returns:
       An object containing a base64url encoded email object.
   """
   message = MIMEText(message_text)
   message['to'] = to
   message['from'] = sender
   message['subject'] = subject

   return {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()}

def send_message(service, user_id, message):
   """Send an email message.

   Args:
       service: Authorized Gmail API service instance.
       user_id: User's email address. The special value "me"
       can be used to indicate the authenticated user.
       message: Message to be sent.

   Returns:
       Sent Message.
   """
   try:
       message = (service.users().messages().send(userId=user_id, body=message)
                  .execute())
       print('Message Id: %s' % message['id'])
       return message
   except errors.HttpError as error:
       print('An error occurred: %s' % error)

SCOPES = [
   "https://www.googleapis.com/auth/gmail.compose",
   "https://www.googleapis.com/auth/gmail.readonly",
   "https://www.googleapis.com/auth/gmail.labels",
   "https://www.googleapis.com/auth/gmail.modify",
]

def get_credential(json_path, token_path):
   import os
   import pickle
   from google.auth.transport.requests import Request
   from google_auth_oauthlib.flow import InstalledAppFlow

   creds = None
   if os.path.exists(token_path):
       with open(token_path, "rb") as token:
           creds = pickle.load(token)
   if not creds or not creds.valid:
       if creds and creds.expired and creds.refresh_token:
           creds.refresh(Request())
       else:
           flow = InstalledAppFlow.from_client_secrets_file(json_path, SCOPES)
           # creds = flow.run_local_server()
           creds = flow.run_console()
       with open(token_path, "wb") as token:
           pickle.dump(creds, token)
   return creds

def main():
   # 初回のみ認証が必要になる。
   # 第1引数に認証情報作成でダウンロードしたjsonファイルのパスを指定。
   # 第2引数は初回にブラウザで認証した結果が保存され、次回以降それが利用される。
   creds = get_credential("client_secret.json", "token.pickle")
   service = build('gmail', 'v1', credentials=creds)

   # テキストメッセージ作成
   message = create_message(
       "ここに差出人のメールアドレスを設定",
       "ここに宛先のメールアドレスを設定",
       "ここにメール件名を設定",
       "ここに本文を設定")
   # メール送信
   send_message(service, "me", message)

if __name__ == "__main__":
   main()

初回実行するとURLが表示されるのでそのURLをブラウザに貼り付けてアクセスする。
アクセスして認証するとコードが払い出されるので、実行画面に戻って貼り付ける。
そうすると次の通りメールが送信される。

画像6

参考


(参考)SMTP送信での事前準備作業

1.Googleアカウントの設定で「安全性の低いアプリのアクセス」を有効化する

画像1


いいなと思ったら応援しよう!