2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NotionAdvent Calendar 2022

Day 17

ブログの改造をしてたらいつの間にかNotion APIの虜になってた

Last updated at Posted at 2022-12-14

こちらはNotion Advent Calendar 2022の17日目です。

こんにちはhoromi(@mineral_30)です。

私はNotion APIが大好きです。
でもNotionも好きです。

なぜNotion APIが好きになったかというと
easy-notion-blogがキッカケでした。
Screenshot 2022-12-14 at 18.54.34.png
https://github.com/otoyo/easy-notion-blog

今ではeasy-notion-blogのコミュニティ運営をしたり
ちょっとしたPRを本家に送ってニヤニヤしたり
ドハマリ中なhoromiではありますが

はじめから
こんな改造オタクではありませんでした。

この記事では
それまでに至ったNotion遍歴を紹介させていただこうと思います。

私のNotionはまず交換日記から始まりました。

気の合う仲間と交換日記

本当に気の合う仲間のみで始めたteamプラン(現 プラスプラン)。

コメント機能をとことん使い続ける...
といった運用の仕方でしたが
招待制SNSのような感覚で楽しめました。

プログラミングを趣味で始めたメンバーで
構成されていて

いつも
「今何の勉強してるの?」というコメントから
話題が発展していきます。

全員が全く同じ課題に取り組むことは稀で
大抵がバラバラ。

でも興味はある。

だから気になる。

そんな感じで
Twitterやネットなどで見つけた話題や
オススメの本なども紹介し合ったりと
交流を続けてかれこれ1年10ヶ月。

特にルールもなく
気になった人がDBに収納したり
ブロック制限に近づいてきたら
専用アカウントに移動させたり
なんとなくゆるく運用しています。

Screenshot 2022-12-14 at 15.43.16.png

勉強したことをNotionに書き溜める習慣がついてきた時期に
「ブログにして公開したい」
という欲が出てきました。

ヘッドレスCMS_easy-notion-blog

Notionに書き溜めたのに
わざわざ編集画面を開いて作業をするのは面倒です。

ブログを続けられたためしがなかったので
極力手間の少ないやり方でできるやり方は無いかと探しました。

そんな時
発見したのがeasy-notion-blogでした。

NotionDBに収納して
それを記事として公開できる!!

デザインも
自由に改造できて
無料\(^o^)/

Screenshot 2022-12-14 at 16.05.02.png

改造したくなるデザインというのがまた憎いッwww

結果的に改造に改造を重ねてこうなりました。
Screenshot 2022-12-14 at 16.08.38.png

「これ作りたい!!」

という欲求のままに
コードを解読して
分からない部分は勉強して
作ってみて
失敗して
エラーに泣かされ
気づけばあっという間の1年でした。

Notionのデータを使って
ブログに表示させているので
改造していく中で
Notion APIについても分かるようになってきたので

代表的なNotion APIメソッドをいくつか紹介します。

NotionDB内Pageを取得する_Query a database

Screenshot 2022-12-14 at 16.20.28.png
https://github.com/otoyo/easy-notion-blog/blob/main/lib/notion/client.ts#L69

これは
NotionDBに入れられたPageを全て取得するための関数です。

Notionからは以下のような状態になっています。
Screenshot 2022-12-14 at 16.23.10.png

公式リファレンスでは以下のように明記されています。
Screenshot 2022-12-14 at 16.26.29.png
https://developers.notion.com/reference/post-database-query

const { Client } = require('@notionhq/client');

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

(async () => {
 const databaseId = 'd9824bdc-8445-4327-be8b-5b47500af6ce';
 const response = await notion.databases.query({
   database_id: databaseId,
   filter: {
     or: [
       {
         property: 'In stock',
         checkbox: {
           equals: true,
         },
       },
       {
         property: 'Cost of next trip',
         number: {
           greater_than_or_equal_to: 2,
         },
       },
     ],
   },
   sorts: [
     {
       property: 'Last ordered',
       direction: 'ascending',
     },
   ],
 });
 console.log(response);
})();

このコードを使って実装するには
キャッシュの知識が必要だということに気づくことができました。

また
変数で整理していく様子も見て学ぶことができるので
自分で改造する時に
「分かりやすく書いていこう!」という意識で取り組めました。

