Notion APIに入門してみた

# はじめに
参加中のインターンで、Notion APIをPostmanから制御する機会がありました。
せっかくなので、入門した時の覚書を記事として書き直します。

# Notionについて
NotionはWebやデスクトップで使える、柔軟なノートアプリケーションです。EvernoteやOneNoteと同じようなものですね。

https://www.notion.so/ja-jp

Notionでは **データベース機能（Notion DB）** が特徴的で、表、カンバンボード、カレンダー、リストなど、さまざまなビューを使用して情報を整理できます。
このDBはリレーショナルデータベースの要素を持ち、異なるデータベース間の関係をリンクさせることが可能だったりと、けっこう便利です。

これは主観ですが、ハッカソンなどの学生プロジェクトの管理ツールとしても多く使われているほか、個人的なノートアプリとして使用しつつ、共有するときは記事として共有できるので、学生の間では結構使われていたりします。

# Notion APIについて
**Notion API** は、外部アプリケーションやサービスがNotionのデータにアクセスし、操作することを可能にするインタフェースです。このAPIを利用することで、ユーザーはNotion内のコンテンツをプログラム的に管理したり、他のアプリケーションと連携したりできます。具体的には、

- データベースの操作
- ページの操作
- ワークスペース内のユーザー情報の取得

などができます。
これら機能の実装には、NotionのWebサイトから**インテグレーション**を作成する必要があります。

## インテグレーションとは
インテグレーションは、外部アプリケーションがNotionと通信するための機能です。これはBotというより外部と内部をつなぐ鍵のようなもので、読み書きの権限やワークスペースへのアクセス権などはこのインテグレーションを介して設定されています。

インテグレーションには二種類あり、
- インターナル（Internal、非公開）
- パブリック（Public、公開）

の二つがあります。デフォルトではインターナルですね。

# APIを制御してみる
それでは、簡単にAPIに触れてみたいと思います。
以下の公式記事が参考になると思うので、分かりづらればこちらをご覧ください。

https://www.notion.so/ja-jp/help/create-integrations-with-the-notion-api

前提として、Notionアカウントを持っていることを確認してください。

<br>
そしたら、テスト用にDBを持ったページを作成しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/a67b2ebf-ffca-a049-eef8-88d9e35d32d2.png)

今回はこのDBに対して新しいデータをPOSTすることを目標としたいと思います。

## インテグレーションを作成する
まずはインテグレーションを作成してみましょう。
以下のリンクから作成ができます。

https://www.notion.so/my-integrations

ログインしたら、まず「新しいインテグレーション」をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/baf3a07e-e84d-a217-03d5-a4b26af6bc1b.png)

そしたらインテグレーションの概要入力欄が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/664bc484-b6b4-ffab-9a0e-c6323217daa5.png)

基本自由で構いませんが、ワークスペースが先ほど作成したテスト用のページがある場所かどうかを確認しておいてください。
作成出来たら、以下のような設定画面が開けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/c7d5aa42-177e-0a6a-96df-cd8a9f17cf5c.png)

「内部インテグレーションシークレット」とありますね。
これがこのインテグレーションの**トークン**になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/390da466-41fa-ed0a-8b32-d8cfbe9a3180.png)

これは使うので、「表示」から「コピー」を選択してどこかにメモしておいてください。

## ページにインテグレーションを追加する
さて、インテグレーションが作成できました。
次は、テスト用のページにインテグレーションを追加していきます。

Notion APIはどのページでも手放しでアクセスできるわけではなく、**インテグレーションが追加されたページのみ**に対してアクセスができます。
そのため、インテグレーションができても、追加しないとAPIが叩けないんですね。

さて、インテグレーションを追加します。
テスト用のページを開き、右上の三点リーダーをクリック。
表示したメニューの中から「Add connections」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/c8660c8d-747f-d19c-3b7e-ee9617ee2f3a.png)

その中にある、先ほど作成したインテグレーションをクリックして追加してください。
追加出来たら、以下のようにメニューの下に表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/c708166a-a7b8-7724-c016-48dd3ddac123.png)

これで下準備は終わり...と行きたいですが、もう少しだけ準備が必要です。

## アクセスしたいDBのIDを確認する
Notionでは、すべてのページ/DB/ブロックに対して一意なIDが割り振られています。そして、APIでアクセスする対象を指定するためには、そのIDが必要です。
今回はDBにアクセスしたいので、このDBのIDを知る必要があります。

方法ですが、まずはDBの共有リンクを生成します。
DBの三点メニューから「Copy link to view」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/e68a5218-6fe2-b7a1-de39-2de235fb5eab.png)

そしたら、以下のような形式のURLが取得できます。

```
https://www.notion.so/<データベースID>?v=<ビューID>
```

このURLから「データベースID」の部分だけ抜き取ってメモしておきましょう。そしたら下準備はOK。

ここからは実際にAPIを叩いていくわけですが、僕は**cURL**と**Postman**の二種類から試してみました。
Windowsの場合はデフォルトでcurlを使用できる環境ではない（Powershellにも`curl`コマンドは存在しますが、文法が別物）なので、混乱を避けるためにもPostmanを使用することをお勧めします。
なお、WSL上ではcurlが動作するので、こちらを導入している場合はcurlでも構いません。

