Notionシステム研究所 > GASとNotion APIを連携する方法|1ページを更新するコードから始める

GASとNotion APIを連携する方法|1ページを更新するコードから始める

2026年10月22日

•約7分で読めます

Google Apps ScriptからNotion APIを呼び、検証用ページの数値と日時を更新するコードを掲載。Script Properties、APIバージョン、列名と型の検査、時間主導トリガーの運用を解説します。

Notion
GAS
Google Apps Script
Notion API

Google Apps Script(GAS)からNotionへデータを送るには、UrlFetchApp でNotion APIを呼び出します。最初は、新しいページを大量に作る処理より、決めた1ページの2項目だけを更新する処理で接続を確かめると、問題を切り分けやすくなります。

この記事では、検証用ページの「集計件数」と「連携確認日時」を更新する最小例を扱います。フォーム回答の受信やCSVの照合は別の処理なので、Googleフォーム連携、CSVの差分更新を参照してください。

用意するのは、Notionの検証用DBとGASのプロジェクト

本番DBとは別に検証用DBを作り、次のプロパティを追加します。

名前 Notionの型 今回の役割
名前 タイトル 「GAS接続確認」など任意の名称
集計件数 数値 サンプル値12を書き込む
連携確認日時 日付 コードを実行した時刻を書き込む

DBに「GAS接続確認」というページを1件作ります。ページ本文には確認用のメモを置いて構いません。今回のコードはこの本文を変更しません。

次にNotionの内部コネクションを作成し、読み取り・更新に必要な権限を設定して、検証用DBへ接続します。ページにアクセスできる自分の権限と、コネクションの権限は別です。設定の全体像はNotionインテグレーションの基本で確認できます。

トークンとページIDをスクリプトプロパティに置く

Apps Scriptのプロジェクト設定で、次のスクリプトプロパティを登録します。

キー 登録する値
NOTION_TOKEN 内部コネクションのトークン
NOTION_PAGE_ID 検証用DBの中に作った1ページのID

ここで使うのはページIDです。DB全体のIDやデータソースIDを入れると、更新対象が違います。APIの取得結果等でページIDを確認し、URL全体やビューを指定するパラメーターを混ぜないでください。

スクリプトプロパティを使うと、コード本文へのトークンの直書きを避けられます。ただし、プロジェクトの編集者から秘密を隔離する保管庫ではありません。プロジェクトの共有範囲も絞ります。Google公式:Properties Service

そのまま貼り付けて試せる更新コード

以下は、架空の集計値12を送る学習用コードです。実データを集計する処理は含みません。APIバージョンは 2026-03-11 を指定しています。Notion公式:APIバージョン

