LoginSignup
1
3

More than 5 years have passed since last update.

Python で、Gmail の oauth 2.0 を使う

Last updated at Posted at 2017-08-22

まず、client_id.json をダウンロードし、client_secret.json にリネームする。

client_secret.json
{
  "installed": {
    "client_id": "392180717871-aa321u2qc154ih40qqe9dc221u0jp9tf.apps.googleusercontent.com",
    "project_id": "unified-firefly-177607",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://accounts.google.com/o/oauth2/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "CABpqwE-2jv-sTy0oJOuTIQG",
    "redirect_uris": [
      "urn:ietf:wg:oauth:2.0:oob",
      "http://localhost"
    ]
  }
}

プログラムを実行して、メールを送る様子

$ ./test_gmail.py 
*** 開始 ***
Message Id: 15e094f0f37f1509
mail_from = test_aa@gmail.com
mail_to = test_bb@example.com
subject = Gmail Api Test Aug/22/2017 PM 16:57
*** 終了 ***

1回目だけは、ブラウザーが開いて、
.credentials というフォルダーに JSON が作成されます。
2回目からは、ブラウザーは開きません。

Arch Linux で必要なライブラリのインストールは

sudo pacman -S python-google-api-python-client

次のプログラム の mail_from と、mail_to は書き換えて下さい。

test_gmail.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#   test_gmail.py
#
#                   Aug/22/2017
# ------------------------------------------------------------------
import sys

from gmail_send import gmail_send_proc
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
mail_from = "test_aa@gmail.com"
mail_to = "test_bb@example.com"
subject = "Gmail Api Test Aug/22/2017 PM 16:57"
#
contents = ""
contents += "こんにちは\n"
contents += "ひがさしています。\n"
contents += subject + "\n"
#
gmail_send_proc(mail_from,mail_to,subject,contents)
#
sys.stderr.write ("mail_from = " + mail_from + "\n")
sys.stderr.write ("mail_to = " + mail_to + "\n")
sys.stderr.write ("subject = " + subject + "\n")
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------

次の2つは変更の必要はありません。

gmail_send.py
# -*- coding: utf-8 -*-
#
#   gmail_sender.py
#
#                   Aug/22/2017
# ------------------------------------------------------------------
import httplib2
import os
import sys
import apiclient
import base64
import traceback
from email.mime.text import MIMEText
from email.utils import formatdate

from get_credentials import get_credentials
# ------------------------------------------------------------------
def create_message(mail_from,mail_to,subject,contents):
    message = MIMEText(contents)
#
    message["from"] = mail_from
    message["to"] = mail_to
    message["subject"] = subject
    message["Date"] = formatdate(localtime=True)

    byte_msg = message.as_string().encode(encoding="UTF-8")
    byte_msg_b64encoded = base64.urlsafe_b64encode(byte_msg)
    str_msg_b64encoded = byte_msg_b64encoded.decode(encoding="UTF-8")

    body = {"raw": str_msg_b64encoded}
#
    return body
#
# ------------------------------------------------------------------
def gmail_send_proc(mail_from,mail_to,subject,contents):
#
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = apiclient.discovery.build("gmail", "v1", http=http)

    try:
        result = service.users().messages().send(
            userId=mail_from,
            body=create_message(mail_from,mail_to,subject,contents)
        ).execute()

        print("Message Id: {}".format(result["id"]))

    except apiclient.errors.HttpError:
        print("------start trace------")
        traceback.print_exc()
        print("------end trace------")
#
# ------------------------------------------------------------------
get_credentials.py
# -*- coding: utf-8 -*-
#
#   gmail_sender.py
#
#                   Aug/22/2017
# ------------------------------------------------------------------
import os
import sys

import apiclient
import oauth2client
import argparse
# ------------------------------------------------------------------
flags = argparse.ArgumentParser(
    parents=[oauth2client.tools.argparser]
).parse_args()

# import traceback

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/gmail-python-quickstart.json
#
SCOPES = "https://www.googleapis.com/auth/gmail.send"
CLIENT_SECRET_FILE = "client_secret.json"
APPLICATION_NAME = "MyGmailSender"


# ------------------------------------------------------------------
def get_credentials():
    script_dir =os.path.abspath(os.path.dirname(__file__)) 
    credential_dir = os.path.join(script_dir, ".credentials")

    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   "my-gmail-sender.json")

    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = oauth2client.client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        credentials = oauth2client.tools.run_flow(flow, store, flags)
        print("Storing credentials to " + credential_path)
#
    return credentials
#
# ------------------------------------------------------------------

次の環境で動作を確認しました。

$ uname -a
Linux iwata 4.19.11-arch1-1-ARCH #1 SMP PREEMPT Thu Dec 20 03:40:28 UTC 2018 x86_64 GNU/Linux
$ python --version
Python 3.7.1
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3