タスク管理の再検討(2) synced block の自動差し替え : Notion 解説(50)

はじめに

前回、タスク管理を再検討するという話を書きました。hkob.hatenablog.com

これを実現するために、NotionRubyMapping に append_block_children を実装しました。あとは、update_block や delete_block などを実装する必要がありますが、この検討をした上で必要なところから実装していこうと思います。この際、NotionRubyMapping に追加で実装した機能はここで紹介してみます。適宜キリのいいところでリリースしますが、一部未リリースの機能を使っている場合もあります。

仕様が大きく一回の記事では終わりそうもないので、何回かに分割して公開します。今回は、まず synced block の自動差し替えを実装することにします。なお、スクリプトは冪等性があるものとして、特に変更なければ何も実行せず、ページなどが更新されていれば、適宜関連するブロックが更新される仕組みを目指します。

作業1. タスク一覧ページを取得または作成

マエダさんのメソッドでは、その日が終わったらブロックをデータベースにドラッグすることでページに変更していました。この処理は API では難しいので、Synced block を活用することにします。

まずは毎日のタスクデータベースに今日のタスク一覧ページを作成します。存在しない場合には、自動生成します。今はデータベースは空の状態です。

毎日のタスクデータベース

処理の最初はこちらになります。NOTION_API_KEY の登録から始まり、上記のデータベースから今日の「タスク一覧ページ」を取得します。今回の場合には存在していないので、create_child_page で日付から作成されます。日付欄があるので、タイトルに日付を付けるのもどうかとは思いますが、タイトルには興味はないので、このままでいきます。

#!/usr/bin/env ruby

require "notion_ruby_mapping"
include NotionRubyMapping

# NotionCache シングルトンを生成し、NOTION_API_KEY を登録
NotionCache.instance.create_client ENV["NOTION_API_KEY"]

#### 1. タスク一覧ページを取得または作成
# 今日を取得
today = Date.today
today_str = "#{today.strftime("%-m月%-d日")}(#{%w[日 月 火 水 木 金 土][today.wday]})"

# 「毎日のタスク」データベースを取得
dt_database = Database.find "0bcdd69abaa6471683a0d54e28577900"

# 日付プロパティを取得
dp = dt_database.properties["日付"]

# 日付が今日の「タスク一覧ページ」を取得
today_dt = dt_database.query_database(dp.filter_equals(today)).first

# 存在しなかった場合には、今日の「タスク一覧ページ」を作成
today_dt || = dt_database.create_child_page do |_, pc|
  pc["名前"] << today_str
  pc["日付"].start_date = today
end

このプログラムを実行したところ、毎日のタスクが生成されました。なお、冪等性からもう一度実行しても、今作成したページがそのまま取得できるだけです。明日になると新しいページが作成されます。

生成された「タスク一覧」ページ

作業2. タスク一覧ページの Synced block を取得または作成

今作成したページを覗くと空のページになっています。

生成された空のページ

このページは Synced block の親ページになります。ページの children を調べて synced block がなければ作ります。ブロックがオリジナルの synced_block なのかを調べるメソッド synced_block_original? を追加しました。

#### 2. タスク一覧ページの Synced block を取得または作成

# タスクページ一覧の Synced block を取得
synced_block_original = today_dt.children.select(&:synced_block_original?).first

# 存在しなかった場合には、オリジナルの Synced block を作成。中身は日付文字列だけ書いておく。
synced_block_original ||= today_dt.append_block_children(
  Block.new.synced_block(sub_blocks: [Block.new.paragraph(today_str)]),
)

実行すると synced block が作成されました。二回目の実行では、すでに取得済の synced_block が取得されていることも確認しています。

作成されたオリジナルの synced_block

作業3. 今日のタスク Synced block の差し替え

今日のタスクは先ほどのタスク一覧の Synced block のコピーが置かれる予定です。日付が変わったら、この Synced block を削除して、先ほど作ったものに置き換えたいと思います。今日のタスクは見出し1のトグルブロックになっていて、この ID で子供を検索することにします。

今日のタスク Synced block

まずはトグルブロックの子供を全て取得します。その後、子供の中に先ほどの Synced block があるかを確認します。あった場合には何もせずに終了します。なかった場合には、存在している子供のブロックを全部消して、先ほどの synced block のコピーを作成します。まだ、Block の削除を作成していなかったので、NotionRubyMapping に機能を追加します。API の名前は delete block ですが、Rails を使っている人は destroy の方が馴染み深いと思うので、メソッド名は destroy の方にしました。

#### 3. 今日のタスク Synced block の差し替え

# トグルブロックを取得
toggle_block = Block.find("f1b63bd647cd4d76b8086f5e4cd161ba")

# トグルブロックの子供の ID を全部取得
toggle_children = toggle_block.children

# Synced block のオリジナルの id を取得し、それが今日のものならスキップ
unless toggle_children.map(&:synced_block_original_id).include? synced_block_original.id
  # 今日のものでなければトグルブロックの子供を全部削除
  toggle_children.each do |block|
    block.destroy
  end

  # 今日の Synced block に置き換え
  toggle_block.append_block_children Block.new.synced_block(block_id: synced_block_original.id)

end

実行すると以下のように Synced block が差し替えられました。2回目は差し替えられずにそのまま残っていました。実装をモタモタしていたので、すでに1日ずれてしまいましたね。

差し替えられた Synced block


www.notion.so