function updateNotionSample() {
  const lock = LockService.getScriptLock();
  if (!lock.tryLock(1000)) {
    throw new Error('別の実行が進行中です');
  }

  try {
    const config = PropertiesService.getScriptProperties();
    const token = config.getProperty('NOTION_TOKEN');
    const pageId = config.getProperty('NOTION_PAGE_ID');
    const idPattern = /^(?:[0-9a-f]{32}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
    if (!token || !pageId || !idPattern.test(pageId)) {
      throw new Error('トークンまたはページIDの設定を確認してください');
    }

    const current = notionRequest_('get', pageId, token);
    const props = current.properties || {};
    if (props['集計件数']?.type !== 'number' ||
        props['連携確認日時']?.type !== 'date') {
      throw new Error('検証用DBの列名と型を確認してください');
    }

    const count = 12; // 動作確認用。実運用では取得・検証した集計値に置き換える
    const observedAt = new Date().toISOString();
    notionRequest_('patch', pageId, token, {
      properties: {
        '集計件数': { number: count },
        '連携確認日時': { date: { start: observedAt } }
      }
    });

    const saved = notionRequest_('get', pageId, token);
    const savedCount = saved.properties['集計件数']?.number;
    const savedTime = saved.properties['連携確認日時']?.date?.start;
    if (savedCount !== count ||
        Date.parse(savedTime) !== Date.parse(observedAt)) {
      throw new Error('書き込み後の値が一致しません。再実行前にページを確認してください');
    }
    console.log('検証用ページの2項目を更新し、読み戻しを確認しました');
  } finally {
    lock.releaseLock();
  }
}

function notionRequest_(method, pageId, token, body) {
  const options = {
    method: method,
    headers: {
      Authorization: 'Bearer ' + token,
      'Notion-Version': '2026-03-11'
    },
    muteHttpExceptions: true
  };
  if (body !== undefined) {
    options.contentType = 'application/json';
    options.payload = JSON.stringify(body);
  }
  const response = UrlFetchApp.fetch(
    'https://api.notion.com/v1/pages/' + encodeURIComponent(pageId),
    options
  );
  const status = response.getResponseCode();
  if (status < 200 || status >= 300) {
    throw new Error('Notion API HTTP ' + status + ':実行を停止しました');
  }
  return JSON.parse(response.getContentText());
}

updateNotionSample を選んで実行し、Google側の認可を完了します。Notionで集計件数が12になり、連携確認日時が更新され、本文のメモが残っていることを確認してください。

HTTP呼び出しはGoogleのURL Fetchサービス、更新形式はNotionのページ更新APIに基づいています。コードは各社の公式サンプルの転載ではなく、接続確認用に構成した例です。Google公式:UrlFetchApp、Notion API:ページの更新

エラーは、認証・アクセス・送信内容に分けて調べる

表示・状態 主に確認すること
設定を確認してください プロパティ名、トークンの未設定、ページIDの形式
HTTP 401 トークンの有効性、別環境の値を入れていないか
HTTP 403 コネクションに必要な操作権限があるか
HTTP 404 対象IDと、コネクションへのページ共有
HTTP 400 プロパティ名・型・送信する値の形式
HTTP 429 呼び出し頻度を下げ、Retry-After に従う
更新後の値が不一致 別処理による上書き、想定と異なるページの参照

エラー調査のためにAuthorizationヘッダーやトークンをログへ出す必要はありません。本文の全文出力も避け、対象ページID、HTTPステータス、実行日時など必要な情報だけを記録します。

このサンプルは、自動再試行を入れず失敗時に停止します。書き込み後の応答だけが失われる場合もあるためです。実運用で再試行を追加するときは、現在値の確認とAPIの待機指示を組み合わせます。Notion公式:リクエスト制限

定期実行は、手動で確認してから設定する

手動更新ができたら、Apps Scriptのトリガー画面から updateNotionSample に時間主導トリガーを1つ設定できます。ただし、そのままでは毎回12を書き込むだけです。実運用に移す前に、集計値の取得処理へ置き換え、対象期間と取得日時も決めてください。

トリガーを複数作ると同じ処理が何度も走ります。引き継ぎ時には、前任者のトリガーと新しいトリガーが重なっていないか確認します。インストール型トリガーが作成者のアカウントで動く点も、運用上の確認事項です。Google公式:インストール型トリガー

GASには実行時間やサービスごとの割り当てがあります。大量データを1回で処理する構成へ広げる前に、分割実行と続きから再開する方法を用意しましょう。Google公式:Apps Scriptの割り当て

まず1ページで、認証、読み取り、更新、読み戻しの4段階を確認する。その後に業務データの取得を追加すれば、「Google側で取れていない」のか「Notion側へ書けていない」のかを切り分けながら進められます。

無料PDF・全16ページ

Notion AI 業務連携ホワイトペーパー

Notion AIの業務連携を、図解で具体的に。

業務連携の構成例から、freee・kintoneとの役割分担、費用・権限のチェックリスト、小さな試行の進め方まで全16ページにまとめました。

無料PDF資料。Notion AIが、ツールをつないで仕事を進める。業務連携の構成例と費用・権限のチェックリスト。無料で資料を受け取る。
著者・運営会社
著者
守高 成悟
守高 成悟

代表取締役 CEO

千葉県出身。10歳の頃からプログラミングを始め、ゲーム、Webサイト、ロボット、スマホアプリなどを制作。大阪大学基礎工学部情報科学科で情報工学と統計学を学び、大学時代はAIを研究。大学在学中にWeb広告代理店でのインターンや人材系Webサービスの立ち上げを経験し、卒業後はフリーランスエンジニアとしてGISシステム、データ基盤構築、Webシステムの開発に従事。10年以上のWebアプリ開発・データ分析経験を基に、2023年9月に株式会社ビットライトを設立し、現場業務の仕組み化からデータ基盤構築、データ活用支援までを一気通貫で支援。

運営会社
株式会社ビットライト
株式会社ビットライト

顧客が本当に必要だった価値を、実装する。

現場業務の仕組み化からデータ基盤構築、データ活用支援までを一気通貫で支援しています。

コーポレートサイトを見る