【画像で説明】AlfredからGoogleTasks(ToDo)にタスクを追加するWorkflowをPythonで作る

公開:2020/11/07
更新:2020/11/15
10 min読了の目安(約9100字TECH技術記事

やりたいこと

こうしたら

スクリーンショット 2020-11-07 4 52 58"


こうっ

スクリーンショット 2020-11-07 4 53 09"


こうしたら

スクリーンショット 2020-11-07 4 53 23"


こうっ

スクリーンショット 2020-11-07 4 53 34"

前提条件

今回説明するworkflowは無料版では使えない機能のため、Powerpackの購入が必要となります。
Powerpackの料金は2020-11-15現在のレートで約¥6,770でした。

GCPアカウントの作成

Google Tasks APIを使うためにGCPアカウントが必要になります。

無料アカウントの作成方法

認証準備

Quickstartをつかう方法

こちらのクイックスタートを利用すると、

  • GCPプロジェクトの作成
  • Tasks APIの有効化
  • OAuth2.0クライアントIDの作成
  • 認証キー(credentials.json)のダウンロード

をまとめて行うことができます。

スクリーンショット 2020-11-06 22 26 18

スクリーンショット 2020-11-06 22 34 13

とりあえずDesktop appで問題ありませんでした。

スクリーンショット 2020-11-06 22 34 47

スクリーンショット 2020-11-07 2 02 59"

通常のプロジェクト作成 ~ 認証キー取得まで

プロジェクト作成

スクリーンショット 2020-11-07 2 14 20"
スクリーンショット 2020-11-07 2 14 43"

Tasks APIの有効化

スクリーンショット 2020-11-07 2 11 45"

スクリーンショット 2020-11-07 2 24 01"

スクリーンショット 2020-11-07 2 24 26"

OAuth2.0クライアントIDの作成

スクリーンショット 2020-11-07 2 29 16"

スクリーンショット 2020-11-07 2 38 46"


こんな画面が出てきますが、この情報は今回は不要です。

スクリーンショット 2020-11-07 2 39 14"

認証キー(credentials.json)のダウンロード

スクリーンショット 2020-11-07 2 39 39"

AlfredのWorkflowを作る

ここからはAlfredの設定画面をさわっていきます。

スクリーンショット 2020-11-06 20 24 49

スクリーンショット 2020-11-06 20 28 39

⇣ ひとまずNameだけあれば大丈夫です。

スクリーンショット 2020-11-06 21 01 07

/Users/ユーザー名/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/ の中に user.workflow.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/みたいなディレクトリが作られます。
このディレクトリがAlfredからPythonファイルを実行するさいのカレントディレクトリになります。

Pythonファイルの作成

先程のuser.workflow.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/ディレクトリの中に好きな名前でファイルを作ります。
今回はadd_task.pyというファイルで。

$ cd /Users/ユーザー名/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

$ touch add_task.py

さきほどダウンロードした credentials.jsonadd_task.py と同じディレクトリに置きます。

ライブラリのインストール

  • google-api-python-client
  • google-auth-httplib2
  • google-auth-oauthlib

の3つが必要。

$ pip install --target=. google-api-python-client google-auth-httplib2 google-auth-oauthlib

user.workflow.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/ディレクトリの中で、pip installします。
--targetオプションで.(カレントディレクトリ)を指定することで、ディレクトリ内に依存ライブラリを含む一式をインストールできます。
このやり方でないと、not found的なエラーで一生前に進めませんでした。
仮想環境を使うやり方などありましたら教えて下さい🙇

コード

クイックスタートのコードをベースにしています。

from __future__ import print_function
import pickle
import os.path
import sys
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

SCOPES = ['https://www.googleapis.com/auth/tasks']


def main():
    """Shows basic usage of the Tasks API.
    Prints the title and ID of the first 10 task lists.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                './credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('tasks', 'v1', credentials=creds)

    # Call the Tasks API
    results = service.tasklists().list(maxResults=10).execute()
    items = results.get('items', [])

    title = sys.argv[1]

    if items:
        task = {
            'title': title,
        }
        result = service.tasks().insert(tasklist='@default', body=task).execute()


if __name__ == '__main__':
    main()

以下、主な変更点です。

タスク追加用にスコープを変更しています。

...
SCOPES = ['https://www.googleapis.com/auth/tasks.readonly']
⇣
SCOPES = ['https://www.googleapis.com/auth/tasks']
...

コマンドライン引数でタスク名を渡し、タスクに追加するように改変しています。

title = sys.argv[1]

if items:
    task = {
        'title': title,
    }
    result = service.tasks().insert(tasklist='@default', body=task).execute(

Workflowの中身

スクリーンショット 2020-11-07 3 18 15

Keywordを指定

スクリーンショット 2020-11-07 3 18 31

KeywordはAlfredの先頭に打ち込む文字列。
ここではtask hoge でhogeがタスクとして追加されるようになる。

スクリーンショット 2020-11-07 3 21 10

次は、Action > Run Script

スクリーンショット 2020-11-07 3 21 39

実行するPythonファイルを指定する。

スクリーンショット 2020-11-07 4 06 21

ドラッグして繋げば完成

スクリーンショット 2020-11-07 3 22 33

動作確認

試してみる。

スクリーンショット 2020-11-07 4 30 23"

初回は認証が必要。

スクリーンショット 2020-11-07 4 28 29

スクリーンショット 2020-11-07 4 31 01

スクリーンショット 2020-11-07 4 31 07

許可で。

スクリーンショット 2020-11-07 4 31 31

許可で。

スクリーンショット 2020-11-07 4 31 48

こんな画面になったら認証完了。
閉じる。

スクリーンショット 2020-11-07 4 32 06

改めまして

スクリーンショット 2020-11-07 4 30 23"

成功。

スクリーンショット 2020-11-07 4 44 01"

Oauth認証は2回目以降は不要です。
初回認証時に token.pickleというファイルが生成され、認証情報が保存されているようです。

参照

ありがとうございました。