NotionデータベースとGAS連携 「シートへ転記」編

GASで自動化・効率化

Notionのデータベースをスプレッドシートへ自動で転記しよう

この記事では、NotionのデータベースをGoogleスプレッドシートへ自動で転記する方法を、初心者向けにカンタンに解説します。

はじめに

今回は以下のようなデータベースを例に進めます。

タスク日付進捗備考
サンプルA2026-04-01完了メモ
サンプルB2026-04-02作業中メモ

全体の流れ(ざっくり理解)

まずは全体像を理解しましょう。

  1. NotionでAPIキーを取得
  2. データベースIDを取得
  3. GASでAPIを呼び出す
  4. スプレッドシートに書き込む

この4ステップで連携できます。

Notion APIの準備

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

  1. Notionの「My integrations」にアクセス
  2. 「新しいインテグレーションを作成」をクリック
  3. 名前を入力して作成

Notionの「My integrations」にアクセスするには「設定」→「コネクト」→「インテグレーションを作成または管理する」をクリック

「新しいインテグレーションを作成」の左の「+」ボタンをクリックして新規作成

「インテグレーション名」にわかりやすい名前を入力する。

「関連ワークスペース」の欄をクリックして使用するワークスペースを選択する。

「作成」ボタンをクリックして作成します。

② APIキー取得

作成後に表示される「Internal Integration Token」をコピー

③ データベースと接続

対象データベース右上の「…」→「接続を追加」から、作成したIntegrationを追加

NotionデータベースIDの取得方法

URLから取得できます。

<https://www.notion.so/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?v=yyyy>

この「xxxxxxxx」の部分がデータベースIDです。

Google Apps Script(GAS)の準備

  1. Googleスプレッドシートを開く
  2. 「拡張機能」→「Apps Script」を開く
  3. 新規プロジェクト作成

【サンプル①】全項目を転記

データベースの項目をすべてシートに転記するサンプルです。

