NotionAPI x GAS で出来ること

こんにちは、ShinonomeインターンのKaitoです。社内業務改善の一環でNotionAPIを使う機会がありました。簡単にできて、活用できる場面も多いと思うので、簡単に紹介していきます。

GOAL

Notionのデータベースからデータを取得し、Google Spreadsheetに書き出す作業を定期実行する。
今回は例として、旅行先の情報を入れたNotionのデータベースをスプレッドシートにエクスポートすることを目標にします。

STEPS

以下の手順で実装していきます。

  1. Notion内のデータベースとの連携を設定
  2. NotionAPI経由でデータを取得
  3. Spreadsheetに書き込む
  4. 定期実行を設定

Notion内のデータベースとの連携を設定

  1. Integrationを作成
    https://www.notion.so/my-integrationsからIntegrationを作成します。
    連携したいデータベースのあるWorkspaceのAdmin権限を持っている必要があるので、その点には注意してください。
    送信と同時に、Internal Integration Tokenを取得することができます。後から確認できますが、念の為保管しておきましょう。

  2. Integrationをデータベースに追加する
    インテグレーションを追加しただけでは、NotionAPIを叩いてもデータベースへのアクセスはできません。APIを用いて取得したいデータベースのPageにアクセスします。画面右上のShareから該当するIntegrationを追加しましょう。

  3. Database IDを取得する
    NotionのDatabaseに付与されているIDを取得します。このIDはデータベースのURLに含まれています。データベースのPageにアクセスし、URLからIDを抽出します。
    /myworkspace/?に挟まれている部分がIDに該当します。

https://www.notion.so/myworkspace/a8aec43384f547ed84390e8e42c2e089?v=...
                                  |--------- Database ID --------|

なお、公式ドキュメントに記載がありますが、この際にコピーするURLは、データベースfull pageで表示した際のURLになります。inlineで表示している場合はview databaseの遷移先でIDを確認することができます。

NotionAPI経由でデータを取得

行きたい旅先リストをSpreadsheetに書き出してみます。

NotionAPIで取得したいデータベース
  1. GASからAPIの実行
https://api.notion.com/v1/databases/{database_id}/query

こちらのエンドポイントを使用してデータベースを取得することができます。
以下のようなGASを書いていきます。

function getNotionData() {
  const database_id = '4edff~~~~~~~~~~~~~~';
  const url = 'https://api.notion.com/v1/databases/' + database_id + '/query';
  const token = 'secret_~~~~~~~~~~~~~~~~~';

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

  let options = {
    'method': 'post',
    'headers': headers,
    "muteHttpExceptions": true
  };

  let notion_data = UrlFetchApp.fetch(url, options);
  notion_data = JSON.parse(notion_data);
  return notion_data
}
  1. APIの実行結果を確認する
    1.で叩いたAPIから下記のようにデータを取得することができました。

ちなみに…

NotionではDatabaseにフィルターをかけられます。NotionAPIデータを取得する際にも同様にフィルターをかけることが可能です。
試しに取得するデータに「県が富山県」という条件をかけてみます。
filterオブジェクトを用意し、リクエストのボディに含めることで適用されます。

{
    "filter": {
        "property": "Prefecture",
        "select": {
          "equals": "富山県"
        }
     }
}

以下のように富山県の旅行先のみを取得することが出来ます。

Spreadsheetに書き込む

  1. 書き出しをする為のシートを用意する

    今回は簡易的に以下のようなシートを用意しました。
  2. シートに書き出す
    取得したJSONのデータから、各カラムのデータを抽出し、配列に格納します。階層の深い値へのアクセスを記述する際には注意してください。
  let data = getNotionData()
  let results = data.results;

  let desinations = [];
  let prefectures = [];
  let priorities = [];
  let estimatedCost = [];

  results.forEach((item) => {
    let destination = item.properties['Destination'].title[0].text.content
    let prefecture = item.properties['Prefecture'].select.name
    let priority = item.properties['Priority'].select.name
    let cost = item.properties['Estimated Cost'].number

    desinations.push(destination);
    prefectures.push(prefecture);
    priorities.push(priority);
    estimatedCost.push(cost);
  })
  1. スプレッドシートに書き出す
    参考記事を元にSpreadsheetに書き出すメソッドを定義します。
    2.で用意した、各カラムの配列、書き出したいカラムを引数に取ります。
    カラム名の入っている1列目は飛ばし、2列目から書き出すようにしています。
function writeSpreadSheet(targetArray, colmn) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(シート名);
  let row = 2;
  targetArray.forEach((value) => {
    sheet.getRange(row, colmn).setValue(value);
    row = row + 1;
  });
}

定期実行を設定する

ここまでの処理を実行した結果、以下のようにNotionのデータをSpreadsheetに書き出すことが出来ました。

最後に今まで書いた処理に対して定期実行を設定していきます。定期実行は、用途によって様々なパターンが考えられます。
社内業務では、名簿に更新をかける処理を自動化したので、毎日発火させるような設定をしました。が、例えば旅行先リストの更新は、毎日行うことが想定されていないので、1ヶ月毎の更新で事足りるでしょう。

  1. App Scriptにアクセス
    Spreadsheetの拡張機能からApp Scriptにアクセスします。
    処理を書いたのは「エディタ」ページですが、「トリガー」ページから設定を行います。
    「トリガー」ページより「トリガーを追加」を選択します。

  2. トリガーを設定する

「イベントのソースを選択」から、様々な定期実行スパンの設定を行うことができます。
今回は「月ベースのタイマー」より「毎月1日」に定期実行されるように設定してみました。

終わりに

NotionAPISpreadsheetに関連する記事では、NotionからSpreadsheetへのフローに関する記事が多いですが、今回はSpreadsheetからNotionへのフローに関する記事を書いてみました。

計算処理に関しては、どうしてもSpreadsheetが勝る部分があると思うので、うまく連携して使いこなしていきたいです。旅程の管理などをNotionで行っている人は、予算の詳しい計算などのために連携してみてはいかがでしょうか?

参考記事