queryメソッドはlib/notion/client.tsx で沢山使われているので
ブログには無くてはならない存在なんだなということも知れました。

Page内のBlockを1つ取得する_Retrieve a block

Screenshot 2022-12-14 at 16.39.06.png
https://github.com/otoyo/easy-notion-blog/blob/main/lib/notion/client.ts#L416

NotionのPageが記事の内容になるんですが、
その中には様々なBlockが含まれています。

それをswitchで条件反射させて取得していく様子を見ることができます。

公式リファレンスでは以下のように明記されています。
Screenshot 2022-12-14 at 16.44.14.png
https://developers.notion.com/reference/retrieve-a-block

const { Client } = require('@notionhq/client');

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

(async () => {
  const blockId = 'c02fc1d3-db8b-45c5-a222-27595b15aea7';
  const response = await notion.blocks.retrieve({
    block_id: blockId,
  });
  console.log(response);
})();

Block内で入れ子にする場合にはもっと複雑になります。

Block内の入れ子も含めて取得する_Retrieve block children

Screenshot 2022-12-14 at 17.26.16.png
https://github.com/otoyo/easy-notion-blog/blob/main/lib/notion/client.ts#L372

Notionを使っていると
当たり前のようにこんなことしませんか?

Screenshot 2022-12-14 at 17.33.14.png
Screenshot 2022-12-14 at 17.34.22.png

Blockの中にまたblockをいれちゃうあれです。
これをブログで実装すると
びっくりするほど
大変なんだなということが分かります。

Screenshot 2022-12-14 at 17.37.07.png
https://github.com/otoyo/easy-notion-blog/blob/main/lib/notion/client.ts#L372

Childrenっていうのがキーワードっぽいです。

公式リファレンスではこう明記されています。
Screenshot 2022-12-14 at 17.40.18.png
https://developers.notion.com/reference/get-block-children

const { Client } = require('@notionhq/client');

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

(async () => {
  const blockId = '59833787-2cf9-4fdf-8782-e53db20768a5';
  const response = await notion.blocks.children.list({
    block_id: blockId,
    page_size: 50,
  });
  console.log(response);
})();

NotionDBのPropertyにデータを追加する _Update page

easy-notion-blogは開発者(otoyoさん)のブログのコードも公開されています。

ここからたくさんのヒントを得ることができます。

特に印象的だったのが【いいねボタン】のコードです。
Screenshot 2022-12-14 at 17.50.37.png
https://github.com/otoyo/notion-blog/blob/main/src/lib/notion/client.ts#L687

これは
記事末尾に設置されたいいねボタンをトリガーとして
NotionDBのPropertyに+1増やすという機能です。

日常的によく使っているいいねボタンですが
実装には頭を抱えるほど難しいということを知りました。

いいねボタンを押したときに直接呼び出せば良いような気がしますが、これはできません。
JavaScript がアクセスできるのは、その JavaScript が生成されたドメインと同じドメインだけという決まりがあります。

ブログの画面上でボタンが押されたら
それをトリガーに
apiでPUT通信をし
Notionサーバーに送る。
送れた合図で+1をNotionDBのPropertyに入れる。

といった流れです。

実際に私もブログに追加して体験してみました。
Screenshot 2022-12-14 at 18.05.30.png

▼NotionDB
Screenshot 2022-12-14 at 18.06.53.png

この改造で
「ブログはNotionにある内容を公開するだけではなく、
ブログからアクションしてもらってNotionにためることもできるんだな」
ということを知りました。

解説記事を読みながら
習得できたことを
まとめたのが以下の記事です。

公式リファレンスでは以下のように明記されています。
Screenshot 2022-12-14 at 18.25.09.png
https://developers.notion.com/reference/patch-page

const { Client } = require('@notionhq/client');

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

(async () => {
  const pageId = '59833787-2cf9-4fdf-8782-e53db20768a5';
  const response = await notion.pages.update({
    page_id: pageId,
    properties: {
      'In stock': {
        checkbox: true,
      },
    },
  });
  console.log(response);
})();

NotionDB内にPageを新規作成する_Create a page

