Blog
Notion APIの活用!DEPARTでの事例も交えてご紹介!
Notion APIとは
Notionとは、一言で言えばドキュメント管理サービスですが、単純なドキュメントだけでなくタスク管理やエクセルのようなデータベースとしての機能があり、他サービスの埋め込みなども可能で入力の自由度が高いサービスです。
そのNotionにはAPIがあり、インテグレーションとして各ページやデータベースに対して情報の取得や更新などが行えます。
Notion APIの基本
Notionのドキュメントにまとめられているので、ほとんどのことがドキュメントを見ていただければと思いますが、NotionAPIを使用するにはデータ構造を知っておく必要があります。 ざっと以下のような感じでできています。
例:ナレッジ
つまり、すべては「ブロック」と呼ばれるものでできており、データベースやページはその集合体ということです。
DEPARTでの事例を例にNotionのデータを活用する方法をご紹介
ナレッジをNotionへ移行した際に各ページに表示している画像の中で元々のURLを使用している箇所があり、Not Foundになってしまっていたため画像URLを新しいものに変えたいということが起きました。 そこで「NotionAPIを使用して一括で更新しようじゃないか!!」となったわけです。
ざっくりと認証の準備編・実装編の2段階でご説明します。
認証の準備編
サービスのAPIを使用するときは基本的にAPIトークンたるものを発行する必要がありますよね。 今回もAPIトークンを発行していきます!
Notionではインテグレーションと呼ばれるものを作成して、APIトークンを発行します。
ワークスペースオーナーのみが インテグレーション タブにアクセスし、インテグレーションを作成できます。管理者でない場合は、ワークスペース管理者に連絡するか、別のワークスペースを使用してください。
ワークスペースのオーナーでないと認証用のAPIトークンを作成することができません。
1. Settings & members > My connections > Developer or manage integrations と進みます。
2. Create new integration をクリックして、画面先の入力項目に従ってインテグレーションを作成します。項目のName には「なにをするためのAPIなのか」を設定すると良いと思います。
3. Settings & members > Connections と進み、作成したインテグレーションの•••からCopy internal integration tokenをクリックします。
APIトークンがコピーできるので、準備完了です。
と言いたいところですが、、、もう一つやることがあります。
4. 更新したいデータベースとインテグレーションを繋げてやる必要があります。
※ 更新したいページ、もしくはその直近の親のデータベースで設定する必要があります。
今度こそ準備完了です。
実装編
NotionAPIにはJSのSDK(ソフトウェア開発キット)が用意されているので、こちらを使用します。
https://github.com/makenotion/notion-sdk-js
重要なので最初にお伝えしておくと、NotionAPIはリクエスト制限が平均3回/秒となっているので、その実装も必要です。
リクエスト制限対応の参考ソースコードはこちら
class PromisePoolExecutor {
constructor({ maxConcurrency, minInterval }) {
this.maxConcurrency = maxConcurrency;
this.minInterval = minInterval;
this.currentConcurrency = 0;
this.queue = [];
}
async execute(process) {
return new Promise((resolve, reject) => {
const task = async () => {
try {
this.currentConcurrency++;
const result = await process();
resolve(result);
} catch (error) {
reject(error);
} finally {
setTimeout(() => {
this.currentConcurrency--;
this.next();
}, this.minInterval)
}
};
if (this.currentConcurrency < this.maxConcurrency) {
task();
} else {
this.queue.push(task)
}
});
}
next() {
if (this.queue.length > 0) {
const task = this.queue.shift();
task();
}
}
}
module.exports = PromisePoolExecutor
使い方はこんな感じです
const poolExecutor = new PromisePoolExecutor({
maxConcurrency: 3,
minInterval: 1000,
})
;(() => {
poolExecutor.execute(async () => {
const pages = await notion.databases.query(query)
})
poolExecutor.execute(async () => {
const pages = await notion.databases.query(query)
})
poolExecutor.execute(async () => {
const pages = await notion.databases.query(query)
})
// これはリクエスト3回/秒以下であれば実行される
poolExecutor.execute(async () => {
const pages = await notion.databases.query(query)
})
})()
今回はデータベース配下の全ページに対して操作する必要があるので、まずは以下を参考にします。
Start building with the Notion API
process.env.NOTION_API_KEY
のところは直接トークンを貼り付けられますが、.env
などを使用すると良いと思います。
.env
に先ほどコピーしたAPIトークンに変更します。
const { Client } = require('@notionhq/client');
const notion = new Client({ auth: process.env.NOTION_API_KEY });
(async () => {
const databaseId = '668d797c-76fa-4934-9b05-ad288df2d136';
const response = await notion.databases.retrieve({ database_id: databaseId });
console.log(response);
})();
# .env
NOTION_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
次にdatabaseId
のところを変更します。データベースIDはURLから取得できます。
引用元:https://developers.notion.com/reference/retrieve-a-database
データベースからはページ一覧が取得できるので、各ページIDを利用してさらにAPIを叩いていきます。
ページの中身を取得するにはブロックAPIから取得する必要がありますが、都度ブロックAPIにリクエストしていたら大変なので配下の全ブロックを取得してくれるcollectPaginatedAPI
というメソッドがSDKに用意されているので、こちらを使用します。
GitHub - makenotion/notion-sdk-js: Official Notion JavaScript Client
今回の場合、parentBlockId
にはページIDを入れます。
const blocks = await Notion.collectPaginatedAPI(notion.blocks.children.list, {
block_id: parentBlockId,
})
冒頭で説明した通り、Notionのデータはブロックでできているのでページもブロックです。 ページIDもブロックIDとして使用することができるということです。 ページIDもデータベースIDと同じように取得できます。
目的のブロックを取得したら、あとは行いたいことに合わせて実行する流れになります。
できること
DEPARTでの事例のようにNotion自体へのデータ更新などを行いさまざまなデータを収集して管理することや、逆にNotion上のデータを取得したいという場合にはAPIを活用することができます。 例えばスプレッドシートや外部のAPIのデータを集約したり、NotionをCMS化して外部のサイトでデータを表示したりということもできます。
できないこと
できないこととしては、NotionのAPIは現在はインカミング(受付)方向のみで、アウトゴーイング(通知)ができません。 どういうことかというと、外部のシステムのタイミングをきっかけにしかAPIを操作することができず、「Notionの記事を更新したら」というNotion側のタイミングでは外部に通知できないのです。
基本的にリアルタイム編集だからというのが大きな理由だと思いますが、システム的な都合等もあり、今後機能が拡張されることが望まれていますが、現状では外部のシステムでタイミングを決めるしかないのです。
まとめ
非常に便利で自由度の高いNotionですが、APIを活用することで自動化や一括更新なども可能なので、ぜひ活用してみてもらえればと思います!
DEPARTではNotion関連やAPI関連のご相談なども可能です!