function notionToSheet_All() {

  const token = "YOUR_NOTION_API_KEY";
  const databaseId = "YOUR_DATABASE_ID";

    const url = `https://api.notion.com/v1/databases/${databaseId}/query`;

  const options = {
    method: "post",
    headers: {
      "Authorization": "Bearer " + token,
      "Notion-Version": "2022-06-28",
      "Content-Type": "application/json"
    }
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  sheet.clear();

  // ヘッダー
  sheet.appendRow(["タスク", "日付", "進捗", "備考"]);

  data.results.forEach(page => {

    const props = page.properties;

    const task = props["タスク"].title[0]?.plain_text || "";
    const date = props["日付"].date?.start || "";
    const status = props["進捗"].select?.name || "";
    const note = props["備考"].rich_text[0]?.plain_text || "";

    sheet.appendRow([task, date, status, note]);
  });
}

【サンプル②】特定の項目のみ転記

以下は「タスク」と「進捗」だけ転記する例です。

function notionToSheet_Selected() {

  const token = "YOUR_NOTION_API_KEY";
  const databaseId = "YOUR_DATABASE_ID";

    const url = `https://api.notion.com/v1/databases/${databaseId}/query`;

  const options = {
    method: "post",
    headers: {
      "Authorization": "Bearer " + token,
      "Notion-Version": "2022-06-28",
      "Content-Type": "application/json"
    }
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  sheet.clear();

  sheet.appendRow(["タスク", "進捗"]);

  data.results.forEach(page => {

    const props = page.properties;

    const task = props["タスク"].title[0]?.plain_text || "";
    const status = props["進捗"].select?.name || "";

    sheet.appendRow([task, status]);
  });
}

【サンプル③】条件に合うデータのみ転記

「進捗」が「完了」のものだけ取得します。

function notionToSheet_Filtered() {

  const token = "YOUR_NOTION_API_KEY";
  const databaseId = "YOUR_DATABASE_ID";

    const url = `https://api.notion.com/v1/databases/${databaseId}/query`;

  const options = {
    method: "post",
    headers: {
      "Authorization": "Bearer " + token,
      "Notion-Version": "2022-06-28",
      "Content-Type": "application/json"
    },
    payload: JSON.stringify({
      filter: {
        property: "進捗",
        select: {
          equals: "完了"
        }
      }
    })
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  sheet.clear();

  sheet.appendRow(["タスク", "日付", "進捗"]);

  data.results.forEach(page => {

    const props = page.properties;

    const task = props["タスク"].title[0]?.plain_text || "";
    const date = props["日付"].date?.start || "";
    const status = props["進捗"].select?.name || "";

    sheet.appendRow([task, date, status]);
  });
}

【サンプル④】全項目を転記(タイトルも自動で作成する)

データベースの項目をそのままタイトル名として転記するサンプルです。

/**
 * スクリプトプロパティから設定を読み込んでNotionデータを転記
 */
function syncNotionToSheetsWithProperties() {
  // --- スクリプトプロパティから設定を取得 ---
  const props = PropertiesService.getScriptProperties();
  const NOTION_API_KEY = props.getProperty('NOTION_API_KEY');
  const DATABASE_ID = props.getProperty('DATABASE_ID');
  const SHEET_NAME = props.getProperty('SHEET_NAME') || 'シート1'; // 未設定なら'シート1'

  // 設定漏れチェック
  if (!NOTION_API_KEY || !DATABASE_ID) {
    throw new Error('スクリプトプロパティ "NOTION_API_KEY" または "DATABASE_ID" が設定されていません。');
  }

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
  if (!sheet) {
    throw new Error(`シート名「${SHEET_NAME}」が見つかりません。`);
  }
  
  const url = `https://api.notion.com/v1/databases/${DATABASE_ID}/query`;
  const options = {
    method: 'post',
    headers: {
      'Authorization': `Bearer ${NOTION_API_KEY}`,
      'Notion-Version': '2022-06-28',
      'Content-Type': 'application/json'
    }
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());
  const results = data.results;

  if (results.length === 0) {
    console.log("Notion側にデータがありません。");
    return;
  }

  // --- 1行目(ヘッダー)とデータの作成 ---
  const headerRow = ['タスク', '日付', '進捗', '備考'];
  const values = results.map(page => {
    const p = page.properties;
    
    return [
      p['タスク']?.title[0]?.plain_text || '',
      p['日付']?.date?.start || '',
      p['進捗']?.select?.name || p['進捗']?.status?.name || '',
      p['備考']?.rich_text[0]?.plain_text || ''
    ];
  });

  // --- スプレッドシートへの書き込み ---
  sheet.clear(); 
  sheet.getRange(1, 1, 1, headerRow.length).setValues([headerRow]);
  if (values.length > 0) {
    sheet.getRange(2, 1, values.length, headerRow.length).setValues(values);
  }

  // 書式設定
  sheet.getRange(1, 1, 1, headerRow.length).setFontWeight("bold").setBackground("#f3f3f3");
  sheet.setFrozenRows(1); // 1行目を固定
  
  console.log("スクリプトプロパティを使用して同期を完了しました。");
}

【サンプル⑤】条件に合うデータのみ転記(タイトルも自動作成)

④のようにタイトルも自動で作成し、さらに条件によって絞り込むサンプルです。

項目を「タスク」と「進捗」に絞り、進捗のデータは「完了」のみを抽出して転記します。

/**
 * Notionから「完了」タスクのみを「シート2」へ転記するスクリプト
 */
function syncCompletedTasksToSheet2() {
  // --- スクリプトプロパティから設定を取得 ---
  const props = PropertiesService.getScriptProperties();
  const NOTION_API_KEY = props.getProperty('NOTION_API_KEY');
  const DATABASE_ID = props.getProperty('DATABASE_ID');
  const SHEET_NAME = 'シート2'; // 今回は直接「シート2」を指定、またはプロパティで管理

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
  if (!sheet) {
    throw new Error(`シート名「${SHEET_NAME}」が見つかりません。スプレッドシートにシートを作成してください。`);
  }
  
  const url = `https://api.notion.com/v1/databases/${DATABASE_ID}/query`;
  const options = {
    method: 'post',
    headers: {
      'Authorization': `Bearer ${NOTION_API_KEY}`,
      'Notion-Version': '2022-06-28',
      'Content-Type': 'application/json'
    }
  };

  const response = UrlFetchApp.fetch(url, options);
  const data = JSON.parse(response.getContentText());
  const results = data.results;

  // --- データの絞り込みと抽出 ---
  // 1. 進捗が「完了」のものだけをフィルタリング
  // 2. 「タスク」と「進捗」の列だけを抽出
  const filteredValues = results
    .filter(page => {
      const progress = page.properties['進捗']?.select?.name || page.properties['進捗']?.status?.name || '';
      return progress === '完了'; // ここで絞り込み条件を指定
    })
    .map(page => {
      const p = page.properties;
      return [
        p['タスク']?.title[0]?.plain_text || '',
        p['進捗']?.select?.name || p['進捗']?.status?.name || ''
      ];
    });

  // --- スプレッドシートへの書き込み ---
  const headerRow = ['タスク', '進捗'];
  sheet.clear(); 
  
  // ヘッダーの書き込み
  sheet.getRange(1, 1, 1, headerRow.length).setValues([headerRow]);
  
  // データがある場合のみ2行目以降に書き込み
  if (filteredValues.length > 0) {
    sheet.getRange(2, 1, filteredValues.length, headerRow.length).setValues(filteredValues);
    console.log(`${filteredValues.length}件の完了済みタスクを同期しました。`);
  } else {
    console.log("「完了」ステータスのタスクは見つかりませんでした。");
  }

  // 書式設定
  sheet.getRange(1, 1, 1, headerRow.length).setFontWeight("bold").setBackground("#e6f4ea"); // 完了っぽく薄い緑
  sheet.setFrozenRows(1);
}

よくあるエラーと対処

① 401エラー

→ APIキーが間違っている

② 空データになる

→ Integrationがデータベースに接続されていない

③ プロパティが取得できない

→ プロパティ名(日本語含む)が一致しているか確認

まとめ

今回は、NotionのデータベースをGASでスプレッドシートに転記する方法を解説しました。

やってみると、意外に簡単にできた!と感動するのではないでしょうか。

ポイントはこの3つです。

  • Notion APIの設定が最重要
  • GASでAPIを呼び出すだけで連携可能
  • フィルターや項目選択で柔軟にカスタマイズできる

この仕組みを応用すれば、

  • タスク管理の自動集計
  • レポート作成
  • ダッシュボード化

など、業務効率化に大きく役立ちます。

ぜひ自分の環境に合わせてカスタマイズしてみてください!

タイトルとURLをコピーしました