## cURLを使う
**cURL**（カールとよみます） は、コマンドラインから様々なプロトコルでデータを転送できるコマンドツールです。よくライブラリをインストールしたりAPIテストでデータを送信したりするときに使いますね。

さて、curlからNotionにリクエストを送るときは、以下の公式ドキュメントから行いたい操作を探します。

https://developers.notion.com/

例えば、データベースにデータをポストするためのリファレンスはここ。

https://developers.notion.com/reference/post-database-query

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/d852f874-4a65-7959-86f5-6bb3ea51c8aa.png)

サンプルコードから説明まで（英語ですが）丁寧に書いてあるので、基本的にここを読めば迷いません。

さて、実際にAPIを叩いてみましょう。
ここに、テストデータを挿入するためのcurlコマンドを書いてみました。

```shell
curl 'https://api.notion.com/v1/pages' \
  -H 'Authorization: Bearer ここにAPIトークン' \
  -H "Content-Type: application/json" \
  -H "Notion-Version: 2022-06-28" \
  --data '{
	"parent": { "database_id": "ここにデータベースID" },
  "icon": {
  	"emoji": "🍀"
  },
 "properties": {
    "Name": {
      "title": [
        {
          "text": {
            "content": "Hello Integration！"
          }
        }
      ]
    }
  }
}'
```

APIトークン、およびデータベースIDは先ほどメモしたものに書き換えてください。
そしたら実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/58dfb517-73b6-a3ed-a4d4-6852127feff2.png)

おおー。
無事、コマンドからデータが生成されました。

## Postmanを使う
**Postman**とは、API開発をサポートするためのGUIツールです。Web上で使えるほか、Windowsならアプリをインストールしてローカルで動かすこともできます。

https://www.postman.com/

cURLでデバッグするのに比べ、同じ操作をキャッシュしたり、パラメータを視覚的にわかりやすく変更できたりするので、こちらのほうがデバッグには適している場合が多いです。

さて、同じようにDBにポストしてみましょう。
新しくリクエストを作成したとき、こんな感じの画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/946e8b8b-3429-fc07-79bb-7d484419c8f0.png)

まずはアクセス先のURLを設定しましょう。
ここでは`https://api.notion.com/v1/pages`とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/5fcc1929-e001-005e-0fb2-413b9af384ba.png)

そしたら設定をしていきます。
cURLでは引数にひとつひとつヘッダー情報などを書いていく必要がありましたが、Postmanでは各情報に応じたタブがあり、ここから情報を編集することができます。

:::note warn
ここでは2023/12/1に追加された日本語版での名称を使用しています。もしかしたら訳が変更されたりする場合があるので、その場合は公式ドキュメントなどを参照してください。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/0a440dcd-ebb3-e94a-7f9e-ffd267423e01.png)

まずはAPIトークンを入力します。
「認証」タブを選択し、トークンタイプを「Bearer トークン」にしてからトークンをコピペしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/637283b2-32ee-6f91-bf8f-b92c53e79ad7.png)

次に、NotionのAPIバージョンを指定します。
Notion APIの最新バージョンは以下より確認できます。

https://developers.notion.com/reference/versioning

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/1a30ed43-dc08-7a4d-4fc5-237d09a440fe.png)

今回は`2022-06-28`です。

最後に、データの部分を入力していきます。
「ボディ」タブを選択し、データ形式に「Raw」を指定します。
入力するのはJsonなので、フォーマットは「JSON」にしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/b8ec6a37-0079-f48a-a756-1995e74d30b2.png)

最後に、HTTPメソッドをPOSTにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/b8c9aab7-c54c-26c8-8fba-df825c9960a0.png)

そして、送信ボタンを押すと...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/971e9b13-8dac-cd59-b7c7-08cad957f04f.png)


おおー。
同じようにデータが送信されました。

### 余談：コレクションについて
今回は１からリクエストを作成してみましたが、実はこのPostmanには**コレクション**という機能があります。
これは様々なリクエストをまとめたライブラリのようなもので、自分で作成したり、他人が作成したものを **フォーク（コピー）** したりできます。

実は、Notionは公式でPostmanのライブラリをサポートしており、フォークしていつでも参考にすることができます。↓

https://www.postman.com/notionhq/workspace/notion-s-api-workspace/overview

使うときは、上のリンクに飛び、三点メニューから「フォークを作成」を選択するだけ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/363f625a-2062-45e1-3d47-40ecbbdeaa9e.png)

あとはざっくり概要を記入して、「コレクションをフォーク」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/56ce5e4b-75dc-d672-ca2a-a95915ccbb68.png)

そしたら、自分のワークスペースにコピーされたコレクションができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/5e38d276-3777-3dd7-a153-a377138d8108.png)

コレクションのタブから「変数」をクリックすれば、コレクション内で共通の定数を設定することもできます。
ここにAPIトークンなどを設置すれば、複数リクエスト内で簡単に使いまわすことができますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/e0711451-75e6-aec6-86e9-959c5dc47a76.png)

# おわりに
ちょうどWeb周りの学習でHTTPリクエストについて学んだので、この辺の話は結構面白かったです。
最近レガシーな環境ばかりで開発していて知識欲がうずうずしているので、次のハッカソンで採用してみようかしら。