🙉

Notion API × GASでNotionのデータをスプレッドシートに移す①

2021/12/16に公開

参考になったサイト

・ https://developers.notion.com/reference/intro
・ https://www.pnkts.net/2021/05/16/gas-notion-api
公式サイトがわかりやすく書いてあったのでデータ取得するまでは結構スムーズに行きました!

はじめに

この記事ではGASを使って、Notionのデータをスプレッドシートに書き写すことを解説しています!
notionはcsvダウンロードも可能なのですが、Notion APIの使用方法の一例として参考にしてもらえれば嬉しいです!

今回はデータベースの情報から、それにぶら下がっているページの文章の内容まで取得していきます!

①インテグレーションの作成


まずはじめに
https://www.notion.com/my-integrations
↑のサイトから開発情報と資格情報の作成を行います。
新しいインテグレーションを作成するを選択してください。

基本情報を選択する画面になるので、名前と必要であれば画像の登録、
最後にAPIを使用したいワークスペースを選択して送信ボタンをクリックします。

②トークンの取得

送信ボタンを押すとインテグレーションの情報にシークレットの項目が表示されます。
そのワークスペースに一意のトークンが付与されるので、どこかに控えておきましょう!
あとでapiを叩く際に使用します。

③データベースの内容の確認とIDの確認

今回使用するデータベースの内容について、以下の写真で示します。

せっかくなら面白い内容のデータベースの方がやる気出るなと思って
自分の好きなゲームについて内容をまとめました!!
左の項目から
・ ゲームタイトル
・ ゲームのカテゴリ
・ 評価(好きなゲームを集めてしまったので必然的に全部星5になった笑)
・ ステータス(持ってる、クリア済み、欲しい!)
・ ゲーム機器の種類
・ 攻略サイトのURL
の順番で表が作成されています。
またゲームタイトルの下にはpageがぶら下がっていて、私が書いたゲームの感想が記入されています。
今回はこのpageのゲームの感想まで取得します!
pageの中身はこの写真のように書かれています。

ではapiを叩く際に必要になるこのデータベースのIDを取得しましょう!

④取得したいデータベースIDの確認方法

ではデータベースIDの確認を行います。実はURLに書かれています。

https://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...

(公式ドキュメントのものを拝借しております。)
このmyworkspaceから?vの手前までの数字と英語の文字列がデータベースIDです!

⑤自分のインテグレーションとデータベースを紐付ける

ここではデータベースとインテグレーションを紐づけることを行っていきます。
ここの操作がないと、apiでリクエストを送っても弾かれてしまうので注意が必要です。

notionのデータベースの右上にある共有の文字をクリックすることで
インテグレーションなどを招待できるボタンが表示されるので、①で作成したインテグレーションの名前を選択して紐付けを行ってください。
さてこれでapiを叩く準備は整ったのでGASの方に移って行きます!!

⑥GASのデータ格納用のシートを作成する

今回は下記のようなシートを使用します(なんの変哲もないシートですが、、、)

このシートに対してapiを使用してNotionのデータをコピーしていきます!

⑦いざGASでapiを実行してみる!(データベース)

さていよいよここからGASにコードを書いていきます!
スプレッドシートの拡張機能のタブから、apps scriptを選択してGASのエディット画面を開きます。
https://developers.notion.com/reference/post-database-query
こちらのサイトを参考にして下記記述を行いました。
先程のデータベースのデータを取得するために以下のコードを記述しました。

function getNotionDbData() {
  //API取得に取得するデータをセットしてデータを取得する
  const database_id = {先程確認したデータベースのID};
  const url = 'https://api.notion.com/v1/databases/' + database_id + '/query';
  const token = {②で確認したインテグレーションのトークン文字列};

  let headers = {
    'content-type' : 'application/json; charset=UTF-8',
    'Authorization': 'Bearer ' + token,
    'Notion-Version': '2021-08-16',
  };
  let options ={
    'method': 'post',
    'headers': headers,
  }

  let notion_data = UrlFetchApp.fetch(url, options);
  notion_data = JSON.parse(notion_data);
  return notion_data;
}

この記述を行うことで、オブジェクトでnotionのデータベースの一覧が取得できます!
デバッグを行いたい場合についてはLogger.logで確認することで、確認したい変数を確認することができます。
万が一エラーが発生した場合は下記のサイトに原因が書いてあるので参考にするといいと思います。
https://developers.notion.com/reference/errors
実際のログ↓

まぁたくさんデータが取れていますよね、、、、、、
ここからスプレッドシートに欲しいデータ抽出していきます。
ただしこのapiで取得できているのはnotionのデータベースの値までです。
ゲームのタイトルにぶら下がっているpageのゲームの感想の要素のブロックまでは取得できません。
この感想が記述されている内容です。

一体どうすればいいのか???
それは上記のデータベースの情報を取得した際に抽出したページIDを使用して、感想を取得するためのapiをもう一度作成する必要があります。
notionのデータベースとページとブロックの関係がイマイチわからん、、、という方は
こちらのサイトが参考になります。(お友達に教えてもらいました。)
https://note.com/mamizo/n/n557db93b1ac4
では次のステップでpageIDを使用して、感想のブロックを取得しましょう!

⑧いざGASでapiを実行してみる!(ページ内のブロック)

上記で取得したデータベースに含まれている、データの1つ1つに感想のブロックが所属しているPageIDが振られています。
データベースを取得した際には行ごとに配列で値が格納されます。
これをforEachで行ごとにpageIDを取り出して、そのpageIDを元にapiを実行していきます。
この取得したデータ構造がかなり複雑になっているので参考になればと思います。
ページの下のブロック要素を取得するには
https://developers.notion.com/reference/get-block-children
こちらのURLに書いてあるようにurlのpageIDの後ろに/childrenを記入すると取得することが可能です。

//ページに関するデータを習得してスプレッドシートに書き込む
function getNotionPageData(page_id_array) {
  let page_texts = [];
  //pageIDが格納されいる配列を回して1つ1つのページのブロック要素を取得する
  page_id_array.forEach((page_id)=>{
    //API取得に取得するデータをセットしてデータを取得する
    const url = 'https://api.notion.com/v1/blocks/' + page_id + '/children';
    const token = {②で確認したインテグレーションのトークン文字列};

    let headers = {
      'content-type' : 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + token,
      'Notion-Version': '2021-08-16',
    };
    let options ={
      'method': 'get',
      'headers': headers,
    }
    let notion_data = UrlFetchApp.fetch(url, options);
    notion_data = JSON.parse(notion_data);
    //ゲームの感想が格納されているプロパティ、階層深くて大変だった、、、
    let page_text = notion_data.results[0].paragraph.text[0].text.content;
    page_texts.push(page_text);
  });
}

function notionDataToSpreadSheet(){
  //上記のgetNotionDbDataを実行してdb_dataに格納する
  let db_data = getNotionDbData();
  let game_datas = db_data.results;

  //スプレッドシートに格納する値を抽出して配列に格納する
  let game_ids = [];
  
  //データベースのデータからpageIDだけを抽出して配列に格納する
  game_datas.forEach((game)=>{
    let game_id = game.id;
    game_ids.push(game_id);
  })
  getNotionPageData(game_ids);
}

これでpage_textsの配列の中にゲームの感想がデータごとに1つずつ格納されました!
残りのジャンルやステータス等については、データベースの情報から取得できるので
次回の記事では残りの必要な情報を配列で取得して、スプレッドシートに書き込む作業を行なっていきます!寝ます!!!

Discussion