Flow Launcherのプラグインを作ってNotionに手軽にToDoを追加する



はじめに

今年の目標として「ライフログを取る」という目標を立てており、年始に公開した記事のようにショートカットキーを作って簡単に情報を保存したり、あとは1月頭に友人に教えてもらったDaylio( https://apps.apple.com/jp/app/daylio-%E6%97%A5%E8%A8%98/id1194023242 )というアプリで今のところ毎日欠かさず日記を付けたりして、割と達成できている感じがある。

本当は別の絵文字も使いたいのにiPhoneがぶっ壊れていて使いたい絵文字をタッチできない

ただし記事でも言及していたように、総覧を作ったり、あとは例えばToDoリストのような総覧があること前提の記録をしたりというのは全然できておらず方法を色々と考えていた。

そこで先日ボーっとyoutubeを見てたら「Notionを使った最強タスク管理術!」みたいなのが目に入ってきて確かに使えるかもな~と思い触ってみたが、いちいちNotionのページを開いてデータベースの項目をクリックして入力して…というのがめんどくさすぎる。ショートカットキーみたいにほぼワンボタンで完結させたい。

で、それについては動画でも同様の言及があり、Alfredとの連携を提言していた。

AlfredはMacOS向けのランチャーアプリで、ショートカットキーでメニューを呼び出せばそこからあれやこれやの動作をコマンドで実行できる素晴らしいやつである。

https://apps.apple.com/jp/app/alfred/id405843582

これでコマンド入力だけでNotionを更新しよう!という提言であり、これはかなり魅力的に思えた。

ただし書いてあるようにMacOS向けであり、基本的にWindowsで作業しているため別の代替アプリが欲しい。

そこで目をつけたのがFlow Launcher。

他にもランチャーアプリは色々あるのだが、今回やりたいのは自作の機能を追加することなので、プラグインを自作できてかつそのガイドがある程度シンプルにまとまっているFlow Launcherを使うことにした。


NotionでTODO データベースを準備する

まず手始めにNotionのデータベースを用意する。

ページ作成時に「テーブル」の項目があるので、それを選ぶ。

するとテーブルビューが作成されるので、これをデータベースとして更新していく。

テーブルのタイトルやカラム名は適当に設定


インテグレーションを追加する

これを外部からAPIで更新するにはインテグレーションを作成する必要がある。

以下のページで「新しいインテグレーションを作成する」を選択し、先程データベースを作成したワークスペースを選択してインテグレーションの名称を設定する。

インテグレーションを作成するとシークレットトークンの表示画面になるのでこれを取得しておく(後からでも確認し直すことが可能)。

その後データベースのページに戻り、作成したインテグレーションとの連携を行う。

ページ右上のメニューボタンから「コネクトの追加」を選択すると先程作成したインテグレーションを選択できるのでこれを選択。これによりトークンを使ってこのページを更新できる。

データベースのdatabase_idを取得する

データベースを更新する際に対象のデータベースを指定するためにデータベース固有のidを取得する必要がある。

そのために、まずデータベースのページタブを右クリックして「ビューのリンクをコピー」でリンクをコピーする。

リンクは以下のような形式になっているため、"?v="より前の部分をdatabase_idとして取得しておく。

https://www.notion.so/{ワークスペース名}/{database_id}?v=…

Flow Launcherプラグインの作成

プラグインはjs, ts, pythonなどで書けるが、今回はpythonで作成する。
公式ドキュメントは以下。

プラグインのプロジェクトは最低限以下のような構成になっていれば良い。

./PluginFolder
├── Images
│  └── icon.png
├── lib
├── main.py
├── plugin.json
└── requirements.txt


plugin.jsonにはコマンド実行に必要な情報を書く。

{
    "ID": "適当なUUID",
    "ActionKeyword": "stn",
    "Name": "Send To Notion",
    "Description": "Update Notion Database",
    "Author": "watagasi_",
    "Version": "1.4.0",
    "Language": "python",
    "Website": "",
    "IcoPath": "assets//icon.png",
    "ExecuteFileName": "main.py"
}

IDは他のプラグインと値が被った場合機能しなくなるので、適当なUUIDを設定しておく。
ActionKeywordは今回のアクションを行う際のコマンドを書いておく。


requirements.txtには実行に必要なライブラリを書く。今回はFlow Launcherのプラグイン作成をサポートするflowlauncherと、POST通信をするのでrequestsを書いておく。

flowlauncher
requests


main.py 

# -*- coding: utf-8 -*-

import requests
import json
import sys
import os

from flowlauncher import FlowLauncher

parent_folder_path = os.path.abspath(os.path.dirname(__file__))
sys.path.append(parent_folder_path)
sys.path.append(os.path.join(parent_folder_path, 'lib'))

class Send(FlowLauncher):

    def query(self, query):
        return [
            {
                "Title": "Send to Notion. {}".format(('register: ' + query , query)[query == '']),
                "SubTitle": "Register word to Notion Database",
                "IcoPath": "Images/icon.png",
                "JsonRPCAction": {
                    "method": "send",
                    "parameters": [query]
                }
            }
        ]

    def send(self, query):
        q = query.strip()
        args = q.split(" ")
        if len(args) == 1:
            url = 'https://api.notion.com/v1/pages'
            headers = {
                'Authorization': 'Bearer {シークレットトークン}',
                'Content-Type': 'application/json',
                'Notion-Version': '2022-06-28'
            }
            data = {
                "parent": {
                    "database_id": "{データベースID}"
                },
                "properties": {
                    "{更新するカラム名}": {
                        "title": [
                            {"text": {"content": q}}
                        ]
                    },
                }
            }
            try:
                response = requests.post(url, headers=headers, json=data)

            except Exception as e:
                print(f"エラー: {e}")


if __name__ == "__main__":
    Send()

めんどくさがってるけど各々エラーハンドリングはちゃんとやっておいてください。

今回の場合はカラム1つを更新することだけしか想定していないが、複数更新したい場合はFlow LauncherとNotionのドキュメントを参照してクエリの処理と送信するデータの処理を良い感じにしてもらえれば。

あとはicon.pngにメニュー画面でのアイコンを設定し、libにpythonのライブラリをインストールしておく。

libの設定の仕方は多分プラグインのプロジェクトフォルダ内で

pip install -r requirements.txt -t ./lib

を実行するのが一番ラクなはず。

この際に使用したpythonのパスをFlow Launcherで設定しておけば実行環境は問題なし。

あとは"%APPDATA%\Roaming\FlowLauncher\Plugins\"にプロジェクトフォルダを配置してFlow Launcherを再起動するか「Reload Plugin Data」のコマンドを実行すれば読み込まれる。


あとはFlow Launcherでコマンド実行すればデータベースに登録可能!


まとめ

地味に日本語で手順の記事とかがまとまってなかったので書きたかった。これができればあらゆる行為をコマンド化出来るし色々試したい。

自分で入力するようなものはだいたいラクになってきたので、あとは自身のデータの自動取得とそれをまとめる方法、そしてそこから高速にフィードバックを得る方法などを模索したい。



参考


この記事が気に入ったらサポートをしてみませんか?