Python で、Gmail の oauth 2.0 を使う

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

```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"
    ]
  }
}
```

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

```text
$ ./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
*** 終了 ***
```

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

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

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


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

```py3: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")
# ------------------------------------------------------------------
```

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

```py3: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------")
#
# ------------------------------------------------------------------
```

```py3: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
#
# ------------------------------------------------------------------
```

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

```text
$ 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
```