Site cover image

📖Ast-Rock Blog

Notion + astro なブログ

🔄astro-notion-blog の記事更新をGASで反映させる

astro-notion-blog は Notion で書いたページがそのままブログとして公開できる便利なサービスです。

1つ注意点があって、astro-notion-blog は Githubのページにも記載があるように、記事を更新したり、新しく記事を作っても自動で記事をサイトに反映することはできません。

ここでは詳しく解説しませんが、astroの機能で静的サイト(Static Site Generation)として出力しているためです。

astro-notion-blog では新しい記事や変更を公開したいとき毎回デプロイが必要になります。Cloudflare Pages のダッシュボードから手動でデプロイするか、GitHub Action のような CI を使って定時デプロイしてください。

記事を作成、修正するたびに Cloudflare Pages を開いてデプロイするか、Github Actions 利用する必要があります。なんとか手軽に更新したいですよね。

この記事では、一定時間ごとにNotionの記事更新をGoogle Apps Scriptで監視して、更新があったときだけデプロイする方法を紹介します。

記事を更新したときだけデプロイをかける仕組みなのでCloudflare Pages のデプロイ回数(1ヶ月500回)制限にも引っかからず、無駄なデプロイが発生しにくくなります。

また、記事数が多い(数百)場合はビルドに時間がかかるため実行間隔を長く設定したほうがよいです。

https://alpacat.com/blog/astro-notion-blog-02/#ビルドの高速化が必要な理由

下準備

すでに Cloudflare Pages に astro-notion-blogを導入済みとして解説します。

Notion APIとデータベースIDを取得

Notion API トークンとデータベースIDをまだ取得していない場合はastro-notion-blogリポジトリのREADMEか、easy-notion-blog を詳しく解説している horomi さんの記事をごらんください。

Cloudflare Page デプロイURL を取得

Cloudflare にログインして左側の「Pages」を選んだら、すでにデプロイしているリポジトリを開いて「Settings (設定)」をクリックします。

Image in a image block

さらに「Build & deployments」、一番下までスクロールして、Deploya hooksの「Add deploy hook」をクリックしましょう。

任意のフック名とデプロイしたいブランチを選んで「Add」を押します。

Image in a image block

すると、長いURLが表示されるのでクリックしてコピーしておきましょう。

Image in a image block

これがデプロイ用のURLです。

実はこのURLをそのままブラウザに貼り付けても機能しません。…なんてこった。POSTに入れてやらないとダメなんです。

引き続き このデプロイURLを外部から呼び出す紹介します。

Google Apps Script

新規プロジェクトを作成して元のコードを削除し、下記のコードをまるっとコピペします。

Image in a image block
function deployRequest() {
  // Cloudflare デプロイURL
  const deployUrl = "Cloudflare Pages デプロイフック URL";

  let deployOptions = {
    'method' : 'post',
    'contentType': 'application/json',
  };
  UrlFetchApp.fetch(deployUrl, deployOptions);
}

function doGet(e) {
  // 下記時間内に更新していたらデプロイリクエスト(分)
  let freq = 60;

  // 現在時刻から設定した時間を引く
  let date = new Date();
  date.setMinutes(date.getMinutes() - freq);

  // Notion API をセット
  const databaseId = "自分のデータベースID";
  const token = "自分のNotion API TOKEN";
  const url = 'https://api.notion.com/v1/databases/' + databaseId + '/query';

  // Notion データベース取得
  let headers = {
    'content-type' : 'application/json; charset=UTF-8',
    'Authorization': 'Bearer ' + token,
    'Notion-Version': '2021-08-16',
  };

  let filter = {
    "filter": {
      "timestamp": "last_edited_time",
      "last_edited_time": {
          "on_or_after": date
      }
    },
    "sorts": [
        {
            "timestamp": "last_edited_time",
            "direction": "descending"
        }
    ]
  };

  let options ={
    'method': 'post',
    'headers': headers,
    'payload' : JSON.stringify(filter)
  };

  let notionData = UrlFetchApp.fetch(url, options);
  notionData = JSON.parse(notionData);

  // データを配列に入れる
  let arr = notionData["results"];
  let message = "記事の更新はありません。";

  // デプロイリクエスト
  if (arr.length !== 0) { // 更新記事がある場合
    try {
      deployRequest();
      message = "Cloudflare Pages にデプロイリクエストを送りました。";
    } catch(e) {
      message = "デプロイリクエストに失敗しました。時間を置いて試してください。";
    }
  } else { // 更新記事がない場合
      // 何もしない
  };

  return ContentService.createTextOutput(message);
}

