Draft Gmail in Python

Created on September 26, 2020. </ b>

environment

Windows10 home
Python 3.8.3
google-auth-oauthlib 0.4.1
google-api-python-client 1.12.2

Thing you want to do

I want to run Python in my local environment and create a draft in Gmail via API.

In this article, I'll write code with minimal error handling and no shit. Not bad.

procedure

The general procedure is as follows.

  1. Create a project with GCP
  2. Create credentials with GCP
  3. Creating a Python script

1. Create a project with GCP ~ 2. Create credentials

For 1 and 2, article → "Send and receive Gmail via Gmail API using Python" Is very easy to understand.

Basically, if you follow the article, there should be no problem, but in my case "When I access GCP with Vivaldi, client_ <id> .json cannot be downloaded "</ b> .. This could be avoided by using Chrome.

3. Creating a Python script

As a flow, Get an access token according to the OAuth authentication flow ↓ Create data for emails to send ↓ Hit the Gmail API to create a draft

It's like that.

1. Obtaining an access token

The minimum required function to get an access token is as follows. Reference → [API Authentication and Calling (Google Cloud Guide)](https://cloud.google.com/bigquery/docs/authentication/end-user-installed?hl=ja#authenticating-and-calling-the- api)

from google_auth_oauthlib.flow import InstalledAppFlow
#Set API scope(Setting which API to use)
SCOPES = ["https://www.googleapis.com/auth/gmail.modify"]

def get_credential():
    launch_browser = True
    flow = InstalledAppFlow.from_client_secrets_file("client_id.json", SCOPES)
    flow.run_local_server()
    cred = flow.credentials
    return cred

ʻInstalledAppFlow.from_client_secrets_filecontains the JSON file dropped from GCP and the API information you want to use to create aFlow instance, and when you do run_local_server () `, the browser will start up and the familiar permission screen will appear. スクリーンショット 2020-09-26 170859.jpg

Now press Allow and you will get an access token.

By the way, until now, the permission screen will be displayed every time the program is executed, so it seems convenient and convenient in practice to save the access token as a pickle.

2. Create an email draft


from email.mime.text import MIMEText
import base64

def create_message(sender, to, subject, message_text):
    enc = "utf-8"
    message = MIMEText(message_text.encode(enc), _charset=enc)
    message["to"] = to
    message["from"] = sender
    message["subject"] = subject
    encode_message = base64.urlsafe_b64encode(message.as_bytes())
    return {"raw": encode_message.decode()}

It's in the Gmail API docs Creating draft messages, but in the docs, the last line of the create_message function. But


return {'raw': base64.urlsafe_b64encode(message.as_string())}

It has become. However, since base64.urlsafe_b64encode () needs to include bytes instead of strings as input,

encode_message = base64.urlsafe_b64encode(message.as_bytes())

Since the str type is required in the process of changing to and saving it in the draft later

return {"raw": encode_message.decode()}

And decode.

3. Save the email data created by Gmail API as a draft

Add the data of the email you created earlier to the draft.


def create_draft(service, user_id, message_body):
    message = {'message':message_body}
    draft = service.users().drafts().create(userId=user_id, body=message).execute()
    return draft

The service used in this is like a masterpiece when using the Gmail API, and it is listed in Gmail API Reference. This is the instance that contains the function. This is made with the following code.


from googleapiclient.discovery import build

service = build("gmail", "v1", credentials=creds, cache_discovery=False)

If you combine the above into one program, it will look like the following.


from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build

import base64
from email.mime.text import MIMEText

SCOPES = ["https://www.googleapis.com/auth/gmail.compose",]


def get_credential():
    launch_browser = True
    flow = InstalledAppFlow.from_client_secrets_file("client_id.json", SCOPES)
    flow.run_local_server()
    cred = flow.credentials
    return cred


def create_message(sender, to, subject, message_text):
    enc = "utf-8"
    message = MIMEText(message_text.encode(enc), _charset=enc)
    message["to"] = to
    message["from"] = sender
    message["subject"] = subject
    encode_message = base64.urlsafe_b64encode(message.as_bytes())
    return {"raw": encode_message.decode()}


def create_draft(service, user_id, message_body):
    message = {'message':message_body}
    draft = service.users().drafts().create(userId=user_id, body=message).execute()
    return draft


def main(sender, to, subject, message_text):
    creds = get_credential()
    service = build("gmail", "v1", credentials=creds, cache_discovery=False)
    message = create_message(sender, to, subject, message_text)
    create_draft(service, "me", message)


if __name__ == "__main__":

    sender = "Email sender address"
    to = "Destination address"
    subject = "subject"
    message_text = "Text"

    main(sender=sender, to=to, subject=subject, message_text=message_text)

Doing this will add the draft to Gmail. You did it! (・ ∀ ・)

reference

・ The most helpful article https://qiita.com/muuuuuwa/items/822c6cffedb9b3c27e21

-Flow class and InstalledAppFlow class documentation google_auth_oauthlib.flow module

-Googleapiclient.discovery.build documentation https://googleapis.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build

Recommended Posts