notebook

都内でWEB系エンジニアやってます。

NotionのAPIを使ってTimeTrack機能を付けてみる

最近FLEXISPOTの電動昇降机を買ったので会議のときとか気分を変えたいときなど立ち姿勢で仕事することが増えた

そして、1日どれくらい立ち姿勢で仕事していたか測りたくなってきた

ちょうどNotionを使って習慣化や目標を管理していたのでどうせならNotionの中で見たいということで、最初はデータベース作って都度時刻を入力していたが時刻確認してNotionに移動して入力してというのが結構面倒だった

TypeScript + Notion JavaScript SDK + dayjsでさっとコード書いてなんとかできそうだったので雑だがスクリプトを書いた

基本的に机を昇降する際はPC開いている前提なのでローカルからスクリプトたたいて記録するようにしている

さっそくだがコードは下記

  • app.ts
import {Client} from "@notionhq/client";
import dayjs from "dayjs";

const lastRecord = async(notion: Client, databaseId: string) => {
  const res = await notion.databases.query({
    database_id: databaseId,
    sorts: [
      {
        property: "lastUpdate",
        direction: "descending"
      }
    ]
  })

  return res.results[0];
}

const record = async() => {
  const args = process.argv.slice(2);
  const specifiedTime = args[0];

  const notion = new Client({
    auth: process.env.NOTION_TOKEN
  });

  const databaseId = process.env.NOTION_DATABASE_ID;
  const today = dayjs().format('YYYY-MM-DD')
  const now = specifiedTime !== "" ? dayjs().format("YYYY-MM-DD HH:mm:ss") : dayjs().format(`YYYY-MM-DD ${specifiedTime}:00`)

  const record = await lastRecord(notion, databaseId);

  if(record.properties?.time?.date?.end !== null) {
    notion.pages.create({
      parent: {
        database_id: databaseId
      },
      properties: {
        date: {
          title: [
            {
              type: "text",
              text: {content: today}
            }
          ]
        },
        time: {
          date: {
            start: now,
            time_zone: "Asia/Tokyo"
          }
        }
      }
    })
  }
  else {
    const startTime = dayjs(record.properties.time.date.start).format("YYYY-MM-DD HH:mm:ss")
    notion.pages.update({
      page_id: record.id,
      properties: {
        time: {
          date: {
            start: startTime,
            end: now,
            time_zone: "Asia/Tokyo"
          }
        }
      }
    });
  }
}

const initial = async() => {
  const notion = new Client({
    auth: process.env.NOTION_TOKEN
  });

  const pageId = process.env.NOTION_PAGE_ID;

  const database = await notion.databases.create({
    title: [
      {
        text: {content: "Time Record"}
      }
    ],
    parent: {
      type: "page_id",
      page_id: pageId
    },
    properties: {
      date: {
        title: {}
      },
      time: {
        date: {}
      },
      lastUpdate: {
        last_edited_time: {}
      },
      minute: {
        formula: {
          expression: `dateBetween(end(prop("time")), start(prop("time")), "minutes")`
        }
      }
    }
  })

  console.log(`Created Database. id: ${database.id}`);
}

(async() => {
  await initial()
  // await record()
})();
  • 実行
ts-node -T app.ts

1度目の実行でレコード作成、開始時刻を記入、2度目の実行で既存レコードの終了時刻を記入という感じ

TypeScriptで書いておきながら-Tオプションを付けて実行時の型チェックは回避している…

環境変数

3つ使用している

環境変数名 説明 使用箇所
NOTION_TOKEN APIをたたく際に必要 initial,record
NOTION_PAGE_ID データベースを作成する対象のページID initial
NOTION_DATABASE_ID 対象データベースのID record

APIトークンの生成方法は他にも記事がたくさんあるので今回は割愛する

データベースの作成

initial()は最初にDBを作成する処理

formulaの計算式も書いておくことができる

記録

record()で記録処理を行っている

NotionのDateカラムはstart,endを設定できるのでカラム1つに開始、終了の時刻を記録する

見た目の調整

スクリプトを実行しただけだとただただページのリンクが表示されているだけなので下記の作業を行う

APIでこのあたりの機能は提供されてなさそうなので今後追加されたら完全に自動化できるはず

  • Turn into inlineで対象ページからインラインでテーブルの中身を見れるようにする

f:id:swfz:20220211011742p:plain

  • グループ化はdate列でグループ化しておく、グループ化の種類はExactに変更する

f:id:swfz:20220211011748p:plain

  • minute列のCalculateをSumにする

ここまでやると使えるようになる

実際に何度か実行してみたらこんな感じ

「2月6日は11分立ち姿勢で作業している」ということが分かる

f:id:swfz:20220211011753p:plain

手動な部分はあるが最低限計測可能になったので良し

おわり

色々調べていく中で、FLEXISPOTの机自体に端子が用意されているようで、それにつないでごにょごにょして色々できる!

みたいな記事もみたが今回はさっとわかればよいだけだったのでとりあえずスクリプト書いて解決した

NotionのJavaScript SDKに型情報がしっかり記述してありリクエスト時に必要なパラメータなどの確認に便利だった

何かの参考になれば…