LoginSignup
0
0

More than 1 year has passed since last update.

Notonのページの最終変更の内容を取得してみる

Last updated at Posted at 2022-12-07

専用のAPIがあればいいですけど、ウォッチ系のAPIは無さそうなので実装してみます

Page IDからブロックIDを取得する

Notionだとページの中身を取得するAPIが無い模様です。

ブロックという概念になっていてブロックに対してAPIを使っていくみたいですね。

こちらの記事の概念図がすごく分かりやすかったです。

Retrieve block children

Database > Page > Blockといった階層構造のイメージで大丈夫だと思います。

めちゃめちゃpage.contentみたいな感じで一発で取得したいですが...苦笑

親のBlockIDはPageIDでOK

ということでBlockの中身を取りたいのですが、APIのサンプルをみるとこれが分からなくて最初戸惑いました。

サンプルだとこのような形でブロックIDを指定して子要素を取得せよ、みたいなサンプルになってますが、重要な親のBlockIDをPageIDから取得する方法がわかりませんでした。

const blockId = `ブロックID`;
const response = await notion.blocks.children.list({block_id: blockId});

const blockId = `ページIDでOK`;
const response = await notion.blocks.children.list({block_id: blockId});

こんな感じでページIDを指定してみたらそのまま動いてくれたので親のBlockID = PageIDの模様です。

const main = async () => {
    const response = await notion.databases.query({
        database_id: studentDBId,
        filter: {
          or: [
            {
              property: '学籍番号',
              rich_text: {
                contains: 'po-07'
              }
            }
          ],
        },
    });
    const items = response.results;
    
    //ここまではDatabaseオブジェクト
    
    //Retrieve block childrenだけどPageIdをそのままBlockIDとしてAPI呼び出し
    const users = [];
    for await (const item of items) {
        const blockId = item.id; //本来はpageid
        const response = await notion.blocks.children.list({
          block_id: blockId,
          page_size: 50,
        });
        users.push(response.results);
    }
    
    console.log(user[1]); //二人目のUserページの中身

}

main();

これでブロックが丸っと取得できます。

last_edited_timeでソート

ブロックのリストが入っている状態になりますが、最終変更の時間はlast_edited_timeに入ってるのでソートします。


省略
    const obj = users[1];
    // console.log(users[1]);

    //最終編集が新しい順でソート
    const result = Object.keys(obj).map(function(key) {
        return obj[key];
    }).sort(function(a, b) {
        return (a.last_edited_time > b.last_edited_time) ? -1 : 1;
    });

Blockのタイプによってオブジェクトのキーが変わる

Notionのブロックは箇条書きや段落、画像など色々な種類がありますが、種類によってAPIが返してくるデータの形も変わってしまいます。

箇条書きの場合はobj.bulleted_list_itemになり、通常のテキスト(段落)の場合はobj.paragraphを参照する形になるという、厄介な仕様です。

  • 箇条書き
{
  object: 'block',
  id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
  parent: { type: 'page_id', page_id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx' },
  created_time: '2022-12-03T06:58:00.000Z',
  last_edited_time: '2022-12-07T08:08:00.000Z',
  created_by: { object: 'user', id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx' },
  last_edited_by: { object: 'user', id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx' },
  has_children: false,
  archived: false,
  type: 'bulleted_list_item',
  bulleted_list_item: { rich_text: [ [Object] ], color: 'default' }
}
  • 段落
{
  object: 'block',
  id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
  parent: { type: 'page_id', page_id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx' },
  created_time: '2022-12-03T06:58:00.000Z',
  last_edited_time: '2022-12-07T08:08:00.000Z',
  created_by: { object: 'user', id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx' },
  last_edited_by: { object: 'user', id: 'xxxxxxxxxxxxxxxxxxxxxxxxxx' },
  has_children: false,
  archived: false,
  type: 'paragraph',
  paragraph: { rich_text: [ [Object] ], color: 'default' }
}

ということでこんな感じでtypeのキーをもとに情報を持ってきます。


省略

    const last_edited_block = result[0]; //最新の変更があったブロック

    const lastUpdateType = last_edited_block.type;
    const lastUpdateContent = last_edited_block[lastUpdateType];
    const lastUpdateText = lastUpdateContent.rich_text[0].plain_text;

    console.log(`${last_edited_block.last_edited_time}に変更がありました。 -> ${lastUpdateText}`);

結果

2022-12-07T08:08:00.000Zに変更がありました。 -> aaaa

スクリーンショット 2022-12-07 17.29.56.png

箇条書きでaaaaと書いた内容が最新の変更なのでうまく取れてそうでした。

所感

とりあえずできた!って感じです。

Blockは一つのページの中で複数存在する形になっていくので、データベースから検索をかけてくると入れ子構造がエグい感じになっていきますね。

どなたか一発取得のやり方でもっと良い方法あれば教えてください苦笑

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0