Gmail APIを使って、Pythonからメールを自動下書きする

投稿日2019/01/03

#動作環境
Python 3.7.2

#はじめに
Gmail APIを触る機会があり、日本語の資料が少なかったので書くことにしました。

#Gmail APIの有効化とサンプルプログラムの実行
(この章は参考サイトの手順の翻訳と解説です。)
[Python Quickstart - Gmail API](https://developers.google.com/gmail/api/quickstart/python?authuser=2)
このサイトで、あなたのGoogleアカウントでのGmail APIの有効化を行います。

##Step 1: Turn on the Gmail API
[Python Quickstart - Gmail API](https://developers.google.com/gmail/api/quickstart/python?authuser=2)に飛び、「ENABLE THE GMAIL API」ボタンをクリックします。するとポップアップが出るので、
a. 「Create a new project」を選択します。
b. 「DOWNLOAD CLIENT CONFIGURATION」を選択して保存します。名前はそのままの「credentials.json」で。
c. このcredentials.jsonがGmail APIの認証に使われる.jsonファイルなので、これをあなたがこれから作るメール自動送信用のPythonファイルと同じディレクトリに置きます。

##Step 2: Install the Google Client Library
次のコマンドで、Google Client Libraryのインストールをします。

```
pip install --upgrade google-api-python-client oauth2client
```

とりあえず、ここまででPythonからGmail APIを利用する準備は整いました。

##Step 3: Set up the sample
(この手順はスキップしても構いません。)
次に、quickstart.pyという名前のファイルを作って、[Python Quickstart - Gmail API](https://developers.google.com/gmail/api/quickstart/python?authuser=2)にあるサンプルである、gmail/quickstart/quickstart.pyのコードをコピペしてください。


##Step 4: Run the sample
```
python quickstart.py
```
のコマンドで、Step 3で作ったファイルを実行してください。

a.このサンプルはブラウザの新しいウィンドウかタブを開こうとします。もし、失敗したらコンソールからURLをコピーして手動で開いてください。

b.もし、あなたがGoogleアカウントにログインしていなかったら、ログインしてください。もし、複数のアカウントにログインしていたら、自動でメールを送信したいアカウントを選んで認証してください。

c.そのあと、「Quick StartがGoogle アカウントへのアクセスをリクエストしています」となるので、許可のボタンを押してください。

d.すると、ブラウザの方で認証が成功すれば「The authentication flow has completed.」と出るはずです。そして、コンソールの方では、メールのラベルの一覧が出力されているはずです。


#Gmail メールの自動下書き

以下のプログラムは自動で下書きを作成するプログラムです。
main文のとこで、mygmail.draft('相手のメールアドレス', '件名', '本文')とすることで、メールの下書きを作成することができます。
__なお、上の手順のquickstart.pyを実行している方は、この下書きプログラムを実行する前に同じディレクトリにあるtoken.jsonを削除してください。__

私が適当に書いたプログラムですので、至らない点があるかもですのでアドバイス等ありましたらコメントしていただけると幸いです。また、MIMEまわりのimportが多いですが、ファイルを添付する機能をこれから説明しようとしていたからです。(時間があったら記事にするかもです。)

```python:draft.py
from __future__ import print_function
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

import base64
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import mimetypes
import os

from apiclient import errors


# If modifying these scopes, delete the file token.json.
# SCOPESを変更したら、同じディレクトリにあるtoken.jsonを削除する。すると、実行時にgoogleアカウントの承認がブラウザの方で出てくる。
SCOPES = 'https://www.googleapis.com/auth/gmail.modify'
FROM_ADDRESS = 'from@gmail.com'

to_ad = 'to@gmail.com'


class gmail_api:
    def __init__(self):#get_credential 認証する。
        store = file.Storage('token.json')
        creds = store.get()
        if not creds or creds.invalid:
            flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
            creds = tools.run_flow(flow, store)
        self.service = build('gmail', 'v1', http=creds.authorize(Http()))


    def create_draft(self, service, user_id, message_body):
        try:
            message = {'message': message_body}
            draft = service.users().drafts().create(userId=user_id, body=message).execute()
            print('下書き作成しました')
            return draft
        except errors.HttpError:
            print('下書き作成時のHttpError')
            return None


    def draft(self, to_address, subject, body):
        message = MIMEMultipart()
        message['to'] = to_address
        message['from'] = FROM_ADDRESS
        message['subject'] = subject

        msg = MIMEText(body)
        message.attach(msg)

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

        self.create_draft(self.service, 'me', message_body)


if __name__ == '__main__':
    mygmail = gmail_api()
    mygmail.draft(to_ad, '件名', '本文')
```