GASでスプレッドシートのデータをNotionに自動同期する方法

「スプレッドシートのデータをNotionに手動でコピーしているが、入力漏れやミスが多い…」そんな悩みを抱える方は多いはずです。この記事では、Google Apps Script(GAS)とNotion APIを使って、スプレッドシートのデータをNotionデータベースへ自動同期する仕組みを、コードつきで徹底解説します。

Notionは多機能なプロジェクト管理ツールですが、既存のスプレッドシートとのデータ連携は手動になりがちです。GASを使えば、毎日決まった時間にスプレッドシートの最新データをNotionに自動で同期させることができます。プログラミング経験が浅くても、コードをコピーして設定するだけで動かせるよう丁寧に説明します。

この記事でできること

  • スプレッドシートの行データをNotionデータベースのページとして自動追加
  • 差分検知で重複なく新規行のみを同期
  • 毎朝9時に自動実行するトリガー設定
  • 同期済みフラグをスプレッドシートに自動書き込み

事前準備(15分)

以下のものを事前に用意してください。

  • Googleアカウント(スプレッドシートが使えるもの)
  • Notionアカウント(無料プランでOK)
  • Notion APIキー:Notionの「設定とメンバー」→「APIと連携」→「新しいインテグレーションを作成」から取得
  • NotionデータベースID:同期先のNotionデータベースURLに含まれる32文字のID

NotionデータベースのURLは https://www.notion.so/xxxxxxxxxx?v=yyyyyy の形式です。xxxxxxxxxx部分(ハイフンなし32文字)がデータベースIDです。また、作成したインテグレーションをデータベースに「接続」する必要があります(データベース右上「…」→「接続先を追加」)。

STEP 1:スプレッドシートの構成を確認する

今回は以下のような営業リスト(シート名:「リスト」)を例にします。A列〜D列にデータが入り、E列を「同期済みフラグ」として使います。

A列:会社名B列:担当者C列:ステータスD列:次回アクション日E列:同期済み
株式会社〇〇田中太郎商談中2026/04/25(空白)

NotionデータベースにはA〜D列に対応するプロパティを作成してください。プロパティ名は日本語でもOKです(コードで指定します)。

STEP 2:GASスクリプトを作成する

スプレッドシートを開き、「拡張機能」→「Apps Script」を選択してスクリプトエディタを開きます。デフォルトのコードを削除し、以下のコードを貼り付けてください。

// ===== 設定値 =====
const NOTION_API_KEY = PropertiesService.getScriptProperties().getProperty('NOTION_API_KEY');
const DATABASE_ID = PropertiesService.getScriptProperties().getProperty('DATABASE_ID');
const SHEET_NAME = 'リスト';
const SYNCED_COLUMN = 5; // E列(1始まり)
const DATA_START_ROW = 2; // ヘッダー行の次から

function syncToNotion() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
  const lastRow = sheet.getLastRow();
  
  if (lastRow < DATA_START_ROW) {
    console.log('データがありません');
    return;
  }
  
  const dataRange = sheet.getRange(DATA_START_ROW, 1, lastRow - DATA_START_ROW + 1, 5);
  const values = dataRange.getValues();
  
  let syncCount = 0;
  
  values.forEach((row, index) => {
    const [companyName, contactPerson, status, nextActionDate, synced] = row;
    
    // 同期済みの行はスキップ
    if (synced === '済') return;
    // 会社名が空の行はスキップ
    if (!companyName) return;
    
    const notionPage = createNotionPage(companyName, contactPerson, status, nextActionDate);
    
    if (notionPage) {
      // 同期済みフラグを書き込む
      sheet.getRange(DATA_START_ROW + index, SYNCED_COLUMN).setValue('済');
      syncCount++;
      Utilities.sleep(300); // API制限対策
    }
  });
  
  console.log(`同期完了: ${syncCount}件`);
}

