🚀

Notion APIとGitHub Actionsで毎日ページを自動生成する

2022/08/17に公開2

どうも。えーたん(@eetann092)です。

先日、Chrome拡張機能Choomameを公開し、GitHub Actionsを使ったChrome拡張機能の開発の記事も書きました。
その過程でGitHub Actions面白いなぁと思ったので、今回はNotion APIと組み合わせてみました。
本記事では、「毎日午前0時過ぎにNotionのデータベースに自動でページを作成させる手順」を紹介します。

デイリーページのタイトルの入力の手間が省けて少し楽になりました。

ワークフローを見てみよう

ざっくりとしたワークフローの流れは以下です。

  1. ワークフローのトリガーを設定する
  2. ワークフローの実行環境を整える
  3. Notion APIを実行する

先に実際に使っているワークフローの定義を載せます。

.github/workflows/generator.yaml
name: Notion Daily Generator
on:
  schedule:
    - cron: "8 15 * * *" # 毎日 0 時 8 分(JST)に実行
  workflow_dispatch:
jobs:
  notion-daily-generator:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm run deploy
        env:
          NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
          DATABASE_ID: ${{ secrets.DATABASE_ID }}

区切って順に説明します。

ワークフローのトリガーを設定する

まず、最初はワークフローの名前といつ実行するかを書いています。

.github/workflows/generator.yaml
name: Notion Daily Generator
on:
  schedule:
    - cron: "8 15 * * *" # 毎日 0 時 8 分(JST)に実行
  workflow_dispatch:

GitHubの公式ドキュメントGitHub Actions を月初の日本時間0〜9時に実行したいを参考に、日本時間における午前0時8分にワークフローが実行されるようにしました。
また、一応手動でも実行できるようにworkflow_dispatchも指定しています。

ワークフローの実行環境を整える

次に、ワークフロー内でのリポジトリの準備をします。

.github/workflows/generator.yaml
jobs:
  notion-daily-generator:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
          cache: npm
      - run: npm ci
      - run: npm run lint

今回はpackage.jsonscriptsに書いたlinterの実行も同じジョブで行っています。

Notion APIを実行する

最後に、実際にNotion APIを実行しています。

.github/workflows/generator.yaml
      - run: npm run deploy
        env:
          NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
          DATABASE_ID: ${{ secrets.DATABASE_ID }}

先に、envで指定している環境変数について説明します。今回実行するスクリプトでは、「Notion APIを実行するために必要なToken」をNOTION_API_KEY、「ページを作成したいデータベースのID」をDATABASE_IDとして登録しました。
取得方法はNotion API公式ドキュメントをご覧ください。

取得した値は、GitHubのリポジトリの「Settingsタブ > Security > Secrets > Actions」からsecretsとして登録します。

secretsの登録

npm run deployで実際にAPIを叩いています。以下がpackage.jsonscriptsの例です。

package.json
  "scripts": {
    "lint": "eslint src && prettier --check src",
    "deploy": "tsc && node dist/index.js"
  },

dist/index.jsのビルド前であるsrc/index.tsは以下です。
@notionhq/clientと今回は日付操作にdayjsを使ってみました。

src/index.ts
import { Client } from "@notionhq/client";
import dayjs from "dayjs";
import ja from "dayjs/locale/ja";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.locale(ja);

const notion = new Client({ auth: process.env.NOTION_API_KEY });
const DATABASE_ID: string = process.env.DATABASE_ID || "";
const now = dayjs().tz("Asia/Tokyo");
const YYYYMMDD = now.format("YYYY-MM-DD");
const YYYYMMDDdd = now.format("YYYY-MM-DD (ddd)");

(async () => {
  const alreadyExist = await notion.databases.query({
    database_id: DATABASE_ID,
    filter: {
      property: "Name",
      title: {
        equals: YYYYMMDDdd,
      },
    },
  });
  if (alreadyExist.results.length !== 0) {
    console.log("すでに作成されています");
    return;
  }
  try {
    await notion.pages.create({
      parent: {
        database_id: DATABASE_ID,
      },
      properties: {
        Name: {
          title: [
            {
              text: {
                content: YYYYMMDDdd,
              },
            },
          ],
        },
        Date: {
          type: "date",
          date: {
            start: YYYYMMDD,
            end: null,
          },
        },
      },
    });
    console.log("作成したぞ");
  } catch (e) {
    console.log(e);
  }
})();

Dateプロパティにスクリプト実行時の日付を指定しました。タイトルは2022-08-16 (火)のような形式にしています。
本文やアイコンについてはNotionのテンプレ機能をそのまま使う想定です。

注意事項

今回のようなスケジュール形式のワークフローについては、公式ドキュメントに書かれているように制限があるようです。

パブリックリポジトリでは、60日間にリポジトリにアクティビティがなかった場合、スケジュールされたワークフローは自動的に無効化されます。

最後に

冒頭にも書いたとおり、デイリーページの作成でタイトル入力の手間が省けたので良かったです。

筆者のデイリーページの使い方については今度別の記事にでも書きます。

Discussion

aGlnYWtpbg==aGlnYWtpbg==

パブリックリポジトリでは、60日間にリポジトリにアクティビティがなかった場合、スケジュールされたワークフローは自動的に無効化されます。

こちらについては、github actionの処理の中で git commit, pushを行うようにしてやることで回避することができますよ。

      - name: Git commit and push
        run: |
          git pull
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git commit --allow-empty -m "prevent automatic workflow stopping" 
          git push