Screenshot 2022-12-14 at 18.14.12.png
https://github.com/herohoro/data-world-blog/blob/main/lib/submit_form/client.ts

これはいいねボタンからヒントを得て
自分で実装したコードです。

ブログの画面上で入力フォームを用意し
Screenshot 2022-12-14 at 19.26.17.png
https://data.herohoro.com/world/submit

そこに入力されたデータを
apiでPOST通信し
Notionサーバーへ送る。
そのデータをNotionDB内の1つのPageとして作成する...
Screenshot 2022-12-14 at 19.32.29.png

といった機能です。

特にapiの部分に苦戦しましたがなんとか完走しました。

ここまで来ると
公式リフェレンスでは結構簡単に書かれてることでも
実際にやろうとすると苦戦するなといったことを経験できました。
Screenshot 2022-12-14 at 18.26.37.png
https://developers.notion.com/reference/post-page

const { Client } = require('@notionhq/client');

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

(async () => {
  const response = await notion.pages.create({
    "cover": {
        "type": "external",
        "external": {
            "url": "https://upload.wikimedia.org/wikipedia/commons/6/62/Tuscankale.jpg"
        }
    },
    "icon": {
        "type": "emoji",
        "emoji": "🥬"
    },
    "parent": {
        "type": "database_id",
        "database_id": "d9824bdc-8445-4327-be8b-5b47500af6ce"
    },
    "properties": {
        "Name": {
            "title": [
                {
                    "text": {
                        "content": "Tuscan kale"
                    }
                }
            ]
        },
        "Description": {
            "rich_text": [
                {
                    "text": {
                        "content": "A dark green leafy vegetable"
                    }
                }
            ]
        },
        "Food group": {
            "select": {
                "name": "🥬 Vegetable"
            }
        }
    },
    "children": [
        {
            "object": "block",
            "heading_2": {
                "rich_text": [
                    {
                        "text": {
                            "content": "Lacinato kale"
                        }
                    }
                ]
            }
        },
        {
            "object": "block",
            "paragraph": {
                "rich_text": [
                    {
                        "text": {
                            "content": "Lacinato kale is a variety of kale with a long tradition in Italian cuisine, especially that of Tuscany. It is also known as Tuscan kale, Italian kale, dinosaur kale, kale, flat back kale, palm tree kale, or black Tuscan palm.",
                            "link": {
                                "url": "https://en.wikipedia.org/wiki/Lacinato_kale"
                            }
                        },
                        "href": "https://en.wikipedia.org/wiki/Lacinato_kale"
                    }
                ],
                "color": "default"
            }
        }
    ]
});
  console.log(response);
})();

Twitterで広がったeasy-notion-blogの輪

easy-notion-blogにはコミュニティも用意されています。
Screenshot 2022-12-14 at 18.30.08.png
easy-notion-blog/README/community

ツイートに#easy_notion_blogをつけると
比較的関連した方々からイイネがあります。

私が開発者のotoyoさん(@otoyo0122)とつながれたのもTwitterのおかげでした。

導入で詰まってる方を見かけると
私はすかさず飛んでいくようにしています。

なぜなら
ほぼ初心者状態でGitHubも分からなかった時期に
easy-notion-blogを使い始めてしまい
かなり苦労した経験があるからです。

pushとかaddとか全然分かりませんでした。

このコミュニティを通じて
お互いのブログの情報交換をしています。

「どんな改造したの?」
「それ記事に出す予定ある?」

など平和なやりとりもあれば

「今回のアップデート大変〜〜〜」
「ここで詰まってる」

といった嘆きツイートもあり楽しいです。

でもみんなNotionが好きで
好きだからずっと使いたくって
ブログにして記事を出しているのかなと
思ったりしています。

おわりに

Notionを使い始めてから
使えば使うほど欲が出てきて
ブログを始め、
easy-notion-blogがキッカケで
Notion API に触れるようになり
ワクワクが止まらない1年でした。

そんなeasy-notion-blogも
Starがそろそろ3ケタになろうとしていて

一緒にブログの改造をしながら
Notion APIやNext.jsなどを
習得できたらいいなと思っています\(^o^)/

長くなりましたが
最後まで読んでくださり
ありがとうございました★

2
5
1

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
2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?