home / blog / podcasts / videos / notes / photos / about / more

I asked ChatGTP to write me a script to delete one million emails

It did very well

Posted by Jeena

Robot writing code on a old computer

I had a GMail account with about one million emails with attachments in it. There was no way to delete them other than page by page which would take me month to do manually. Today I had the idea that I could ask ChatGTP to write a script for me which would delete them.

With some of my help ChatGTP wrote this code which deletes all the emails from a email account, including the comments.

But I had to come up with the idea to use batchDelete() because ChatGTP would only get one by one, like I did in my previous attempts. I also had to ask it about Google API usage limits which it did not come up with itself. Same with a Pipfile, where it also forgot one dependency, but at least it apologized for the mistake.

On the other side it gave me step by step instructions that I should go to https://console.cloud.google.com/ and what to do where, which was immensely valuable, because those steps are always very confusing, because there are so many options available.

Another problem which ChatGTP could not solve and I had to use Google to do the research myself was that I was getting a insufficientPermissions error. My Google search led me to the official documentation which says that it's not the https://www.googleapis.com/auth/gmail.modify scope which ChatGTP insisted on, but but instead I should use https://mail.google.com/. With that change the code works as expected. The script has been running for about 7 hours to delete all of them.

I tried to tell this to ChatGTP, but when I do it just throws an error: "An error occurred. If this issue persists please contact us through our help center at help.openai.com."

All in all I think with all the back and forth it took me about the same amount of time to let ChatGTP to write it in comparison if I would do it. And I think I'm still a better programmer than ChatGTP - at least for now. But it was much more fun to write it together with ChatGTP, it was almost like pair programming.

Pipfile

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
google-auth = "*"
google-api-python-client = "*"
oauth2client = "*"

[requires]
python_version = "3"

gmail-delete.py

#!/usr/bin/env python3

import httplib2
import os
import base64

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from googleapiclient.errors import HttpError
import time

try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/gmail-python-quickstart.json
SCOPES = 'https://mail.google.com/'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'gmail-delete-all-mails'

def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'gmail-delete-all-mails.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def delete_multiple_emails(service, user_id, msg_ids):
  try:
    service.users().messages().batchDelete(userId=user_id, body={'ids': msg_ids}).execute()
  except HttpError as error:
    print(f'An error occurred: {error}')

def get_all_emails(service, user_id):
    """Retrieve all emails in the user's mailbox.

    Args:
        service: Authorized Gmail API service instance.
        user_id: User's email address. The special value "me"
        can be used to indicate the authenticated user.
    """
    result = service.users().messages().list(userId=user_id).execute()
    messages = result.get("messages", [])
    msg_ids = [msg['id'] for msg in result.get("messages", [])]
    delete_multiple_emails(service, user_id, msg_ids)
    time.sleep(1)
    return msg_ids

def main():
    credentials = get_credentials()
    service = discovery.build('gmail', 'v1', credentials=credentials)
    user_id = "swierczyniec@gmail.com"

    page = 0
    while get_all_emails(service, user_id):
        page += 1
        print("Page: ", page)


if __name__ == "__main__":
    main()

PS: The hero image has been generated by DALL-E 2 with the prompt: robot writing code on a old computer

1 Reply

Have you written a response? Let me know the URL:

There's also indie comments (webmentions) support.