はじめに
昨日はics からNotion に一括登録する記事を書きました。また、今朝は繰り返しイベントの登録を実施しました。3 本目は Calendar イベント登録時に Notion タスクページを自動登録します。繰り返しイベントでは、時間手動型のイベントを使いましたが、今回はカレンダー更新をトリガーにして、Notion API に送ります。
似たようなことをやっている人がいるだろうと検索したところ、以下の記事を見つけました。カレンダーデータの取得部分については、これを真似ればできそうです。 qiita.com
準備
Google Calendar API の有効化
Google Calendar API が必要とのことなので、API を有効にします。以下のリンク先で設定します。 console.developers.google.com
API ライブラリから、「Google Calendar API」を選びます。以下の画面になるので、「有効にする」をクリックします。
自分のアカウントからのアクセスになるので、認証情報などを追加する必要はないようです。
カレンダーの準備
Google Calendar には Notion という専用のカレンダーを準備しました。このカレンダーの「設定と共有」を表示して、「カレンダーID」を取得しておきます。
Google Apps Script の修正
まず、Google Calendar API を使えるようにするために、サービスを追加します。まず、サービスの右の「+」をクリックします。
Google Calendar API を選択して、「追加」をクリックします。
詳しい説明は省略しますが、スクリプトは以下のようになりました。終了時間の設定もしたいので、前回の繰り返し登録関数の日付部分も少し修正しています。
// 初回認証のためだけのテスト呼び出し関数 function readCalendar() { let calendarId = "この部分にカレンダーIDを書きます。"; let token = getSyncToken(calendarId); Logger.log(token); } function postNotion(payload){ let MY_NOTION_TOKEN = "この部分にIntegration Token を書きます。"; let url = "https://api.notion.com/v1/pages"; // API URL let options = { "method" : "POST", "headers": { "Content-type": "application/json", "Authorization": "Bearer " + MY_NOTION_TOKEN, "Notion-Version": "2021-05-13", }, "payload" : JSON.stringify(payload) }; Logger.log(options); UrlFetchApp.fetch(url, options); } function createPayload(title, date_hash) { let DATABASE_ID = "この部分にDatabase ID を書きます"; payload = { "parent": { "database_id": DATABASE_ID }, "properties": { "タスク名": { "title": [ { "text": { "content": title } } ] }, "日付": { "type": "date", "date": date_hash }, "非ポモ?": { "type": "checkbox", "checkbox": true } } } return payload; } function doCalendarPost(event) { let calendarId = event.calendarId; // カレンダーIDのの取得 let token = getSyncToken(calendarId); // 前回実行時に取得したカレンダーTokenの取得 let events = Calendar.Events.list(calendarId, {'syncToken': token}); // Token から後のカレンダーを取得 let filteredItems = events.items.filter(e => {return e.status == "confirmed"}); // ステータスを見て登録、もしくは更新の予定のみにフィルタリング filteredItems.map(e => {return eventToPayload(e)}).filter(e => {return e}).forEach(p => { postNotion(p); }); // 予定を Notion に通知する saveSyncToken(events.nextSyncToken); // 今回のTokenを保存する(次回のScript実行時に利用) } // 前回保存したカレンダーのSyncTokenを取り出す、前回保存分が無い場合は今回のSyncTokenを利用する function getSyncToken(calendarId){ var token = PropertiesService.getScriptProperties().getProperty('SYNC_TOKEN'); if (token) { return token; } let events = Calendar.Events.list(calendarId, {'timeMin': (new Date()).toISOString()}); return events.nextSyncToken; } function eventToPayload(e) { let hash = null; if ('dateTime' in e.start){ hash = { "start": e.start.dateTime.replace("T", " "), "end": e.end.dateTime.replace("T", " ") } } if ('date' in e.start) { hash = { "start": e.start.date } } return hash ? createPayload(e.summary, hash) : null; } // SyncTokenをプロパティに保存する function saveSyncToken(token){ PropertiesService.getScriptProperties().setProperty('SYNC_TOKEN', token); } function weekToStr(date) { let w = Utilities.formatDate(date, "JST", "u"); return ["日", "月", "火", "水", "木", "金", "土"][w] } function doEverydayPost() { let today = new Date(); let date_hash = {"start": Utilities.formatDate(today, "JST", "yyyy-MM-dd")}; let week_str = weekToStr(today); let title_base = "雑務・振り返り M/d (" + week_str + ")"; let title = Utilities.formatDate(today, "JST", title_base); // テストのためのデバッグ出力 // Logger.log(createPayload(title, date_hash)); postNotion(createPayload(title, date_hash)); }
認証を取得
この後の設定を先にやっていたのですが、認証に失敗してしまいました。テストのために、スクリプトの一番上に書いた「readCalendar」をエディタから実行したところ、アカウントの認証画面に遷移しました。ここで認証をするとこの後の作業も無事に進みました。以下のように readCalendar を選択した状態で、一度だけ実行をクリックしてください。
カレンダートリガの設定
ここまでできたら、カレンダーの更新トリガを設定するだけです。関数として「doCalendarPost」を選択し、イベントのソースを「カレンダーから」とします。カレンダーオーナーのメールアドレスに、上で取得した「カレンダーID」を登録すれば終了です。
デプロイ
ここまでできたら、デプロイをしておきます。説明は省略します。
実行
ここまでできたら、実際にカレンダーを登録してみます。
時間指定イベントの作成
まずは、時間が指定されたイベントの登録です。Google Calendar にて時間指定イベントの登録をおこないます。
Notion を見てみると無事にタスクが登録されています。
終日イベントの作成
今度は時間指定のない終日イベントを登録してみます。
こちらも問題なく終日イベントとして登録されています。
おわりに
カレンダー登録で自動的にタスクに入ってくれるのは、かなり楽ですね。Notion をメインにしてから、カレンダーがスカスカになってしまっていたのが復活しそうです。上の設定では「非ポモ?」をデフォルトで true にしてしまっていますが、タスクをポモドーロで実施する可能性もあるので、実際にはこの設定を外そうと考えています。