仕組みは単純で、Notion APIで取得したデータベース内のページの最終更新時間が現在時刻と比較して60分以内であれば、CloudflareのデプロイURLを送信します。更新記事がなければ特に何も行いません。

コードリビジョン

自分の Notion 情報を入力

以下の3ヶ所をさがして、さきほど取得した CloudfareのデプロイフックURLと、Notion APIトークン、データベースIDを入力してください。

const deployUrl = "Cloudflare Pages デプロイフック URL";

const databaseId = "自分のデータベースID"
const token = "自分のNotion API TOKEN"

トリガーを作成

今回作ったスクリプトを定時に実行するトリガーを作成します。

1時間ごとに作成したスクリプトを実行するトリガーです。

Image in a image block

左メニューの「時計マーク」をクリックしてトリガーの設定を開く。

Image in a image block

実行する関数を選択:doGet

実行するデプロイを選択:Head

イベントのソースを選択:時間主導型

時間ベースの…:時間ベースのタイマー

時間の間隔を選択:1時間おき

👉
時間は任意で設定できます。変更した場合はスクリプト内の let freq = 60 の値も合わせて変更してください。変更しないとデプロイが重複したりデプロイ漏れが発生する可能性があります。

今回のメイン内容はこれで終わりです。反映されるか確認してみてください。

スクリプトをWebアプリ化

ここまでで作ったスクリプトを使えば問題なく自動で記事を更新できます。

ここからはおまけで、手動でも更新したい場合の方法です。

PCやスマホのWebブラウザのブックマークなどに入れておいて、アクセスするとデプロイリクエストを送ることができます。また、非公開のNotionページにURLを貼り付けておいて使用することも可能です。

トリガーをオフにして自分のタイミングで記事更新をかけたいときに便利だと思います。

右上のほうの青いボタンから「新しいデプロイ」をクリックしましょう。

Image in a image block
Image in a image block

歯車マークを選択して「ウェブアプリ」をクリック

以下の様にデプロイの設定をします。

  • 説明:任意の名前
  • 次のユーザーとして実行:自分
  • アクセスできるユーザー:全員
Image in a image block

アクセス権限を付与

Image in a image block

新しくタブが開くので、利用しているGoogle アカウントを選びます。

Image in a image block

そして、以下のような警告ページが表示されますが、大丈夫です。あわてず左下の「Advanced」をクリックしましょう。ここでは英語でしたが、日本語表示の場合でも同じです。

Image in a image block

下の方の「Go to プロジェクト名 (unsafe)」をクリックします。

Image in a image block

「Allow」で外部からこのWebアプリへのアクセスを許可します。

Image in a image block

これでウェブアプリのURLが作成されました。

Image in a image block

「コピー」を押してこのURLを使ってブラウザなどでアクセスしてみましょう。

スマホからでもWebブラウザのブックマークに入れておけば記事を更新したときに、このリンクを使えばデプロイをすることができるので便利ですよ。

記事が更新される場合は「Cloudflare Pages にデプロイリクエストを送りました。」更新がない場合は「記事の更新はありません」と表示されます。

また、デプロイ進行中に再度URLを開くとデプロイリクエストに失敗するので、少し時間を置いて試してください。

🔥
このURLは公開の場には置かないでください。勝手に再デプロイされます。

重要!

GASスクリプトの内容を修正した場合は、スクリプトのデプロイを新たに作成する必要があります。古いデプロイはアーカイブ化するかそのまま残しても大丈夫です。

公式 Webhooksまでのつなぎに

Notion APIで Webhookが使えれば一番いいのですが、残念ながらまだその機能はありません。(Notion ロードマップによると今後公開予定)