NotionTimeRecorder の作成 - Notion 解説 (74)

(1/13追記) ステータスプロパティで運用している場合の質問があったので、変更点を追記しました。また、日付が設定されていない時にエラーが出るようになっていたので修正しました。 (2/14追記) クリック後に空の画面が出るのが邪魔だったので、該当ページへのリンクを表示するように改修しました。こちらを参照してください。 hkob.hatenablog.com

1. はじめに

先日、Formula の結果がリンクの場合に、クリックでリンク先に飛べるように改良されました。Red Gregory さんが、それを使った様々な検索 (マップ, Google, Wikipedia など) のテクニックを紹介していました。

これで実現できるのは、GET でのアクセスに制限されます。ただ、Notion の page_id 程度の情報であれば URL に見えてしまっていいだろうということで、こんなサービスを作ってみました。

基本的には、これまでショートカットや Ruby アプリで作ってきた NotionTimeRecording です。機能としては単純で以下の二つの作業しかしません。

  1. 日付がないか、開始時間が設定されていなければ、開始時刻を現在時刻に設定する。
  2. 開始時刻が設定されていたら、終了時刻を現在時刻に設定し、完了チェックボックスをチェックする。

これによってタスクの開始と終了の時刻をページの日付プロパティにセットできることになります。今回は、NotionTimeRecorder という名前をつけました。

2. GAS の設定

スクリプトは以下のようになっています。test() の中にはテスト用のページ ID を記録しておいてください。また、日付プロパティの名前とチェックボックスプロパティの名前は自分のものに合わせてください。変更点はそこだけです。

// テスト用のページ ID で実行用テスト
function test() {
  doGet({"parameter": {"id": "d811b3b61ec342a191e8ed0c4e4ab9f7"}})
}

// GET アクセスした時のエントリー関数
function doGet(e) {
   const id = e.parameter.id
   timeRecording(id)
}

// 日付プロパティの名前
function datePropertyName() {
  return "日付"
}

// チェックボックスプロパティの名前
function checkBoxPropertyName() {
  return "Done"
}

// NOTION_API_KEY を取得
function notionAPIKey() {
  return PropertiesService.getScriptProperties().getProperty("NOTION_API_KEY")
}

// Notion に payload を send する
function sendNotion(url_sub, payload, method) {
  const options = {
    "method": method,
    "headers": {
      "Content-type": "application/json",
      "Authorization": "Bearer " + notionAPIKey(),
      "Notion-Version": "2022-06-28",
    },
    "payload": payload ? JSON.stringify(payload) : null
  };
  // デバッグ時にはコメントを外す
  // console.log(options)
  Utilities.sleep(400)
  const url = "https://api.notion.com/v1/" + url_sub
  return JSON.parse(UrlFetchApp.fetch(url, options))
}

// Retrieve a Page API を呼び出す
function retrievePage(page_id) {
  return sendNotion("pages/" + page_id, null, "GET")
}

// Update Page API を呼び出す
function updatePage(page_id, payload) {
  return sendNotion("pages/" + page_id, payload, "PATCH")
}

// 時間記録本体
function timeRecording(id) {
  const date_name = datePropertyName()
  console.log(date_name)
  const page = retrievePage(id)
  const now = new Date().toLocaleString("sv-SE", { timeZone: "Asia/Tokyo" }).replace(" ", "T") + "+09:00"
  const date_property = page.properties[date_name]["date"]
  if (date_property == null || date_property["start"].indexOf("T") == -1) {
    sd = now
    ed = null
    finish = false
  } else {
    sd = date_property["start"]
    ed = now
    finish = true
  }
  const payload = {}
  payload[date_name] = {"date": {"start": sd, "end": ed}}
  payload[checkBoxPropertyName()] = {"checkbox": finish}
  return updatePage(id, {"properties": payload})
}

(1/13追記) タスクをステータスで運用している場合の質問があったので、その場合には以下のように変更してください。進行中や完了が "In Progrss" や "Done" でない人はそれも変えてください。checkBoxPropertyName の関数名が気持ち悪い人はそこも直してください。

function timeRecording(id) {
  const date_name = datePropertyName()
  console.log(date_name)
  const page = retrievePage(id)
  const now = new Date().toLocaleString("sv-SE", { timeZone: "Asia/Tokyo" }).replace(" ", "T") + "+09:00"
  const date_property = page.properties[date_name]["date"]
  if (date_property == null || date_property["start"].indexOf("T") == -1) {
    sd = now
    ed = null
    finish = "In Progress"
  } else {
    sd = date_property["start"]
    ed = now
    finish = "Done"
  }
  const payload = {}
  payload[date_name] = {"date": {"start": sd, "end": ed}}
  payload[checkBoxPropertyName()] = {"status": {"name": finish}}
  return updatePage(id, {"properties": payload})
}

2. スクリプトプロパティの設定

設定の画面でスクリプトプロパティを設定します。NOTION_API_KEY というキーに対して、インテグレーションキーを設定します。

スクリプトプロパティの設定

3. テスト実行

最初に test 関数を実行してみてください。テストページの日付プロパティに現在時刻が格納されることを確認してください。もう一度 test 関数を実行すると今度は終了時刻が格納され、チェックボックスにチェックが付きます。

これが動いたらウェブアプリ化します。

4. デプロイ

右上のデプロイから「新しいデプロイ」を選択します。ウェブアプリを選択し、説明文を設定したら「デプロイ」します。

デプロイ

デプロイしたら、Web アプリの URL が表示されます。

Web アプリの URL

5. Notion Formula の設定

最後に Notion の関数プロパティを追加します。先ほどの URL の後ろに ?id= という文字列を追加し、さらに id() の結果を文字列に追加します。

リンク用の Formula

6. おわりに

これで完成です。日付なしタスクや日付だけのタスクに対して、時間が記録できるのはかなり便利だと思います。


hkob.notion.site