Laravel Advent Calendar 2021 19日目の投稿です。
Notion APIを最近使った時に、Laravel用のAPIラッパーを利用したので使い方を書いていきます!
Notion APIについて
Notionではdatabase、page、blocks、usersに対するAPIが提供されています。
詳細は以下ドキュメントがあります。
Laravel-Notion-APIについて
2021年12月現在でver0.6がリリースされています。
Githubはこちらです。
実装例
Notion APIのインテグレーション作成
まずはNotionAPIを使うためにインテグレーションを作成します。
日本語設定にしているとちょっとレイアウト崩れしてますね。。。
新規作成で名前を入力し、利用する機能を設定します。
これで送信するとトークンが発行されます。
このトークンを操作したいページに対して設定する必要があります
ページの[共有]設定から、[招待]をクリックすると以下が表示されインテグレーション選択出来ます。
今回は私が以前公開した読書リストを使ってやっていきます。このリストはNotionで言うdatabaseに当たるもので、その配下にページが追加されていくイメージです。
Notionの構造を理解する上で、以下の記事がとても参考になりました
現在のNotion API(2021/7/13)で何がどこまでできるか
今回のURLでは、
https://charming-antimatter-5a2.notion.site/b3faf77a97124b4f8c1f242085f1d2e3?v=a1413e285972481e8483c894152047ff
このURLにおけるb3faf77a97124b4f8c1f242085f1d2e3
の部分がdatabase_id
になります。
今回はこのdatabase_id
も'.env'で管理してコードを書きます
NOTION_DATABASE_ID="b3faf77a97124b4f8c1f242085f1d2e3"
```
## Laravel-Notion-APIの設定
composerで追加します。
```ssh
composer require fiveam-code/laravel-notion-api
```
`.env` に先程取得したアクセストークンを設定します
```.env
NOTION_API_TOKEN="$YOUR_ACCESS_TOKEN"
```
Laravel-Notion-APIの設定はこれで完了です。
## configでenvの値を取るように設定
app/config配下に'notion.php'を作ります
```notion.php
<?php
return [
'token' => env('NOTION_API_TOKEN'),
'database' => env('NOTION_DATABASE_ID'),
];
```
## ページ作成
では早速ページを作ってみます
```php
<?php
use FiveamCode\LaravelNotionApi\Entities\Page;
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
use FiveamCode\LaravelNotionApi\Notion;
use Illuminate\Support\Facades\Log;
// 以下実装
$token = config("notion.token");
$notion = new Notion($token);
$databaseId = config("notion.database");
$page = new Page();
// タイトル指定
$page->setTitle("Name", "こち亀200巻");
try {
$page = $notion->pages()->createInDatabase($databaseId, $page);
// ページID
Log::info($page->getId());
} catch (NotionException $e) {
Log::error($e->getMessage());
}
```
さて、これで...とやってみたらエラーが出ました!
```
local.ERROR: Bad Request: (validation_error) (Name is not a property that exists.)
```
Nameというプロパティはないよ!と言われました。
確かに今回対象にしている[読書リスト](https://charming-antimatter-5a2.notion.site/b3faf77a97124b4f8c1f242085f1d2e3?v=a1413e285972481e8483c894152047ff)には`Name`のプロパティはありませんでした。
![スクリーンショット 2021-12-19 14.08.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207269/b5e2bd5c-e2d5-766c-43db-8a1e461741ca.png)
"タイトル"でいけそうですね
```php
use FiveamCode\LaravelNotionApi\Entities\Page;
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
use FiveamCode\LaravelNotionApi\Notion;
use Illuminate\Support\Facades\Log;
// 以下実装
$token = config("notion.token");
$notion = new Notion($token);
$databaseId = config("notion.database");
$page = new Page();
// タイトル指定
$page->setTitle("タイトル", "こち亀200巻");
try {
$page = $notion->pages()->createInDatabase($databaseId, $page);
// ページID
Log::info($page->getId());
} catch (NotionException $e) {
Log::error($e->getMessage());
}
```
これでやってみると...追加されました!!
![スクリーンショット 2021-12-19 14.15.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207269/d46f06c8-4a8b-7f37-59b2-52ee044b4d60.png)
他のタグも設定してみます!
```php
use FiveamCode\LaravelNotionApi\Entities\Page;
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
use FiveamCode\LaravelNotionApi\Notion;
use Illuminate\Support\Facades\Log;
// 以下実装
$token = config("notion.token");
$notion = new Notion($token);
$databaseId = config("notion.database");
$page = new Page();
// タイトル指定
$page->setTitle("タイトル", "こち亀200巻");
// URL
$page->setUrl("Amazonなどのリンク", "https://www.amazon.co.jp/dp/B01KJGD54C/ref=cm_sw_em_r_mt_dp_BJCRXMKNGAM913PDKZR6");
// 選択リスト
$page->setMultiSelect("本の種類", ["物理本"]);
$page->setMultiSelect("カテゴリ", ["技術書","歴史"]);
// チェックボックス
$page->setCheckbox("既読", false);
$page->setCheckbox("お気に入り", true);
$page->setCheckbox("読書中", true);
try {
$page = $notion->pages()->createInDatabase($databaseId, $page);
// ページID
Log::info($page->getId());
} catch (NotionException $e) {
Log::error($e->getMessage());
}
```
これで綺麗に入りました!
![スクリーンショット 2021-12-19 14.25.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207269/3cf7b85d-f94f-b1be-5e12-2564379c33a8.png)
## ページ更新
ページ更新はページIDを指定して更新が出来ます
ページ作成の際は、戻り値でページIDが取得できます。`$page->getId()`の部分です。
このIDを使って更新ができます。
ページのURLでみると `https://www.notion.so/200-` 以下がページIDになります。(ここで200-と付いているのはこち亀200巻の200ですね。タイトルの中の英数字で変わるみたいです。)
`https://www.notion.so/200-c2ea522a427f4966b774e0fd14a69642`
ページIDの詳細はこちらになります。
https://www.notion.so/200-c2ea522a427f4966b774e0fd14a69642
https://developers.notion.com/docs/working-with-page-content#creating-a-page-with-content
```php
use FiveamCode\LaravelNotionApi\Entities\Page;
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
use FiveamCode\LaravelNotionApi\Notion;
use Illuminate\Support\Facades\Log;
// 以下実装
$token = config("notion.token");
$notion = new Notion($token);
$page = new Page();
$page->setId("c2ea522a-427f-4966-b774-e0fd14a69642");
$page->setCheckbox("読書中", false);
try {
$page = $notion->pages()->update($page);
// ページID
Log::info($page->getId());
} catch (NotionException $e) {
Log::error($e->getMessage());
}
```
これで、読書中のフラグが落ちました!
## データベース情報取得
データ取得系のAPIも確認してみます!
データベースに紐づく情報を取得を取ります。
```php
use FiveamCode\LaravelNotionApi\Entities\Page;
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
use FiveamCode\LaravelNotionApi\Notion;
use Illuminate\Support\Facades\Log;
// 以下実装
$token = config("notion.token");
$notion = new Notion($token);
$databaseId = config("notion.database");
try {
$database = $notion->databases()
->find($databaseId);
Log::info($database->getTitle());
// 読書リスト
Log::info($database->getProperties());
// [{"id":"AIrg","responseData":{"id":"AIrg","name":"\u65e2\u8aad","type":"checkbox","checkbox":[]},"title":"\u65e2\u8aad","type":"checkbox","rawContent":[],"content":[]},{"id":"Cl>z","responseData":...(省略)
Log::info($database->getPropertyKeys());
// array (
// 0 => '既読',
// 1 => 'カテゴリ',
// 2 => 'お気に入り',
// 3 => '読書中',
// 4 => '本の種類',
// 5 => 'Amazonなどのリンク',
// 6 => 'タイトル',
// )
Log::info($database->getIcon());
// 📕
Log::info($database->getIconType());
// emoji
Log::info($database->getUrl());
// https://www.notion.so/b3faf77a97124b4f8c1f242085f1d2e3
Log::info($database->toArray());
//array ( ... )
} catch (NotionException $e) {
Log::error($e->getMessage());
}
```
`toArray()` で全部取れるのは使いやすいですね
## データベース配下のページ情報を取る
```php
use FiveamCode\LaravelNotionApi\Exceptions\NotionException;
use FiveamCode\LaravelNotionApi\Notion;
use FiveamCode\LaravelNotionApi\Query\Filters\Filter;
use FiveamCode\LaravelNotionApi\Query\Filters\Operators;
use FiveamCode\LaravelNotionApi\Query\Sorting;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
// 以下実装
$token = config("notion.token");
$notion = new Notion($token);
$databaseId = config("notion.database");
$sorting = new Collection();
$filters = new Collection();
// こち亀をタイトルに含むものだけ取る
$filters
->add(
Filter::textFilter("タイトル", Operators::CONTAINS, "こち亀")
);
// お気に入りを昇順でソートする (降順は"descending")
$sorting
->add(Sorting::propertySort("お気に入り", "ascending"));
try {
$pages = $notion->database($databaseId)
->filterBy($filters)// フィルター
->sortBy($sorting) // ソート
->limit(5) // リミット5件で設定
->query()
->asCollection();
// 取得ページ
foreach ($pages as $page) {
$array = $page->toArray();
Log::info($array['title']);
}
} catch (NotionException $e) {
Log::error($e->getMessage());
}
```
このデータの状態だった場合
![スクリーンショット 2021-12-19 16.32.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207269/9deb1081-68fa-d307-13d1-0c84929a2236.png)
以下の結果で返ってきます!お気に入りの昇順が効いていますね。
```
local.INFO: こち亀201巻
local.INFO: こち亀200巻
```
pageの詳細情報も`$page`に入っています。
# 最後に
簡単にお問い合わせ管理する時とか今の機能でも十分できそうですね。
Notion APIも、Laravel-Notion-APIもまだ出来たばっかりの進化中なので今後の機能追加を楽しみです。