以前、GmailはIMAPやPOP3でのメールの操作ができたのだが、いつのころからかその 方法は禁止になった。しかしメールの操作はOAuth2によりアクセストークンを 取得し、そのアクセストークンを使用してGMail APIを呼び出すことでメール の操作ができる。今回はこの方法を用いてメールの送信を確認する。

プロジェクトを有効にする

(setq dummy-project-name "DUMMY_PROJECT")
(setq dummy-project-user-id "1")

OAuth 2.0 クライアント IDを作成する

(concat "https://console.cloud.google.com/apis/credentials/consent"
        "?"
        (format "authuser=%s" dummy-project-user-id)
        "?"
        (format "project=%s" dummy-project-name)
        )
https://console.cloud.google.com/apis/credentials/consent?authuser=1?project=DUMMY_PROJECT

この値は重要な値である。今回は以下の値を例として扱うことにする。

Name Value
Client ID DUMMY_CLIENT_ID
Client Secret DUMMY_CLIENT_SECRET
(setq dummy-client-id "DUMMY_CLIENT_ID")
(setq dummy-client-secret "DUMMY_CLIENT_SECRET")

Gmail APIを有効にする

(concat "https://console.cloud.google.com/apis/dashboard"
        "?"
        (format "authuser=%s" dummy-project-user-id)
        "?"
        (format "project=%s" dummy-project-name)
        )
https://console.cloud.google.com/apis/dashboard?authuser=1?project=DUMMY_PROJECT
(concat "https://console.cloud.google.com/apis/api/gmail.googleapis.com/metrics"
        "?"
        (format "authuser=%s" dummy-project-user-id)
        "?"
        (format "project=%s" dummy-project-name)
        )
https://console.cloud.google.com/apis/api/gmail.googleapis.com/metrics?authuser=1?project=DUMMY_PROJECT

OAuth2のアクセストークンを取得する

認可ページへのURLを組み立てる

(concat "https://accounts.google.com/o/oauth2/v2/auth"
	"?"
	"redirect_uri=urn:ietf:wg:oauth:2.0:oob"
	"&"
	"scope=https://mail.google.com/"
	"&"
	"response_type=code" 
	"&"
	(format "client_id=%s" dummy-client-id)
	)
https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://mail.google.com/&response_type=code&client_id=DUMMY_CLIENT_ID
アクセストークンの取得の為のパーミッション画面へのURLを生成する

Webブラウザで認可ページへアクセスし認可を行う

認可が正常に完了するとコードが表示される。 このコードはアクセストークンの初回の生成時に使用する。

(setq dummy-authorization-code "DUMMY_CODE")

OAuth2のアクセストークンを生成する

先ほど生成したコードを利用してアクセストークンを生成する。

:CLIENT_ID := dummy-client-id
:CLIENT_SECRET := dummy-client-secret
:CODE := dummy-authorization-code

POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded

redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code&code=:CODE&client_id=:CLIENT_ID&client_secret=:CLIENT_SECRET

アクセストークンには有効期限がある。有効期限の切れたアクセストークンは当然API呼び出しに失敗する。 アクセストークンの生成時にリクレッシュトークンも共に返される。 このリクレッシュトークンはアクセストークンを更新し期限を延長するために使用する。

(setq dummy-access-token "DUMMY_ACCESS_TOKEN")
(setq dummy-refresh-token "DUMMY_REFRESH_TOKEN")

期限の切れたOAuth2のアクセストークンをリフレッシュする

:CLIENT_ID := dummy-client-id
:CLIENT_SECRET := dummy-client-secret
:REFRESH_TOKEN := dummy-refresh-token

POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded

client_id=:CLIENT_ID&client_secret=:CLIENT_SECRET&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=refresh_token&refresh_token=:REFRESH_TOKEN

メールを送信する

送信するメールを作成する

from email.mime.text import MIMEText

m = MIMEText('This is automated draft mail')
m['To'] = '[email protected]om'
m['From'] = '[email protected]'
m['Subject'] = 'succeed!!'

return m.as_string()
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
To: [email protected]
From: [email protected]
Subject: succeed!!

This is automated draft mail

メールのデータをbase64形式にエンコードする

Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1cy1hc2NpaSIKTUlNRS1WZXJzaW9u
OiAxLjAKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdApUbzogdG9AZXhhbXBsZS5jb20K
RnJvbTogZnJvbUBleGFtcGxlLmNvbQpTdWJqZWN0OiBzdWNjZWVkISEKClRoaXMgaXMgYXV0b21h
dGVkIGRyYWZ0IG1haWw=

上記のデータを生成できればよい。base64コマンドを使用すればbase64形式に エンコードできる。Pythonでbase64形式にエンコードする場合、 base64.b64encode()関数を使用する。

メール送信APIを呼び出す

:USER_ID = me
:ACCESS_TOKEN := dummy-access-token

POST https://gmail.googleapis.com/gmail/v1/users/:USER_ID/messages/send
Content-Type: application/json
Authorization: Bearer :ACCESS_TOKEN

{
  "id": "string",
  "labelIds": [],
  "snippet": "string",
  "payload": {
    "partId": "string",
    "mimeType": "string",
    "filename": "string",
    "headers": [
      {
        "name": "To",
        "value": "[email protected]"
      },
      {
        "name": "From",
        "value": "[email protected]"
      }
    ],
    "body": {
      "attachmentId": "",
      "size": 10,
      "data": "YWJjZGU="
    },
    "parts": []
  },
  "sizeEstimate": 10,
  "raw": "Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJ1cy1hc2NpaSIKTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdApUbzogdG9AZXhhbXBsZS5jb20KRnJvbTogZnJvbUBleGFtcGxlLmNvbQpTdWJqZWN0OiBzdWNjZWVkISEKClRoaXMgaXMgYXV0b21hdGVkIGRyYWZ0IG1haWw=",
}