見出し画像

[GAS] Notionのデータベースの列をGoogleスプレッドシートに転記する

はじめに

以前、GASでNotionAPIを使ったスクリプトを作成しました。

今回は、GASでNotionのデータベースの列を、Googleスプレッドシートに転記する処理を実装します。

使用するNotionのデータベース

今回は、Notionのテンプレートにある「会議」のテンプレートを使用します。

右のメニューから「テンプレート」をクリック
右のメニューから「会議」をクリックし、「テンプレートを入手」をクリック
Notionの「会議」テンプレート

プロパティは、一部変更しています。変更点は下記です。

  • イベント時間の表示形式を、タイムゾーンを「JST」、日付の形式を「年/月/日」、時刻の形式を「24時間」に変更

  • 表示するプロパティを、「件名」「イベント時間」「種別」のみに変更

それぞれの行の「件名」「イベント時間」「種別」の列の値を取得し、Googleスプレッドシートに転記します。

事前準備

下記の記事にまとめていますので、ご参照ください。

実装

実装時に必要になるのは、下記2つになります。

  • Internal Integration Token

  • 取得するページID

全体の処理は、下記です。

function fetchListFromNotionDababase() {
  const props = PropertiesService.getScriptProperties();
  const token = props.getProperty('NOTION_TOKEN');
  const databaseId = props.getProperty('NOTION_DATABASE_ID');

  const notionApiManager = new NotionApiManager(token);
  
  try{
    const response = notionApiManager.queryDatabase(databaseId);
    
    const json = response.getContentText();
    const data = JSON.parse(json);

    // 取得したJSONデータを、スプレッドシートに書き込むための2次元配列に変換
    const values = convert2DArrayFromNotion_(data);

    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('会議');
    sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
  }catch(e){
    console.log(e);
  }
}

/**
 * Notion APIから取得したDatabaseのJSONオブジェクトを、Googleスプレッドシートに書き込むため2次元配列に変換
 * 
 * @param {Object} obj - オブジェクト
 * @return  {Array} 
 */
function convert2DArrayFromNotion_(data){
  const values = [];

  for ( const item of data['results'] ){
    const propertiesObj = item['properties'];

    const title = getTitleValue_(propertiesObj['件名']);
    const date = getDateTypeValue_(propertiesObj['イベント時間']);
    const type = getSelectTypeValue_(propertiesObj['種別']);

    if ( title === '' ) continue;
    values.push([title, date, type]);
  }

  const header = ['件名', 'イベント時間', '種別'];
  values.unshift(header);

  return values;
}

/**
 * ページプロパティのタイプが「Select」の値を取得
 * 
 * @param {Object} obj - オブジェクト
 * @return  {string} Selctの値
 *
 * Note:https://developers.notion.com/reference/page-property-values#select
 */
function getSelectTypeValue_(obj){
  let value = '';

  if ( !obj['select'] ) return value;
  value = obj['select']['name'];
  return value;
}

/**
 * ページプロパティのタイプが「Date」の値を、yyyy/MM/dd形式の文字列で取得
 * 
 * @param {Object} obj - オブジェクト
 * @return  {string} Dateの値
 *
 * Note:https://developers.notion.com/reference/page-property-values#date
 */
function getDateTypeValue_(obj){
  let value = '';

  if ( !obj['date'] ) return value;
  value = Utilities.formatDate(new Date(obj['date']['start']), 'JST', 'yyyy/MM/dd');
  return value;
}

/**
 * ページプロパティのタイプが「Title」の値を文字列で取得
 * 
 * @param {Object} obj - オブジェクト
 * @return  {string} Titleの値
 *
 * Note:https://developers.notion.com/reference/page-property-values#title
 */
function getTitleValue_(obj){
  let value = '';

  if ( !obj['title'] ) return value;
  if ( obj['title'].length === 0 ) return value;
  value = obj['title'][0]['text']['content'];
  return value;
}

順番に処理の説明していきます。

Notionのデータベースからページを取得する処理

NotionAPIを呼び出す処理は、下記のように実装しています。

const notionApiManager = new NotionApiManager(token);
const response = notionApiManager.queryDatabase(databaseId);

NotionAPI用のクラスを作成しています。
前回ご紹介した記事でも同様の名前のクラスを定義していますが、今回の処理で使用するメソッドのみを定義しています。

class NotionApiManager{
  /**
   * Notion APIに関するクラスのコンストラクタ
   * @constructor
   */
  constructor(token){
    this._token = token;
    this._notionVersion = this._getNotionAPIVersion();
  }

  /**
   * データベースに含まれるページのリストを取得する
   * 
   * @param {string} databaseId - Database ID
   * @return {HTTPResponse} fetchのresponse
   */
  queryDatabase(databaseId, payload){
    const endpoint = this._getEndpointDatabase(databaseId);
    const options = this._postOption(payload);
    delete options['payload'];

    const response = UrlFetchApp.fetch(endpoint, options);
    return response;
  }

  /**
   * NotionAPI のVersionを取得
   * @param {string} guestId - アプリの名前
   * @return {string} version - NotionAPIのバージョン
   */
  _getNotionAPIVersion(){
    const url = "<https://developers.notion.com/reference/versioning>"
    const reg = /&quot;default&quot;.*?<\\/script>/g;
    const htmldata = UrlFetchApp.fetch(url).getContentText("utf-8");
    const version = htmldata.match(reg)[0].match(/([0-9]{4}-[0-9]{2}-[0-9]{2})/g)[0];
    return version;
  }

  /**
   * データベース用エンドポイントを取得するサブメソッド
   * @return {string} endpoint - エンドポイント
   */
  _getEndpointDatabase(databaseId) {
    return `https://api.notion.com/v1/databases/${databaseId}/query`;
  }

  /**
   * POSTする時のオプションを作成するサブメソッド
   * @param {Object} payload - payload
   * @return {Object} option - option
   */
  _postOption(payload=null) {
    const options = {
      method: 'post',
      headers: {
        'Content-Type': 'application/json',
        'Notion-Version': this._notionVersion,
        'Authorization': "Bearer " + this._token
      },
      payload: JSON.stringify(payload),
      muteHttpExceptions: true
    };
    if ( payload === null ){
      delete options['payload']
    }
    return options;
  }
}

Notionのデータベースに含まれるページを取得するメソッドは、queryDatabaseメソッドとしました。
queryDatabaseメソッドでは、データベースに含まれるページのリストを取得するエンドポイントを指定してHTTPリクエストを実行しています。

公式ドキュメントを見ると、リストを取得する際の絞り込み条件を設定することができます。今回は、全件取得したいので、設定なしとしています。

取得したJSONデータをGoogleスプレッドシートのシートに出力する2次元配列を作成

NotionAPIから取得したJSONデータを、2次元配列に変換する処理は、convert2DArrayFromNotion_関数で処理をまとめています。

公式ドキュメントで、NotionAPIから戻ってくるJSONデータの構成を確認します。
Responseが200、成功の場合、Response bodyは、下記のようなオブジェクトで構成されていることが分かります。

データベース内に含まれるページは、プロパティ名:resultsが配列で格納されていることが確認できました。

次に、データベースの列のデータのプロパティを確認します。
テーブルに表示される列は、ページコンテンツのヘッダ部分である、ページプロパティ(Page properties)です。プロパティ名は、propertiesになります。

コンソールログに取得したデータを表示して確認してみます。

const json = response.getContentText();
const data = JSON.parse(json);
console.log(data);

なお、Notionのページの構成については、下記の記事でご紹介していますので、ご参照ください。

続いては、各列のプロパティを取得します。プロパティ毎に階層が異なるので、個別に関数を準備しました。

プロパティがTitleの場合の値を取得する関数は、getTitleValue_関数として定義しています。

function getTitleValue_(obj){
  let value = '';

  if ( !obj['title'] ) return value;
  if ( obj['title'].length === 0 ) return value;
  value = obj['title'][0]['text']['content'];
  return value;
}

プロパティがDateの場合の値を取得する関数は、getDateTypeValue_関数として定義しています。

function getDateTypeValue_(obj){
  let value = '';

  if ( !obj['date'] ) return value;
  value = Utilities.formatDate(new Date(obj['date']['start']), 'JST', 'yyyy/MM/dd');
  return value;
}

プロパティがSelectの場合の値を取得する関数は、getSelectTypeValue_関数として定義しています。

function getSelectTypeValue_(obj){
  let value = '';

  if ( !obj['select'] ) return value;
  value = obj['select']['name'];
  return value;
}

順番にプロパティを取得して、2次元配列に格納します。

    values.push([
      title,
      date,
      type,
    ]);

最後に、見出し行を先ほど作成した2次元配列の先頭に追加します。

const header = [
    '件名',
    'イベント時間',
    '種別'
  ];
values.unshift(header);

Googleスプレッドシートに書き込みを行って処理は完了です!

const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('会議');
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);

まとめ

今回は、GASでNotionのデータベースの列を、Googleスプレッドシートに転記する処理を実装しました。

このスクリプトをGASのトリガーを使用して、定期実行を行うことで、Googleスプレッドシートに転記しておくことで、バックアップする、ということもできるようになります。

この記事が気に入ったらサポートをしてみませんか?