LoginSignup
4
6

More than 3 years have passed since last update.

溜まったGmailの不要メールをAPIで一括削除する

Posted at

以前の記事、Pythonを使ってGmail APIからメールを取得するという記事を書きましたが、
その延長で過去のメールの一括削除をAPIを使ってやってみました。

動作環境

python3.8.3

使用するAPI

batchDeleteという、APIを使用します。使い方として、request bodyに削除するメールのIDをlistで渡すと、一括削除ができます。

SCOPEの変更

GmailAPIに接続する際に、SCOPEを指定します。前回は、取得のみだったため、読取専用(ReadOnly)でOKでしたが、今回は削除を行うため、フルでアクセスできるSCOPEに変更が必要です。
また、注意事項として、途中でSCOPEを変更する場合は、'token.json'のファイルを削除する必要があります。削除しないと変更が反映されません。
参考:Choose Auth Scopes(GmailAPIのページより)

    def __init__(self):
        # Scopeを変更した場合は、token.jsonを削除すること
        self._SCOPES = 'https://mail.google.com/' #フルアクセスのSCOPEを指定
        self.MessageIDList = []
        self.MessageList = []

    def ConnectGmail(self):
        #GmailAPIに接続
        store = file.Storage('token.json')
        creds = store.get()
        if not creds or creds.invalid:
            flow = client.flow_from_clientsecrets('credentials.json', self._SCOPES)
            creds = tools.run_flow(flow, store)
        service = build('gmail', 'v1', http=creds.authorize(Http()))

        return service

ソースコード

実際に、以下のソースで削除処理を行います。
※実行すると、実際にメールが削除されるため、指定する条件などご注意ください。

GmailAPI.py
from __future__ import print_function
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
import time

class GmailAPI:

    def __init__(self):
        # If modifying these scopes, delete the file token.json.
        self._SCOPES = 'https://mail.google.com/'
        self.MessageIDList = []

    def ConnectGmail(self):
        store = file.Storage('token.json')
        creds = store.get()
        if not creds or creds.invalid:
            flow = client.flow_from_clientsecrets('credentials.json', self._SCOPES)
            creds = tools.run_flow(flow, store)
        service = build('gmail', 'v1', http=creds.authorize(Http()))

        return service


    def DeleteMessageList(self,DateFrom,DateTo,MessageFrom):
        try:

            #APIに接続
            service = self.ConnectGmail()
            self.MessageIDList = []

            query = ''
            # 検索用クエリを指定する
            if DateFrom != None and DateFrom !="":
                query += 'after:' + DateFrom + ' '
            if DateTo != None  and DateTo !="":
                query += 'before:' + DateTo + ' '
            if MessageFrom != None and MessageFrom !="":
                query += 'From:' + MessageFrom + ' '
            print("削除条件 開始日付{0} 終了日付{1} From:{2}".format(DateFrom,DateTo,MessageFrom))

            # メールIDの一覧を取得する(最大500件)
            self.MessageIDList = service.users().messages().list(userId='me',maxResults=500,q=query).execute()
            if self.MessageIDList['resultSizeEstimate'] == 0: 
                print("Message is not found")
                return False

            #batchDeleteのrequestbody用にIDを抽出
            ids = {
                'ids': []
            }
            ids['ids'].extend([str(d['id']) for d in self.MessageIDList['messages']])

            #削除処理
            print("{0}件削除処理開始".format(len(ids['ids'])))
            service.users().messages().batchDelete(userId='me',body=ids).execute()
            print("削除が完了しました")

            return True

        except Exception as e:
            print("エラーが発生しました")
            print(e)
            return False

if __name__ == '__main__':

    gmail = GmailAPI()

    #一度に消せる件数に制限があるので、対象データがなくなるまで繰り返し処理する
    for i in range(100):
        #任意の条件を指定(期間とFromアドレス)して、削除処理を呼び出し
        if (gmail.DeleteMessageList(DateFrom='2010-01-01',DateTo='2020-10-30',MessageFrom='xxxxx@xxxxxx.com') == False):
            break
        if len(gmail.MessageIDList['messages']) < 500:
            #処理を抜ける
            break
        else:
            #10秒待つ
            time.sleep(10)

おわりに

APIを使って、メールの削除を行ってみました。GmailのGUIで削除するよりは楽だと思いますので、参考にしてもらえると幸いです。

4
6
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
4
6