function createNotionPage(companyName, contactPerson, status, nextActionDate) {
  const url = 'https://api.notion.com/v1/pages';
  
  // 日付のフォーマット(スプレッドシートのDate型をISO文字列に変換)
  let dateStr = '';
  if (nextActionDate instanceof Date) {
    dateStr = Utilities.formatDate(nextActionDate, 'Asia/Tokyo', 'yyyy-MM-dd');
  } else if (nextActionDate) {
    dateStr = String(nextActionDate);
  }
  
  const payload = {
    parent: { database_id: DATABASE_ID },
    properties: {
      '会社名': {
        title: [{ text: { content: String(companyName) } }]
      },
      '担当者': {
        rich_text: [{ text: { content: String(contactPerson || '') } }]
      },
      'ステータス': {
        select: { name: String(status || '') }
      },
      '次回アクション日': {
        date: dateStr ? { start: dateStr } : null
      }
    }
  };
  
  const options = {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + NOTION_API_KEY,
      'Content-Type': 'application/json',
      'Notion-Version': '2022-06-28'
    },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };
  
  const response = UrlFetchApp.fetch(url, options);
  const responseCode = response.getResponseCode();
  const responseBody = JSON.parse(response.getContentText());
  
  if (responseCode === 200) {
    console.log(`追加成功: ${companyName}`);
    return responseBody;
  } else {
    console.error(`エラー (${responseCode}): ${companyName} - ${JSON.stringify(responseBody)}`);
    return null;
  }
}

STEP 3:APIキーとデータベースIDをスクリプトプロパティに設定する

APIキーなどの秘密情報はコードに直書きせず、スクリプトプロパティを使って安全に管理します。スクリプトエディタの左メニューから「プロジェクトの設定」→「スクリプト プロパティ」→「プロパティを追加」で以下を設定してください。

  • NOTION_API_KEY:Notionインテグレーションのシークレットキー(secret_xxx...の形式)
  • DATABASE_ID:同期先NotionデータベースID(32文字の英数字)

設定後、スクリプトエディタ上部の関数名を「syncToNotion」に選択して▶ボタンをクリックし、初回の認証許可を行ってください。

STEP 4:動作確認

スクリプトを手動実行し、Notionデータベースに行が追加されることを確認します。

トラブルシュートチェックリスト

  • 「401 Unauthorized」エラー:NOTION_API_KEYが正しく設定されているか確認。スクリプトプロパティに保存したか再確認する
  • 「object not found」エラー:DATABASE_IDが間違っている、またはインテグレーションがデータベースに接続されていない。Notionのデータベース右上「…」→「接続先を追加」でインテグレーションを追加する
  • プロパティ名エラー:Notionデータベースのプロパティ名とコード内の文字列が完全一致していることを確認(全角・半角・スペースの差異に注意)
  • 日付が入らない:スプレッドシートの日付セルの形式を確認。テキストではなく日付型になっているか確認する

定期実行トリガーを設定する

毎朝9時に自動実行するには、スクリプトエディタ左メニューの時計アイコン「トリガー」をクリックし、以下の設定でトリガーを追加します。

  • 実行する関数:syncToNotion
  • イベントのソース:時間主導型
  • 時間ベースのトリガーのタイプ:日タイマー
  • 時刻:午前9時〜10時

設定後は「保存」を押すだけで、翌朝から自動同期が始まります。スプレッドシートに新しい行を追加するだけで、翌朝Notionに自動反映される運用が完成します。

応用:さらに便利にする拡張アイデア

  • 双方向同期:Notionのページ更新をWebhookで受け取り、GASでスプレッドシートに書き戻す(Notion Webhookは現在β機能)
  • ステータス変更時のみ同期:E列のフラグをステータス値と組み合わせ、「商談中→成約」に変わった行だけを別のNotionデータベースに追加する
  • Slack通知との組み合わせ:syncToNotionの完了後にSlack通知を送り、同期件数を自動報告する仕組みにする
  • 複数シートの一括同期:シート名を配列で管理し、複数のスプレッドシートを1つのGASスクリプトでまとめて同期する

まとめ

GASとNotion APIを組み合わせることで、スプレッドシートからNotionへのデータ自動同期が実現できます。手動コピーのミスや手間をゼロにして、常に最新データをNotionで管理できる環境を構築しましょう。

  • Notion APIキーとデータベースIDをスクリプトプロパティに安全保管する
  • E列の「同期済みフラグ」で重複同期を防止する
  • 時間トリガーで毎朝自動実行することで完全な自動化が完成する
  • Slack通知や複数シート対応などの拡張で、さらに実用的な仕組みに育てられる

GASとNotion APIの連携設定でお困りの点があれば、お気軽にお問い合わせください。御社の業務フローに合わせたカスタマイズも承っています。

お問い合わせはこちら

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA