Notion APIとGitHub Actionsで毎日ページを自動生成する
どうも。えーたんです。
先日、Chrome拡張機能Choomameを公開し、GitHub Actionsを使ったChrome拡張機能の開発の記事も書きました。
その過程でGitHub Actions面白いなぁと思ったので、今回はNotion APIと組み合わせてみました。
本記事では、「毎日午前0時過ぎにNotionのデータベースに自動でページを作成させる手順」を紹介します。
デイリーページのタイトルの入力の手間が省けて少し楽になりました。
ワークフローを見てみよう
ざっくりとしたワークフローの流れは以下です。
- ワークフローのトリガーを設定する
- ワークフローの実行環境を整える
- Notion APIを実行する
先に実際に使っているワークフローの定義を載せます。
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 }}
区切って順に説明します。
ワークフローのトリガーを設定する
まず、最初はワークフローの名前といつ実行するかを書いています。
name: Notion Daily Generator
on:
schedule:
- cron: "8 15 * * *" # 毎日 0 時 8 分(JST)に実行
workflow_dispatch:
GitHubの公式ドキュメントとGitHub Actions を月初の日本時間0〜9時に実行したいを参考に、日本時間における午前0時8分にワークフローが実行されるようにしました。
また、一応手動でも実行できるように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
今回はpackage.json
のscripts
に書いたlinterの実行も同じジョブで行っています。
Notion APIを実行する
最後に、実際にNotion APIを実行しています。
- 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として登録します。
npm run deploy
で実際にAPIを叩いています。以下がpackage.json
のscripts
の例です。
"scripts": {
"lint": "eslint src && prettier --check src",
"deploy": "tsc && node dist/index.js"
},
dist/index.js
のビルド前であるsrc/index.ts
は以下です。
@notionhq/client
と今回は日付操作にdayjs
を使ってみました。
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
こちらについては、github actionの処理の中で git commit, pushを行うようにしてやることで回避することができますよ。
回避策自体は知っていたのですが、具体的な手順までは知らなかったので助かります🙏
ありがとうございます!