HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
執筆中ページ/
📕
「Notion API 活用術」テンプレート
/
4️⃣
S21. Google カレンダーからタスクを作成するアプリ
4️⃣

S21. Google カレンダーからタスクを作成するアプリ

⚠️
補足情報
2023年3月現在、まだ Google カレンダーの同期データベースは実装されていません。そのため、この節は多くの読者が興味を持っており、実際に自分で実装したいと考えていると思います。そのため、ここについてはチェックボックス形式でワークシートの形にしてみました。

21.1 タスクデータベースの作成

  • 最初は練習のため、このテンプレートデータベースでテストしてみてください。うまく動いたら自分のタスクデータベースに差し替えるといいでしょう。
    • サンプルタスクデータベース
タスクデータベースを準備
タスクデータベースにインテグレーションキーをコネクト
タスクデータベースの URL を取得
タスクデータベースURL (例: https://www.notion.so/hkob/33a3ea2f301f46d781a5cdcb8dc90231?v=b1e5f0dc7f644d9abf63bc695788c4e1)
タスクデータベースの database_id を取得
タスクデータベースID (例: 33a3ea2f301f46d781a5cdcb8dc90231)

21.2 Google Calendar API の有効化

Google Cloud Platform へアクセス
Google Cloud Platform
Google Cloud Platform lets you build, deploy, and scale applications, websites, and services on the same infrastructure as Google.
Google Cloud Platform
https://console.developers.google.com/apis/
Google Calendar API を有効化

21.3 GAS 環境の準備

Google Sheets: Sign-in
Access Google Sheets with a personal Google account or Google Workspace account (for business use).
Google Sheets: Sign-in
https://docs.google.com/spreadsheets/u/0/
アプリに名前を設定
カレンダーサービスを追加

21.4 Google Calendar の準備

Sign in
Access Google Calendar with a free Google account (for personal use) or Google Workspace account (for business use).
Sign in
https://calendar.google.com/calendar/u/0/r
カレンダーID (hogehoge@group.calendar.google.com)
CALENDAR_ID プロパティを追加
NOTION_API_KEY プロパティを追加
DATABASE_ID プロパティを追加
NOTION_VERSION プロパティを追加

21.5 カレンダー認証

19節で紹介した以下の関数をコピーしておきます。同期ブロックで持ってきています。
scriptPropertyFor を追加
// スクリプトプロパティを取得 function scriptPropertyFor(key) { return PropertiesService.getScriptProperties().getProperty(key) }
スクリプトプロパティ取得関数
notionAPIKey を追加
notionVersion を追加
databaseID を追加
// NOTION_API_KEY を取得 function notionAPIKey() { return scriptPropertyFor("NOTION_API_KEY") } // NOTION_VERSION を取得 function notionVersion() { return scriptPropertyFor("NOTION_VERSION") } // DATABASE_ID を取得 function databaseID() { return scriptPropertyFor("DATABASE_ID") }
特定スクリプトプロパティ取得関数
saveScriptPropertyTo を追加
// スクリプトプロパティにデータを保存 function saveScriptPropertyTo(key, value) { PropertiesService.getScriptProperties().setProperty(key, value) }
スクリプトプロパティ設定関数
sendNotion を追加
// Notion に payload を send する function sendNotion(url_sub, payload, method) { const options = { "method": method, "headers": { "Content-type": "application/json", "Authorization": "Bearer " + notionAPIKey(), "Notion-Version": notionVersion(), }, "payload": payload ? JSON.stringify(payload) : null }; // デバッグ時にはコメントを外す // console.log(options) Utilities.sleep(400) const url = "https://api.notion.com/v1/" + url_sub return JSON.parse(UrlFetchApp.fetch(url, options)) }
Notionに payload を送信する
createPage を追加
// Create Page API を呼び出す function createPage(payload) { return sendNotion("pages", payload, "POST") }
Create page API を呼び出す
updatePage を追加
// Update Page API を呼び出す function updatePage(page_id, payload) { return sendNotion("pages/" + page_id, payload, "PATCH") }
Update page API を呼び出す
readCalendar までを記述
// CALENDAR_ID を取得 function calendarID() { return scriptPropertyFor("CALENDAR_ID") } // 前回保存したカレンダーのSyncTokenを取り出す、前回保存分が無い場合は今回のSyncTokenを利用する function getSyncToken(calendar_id) { const token = PropertiesService.getScriptProperties().getProperty("SYNC_TOKEN") if (token) { return token } const events = Calendar.Events.list(calendar_id, {"timeMin": (new Date()).toISOString()}) return events.nextSyncToken } // SyncTokenをプロパティに保存する function saveSyncToken(token) { saveScriptPropertyTo("SYNC_TOKEN", token) } // 初回認証のためだけのテスト呼び出し関数 -> 現在の SYNC_TOKEN を保存 function readCalendar() { const token = getSyncToken(calendarID()) saveSyncToken(token) console.log(token) }
readCalendar を実行して認証

21.6 カレンダーイベントによるトリガ

eventToDateHash を追加
// カレンダーイベントから日付の hash を作成 (削除時にも呼ばれるので、イベントに日付が設定されていなければ null を返却) function eventToDateHash(e) { let hash = null if ("dateTime" in e.start) { hash = { "start": e.start.dateTime, "end": e.end.dateTime } } if ("date" in e.start) { const sday_str = e.start.date hash = { "start": sday_str } let eday = new Date(e.end.date) eday.setDate(eday.getDate() - 1) const eday_str = eday.toISOString().split('T')[0] if (sday_str != eday_str) { hash["end"] = eday_str } } return hash }
カレンダーイベントの hash を作成
updatePayload を追加
// title と date_hash から update payload を作成 function updatePayload(title, date_hash) { return { "properties": { "日付": {"date": date_hash}, "タスク名": {"title": [{"text": {"content": title}}]} } } }
updatePayload
createPayload を追加
// title, date_hash から create payload を作成 function createPayload(title, date_hash) { return { "parent": {"database_id": databaseID()}, "properties": { "日付": {"date": date_hash}, "タスク名": {"title": [{"text": {"content": title}}]}, } } }
createPayload
doCalendarPost を追加
// カレンダーイベントが変更されたら呼ばれるメソッド function doCalendarPost(event) { // カレンダーIDのの取得 const calendar_id = calendarID() // 前回実行時に取得したカレンダーTokenの取得 let token = getSyncToken(calendar_id) // Token から後のカレンダーを取得 const events = Calendar.Events.list(calendar_id, {"syncToken": token}) // ステータスを見て登録、もしくは更新の予定のみにフィルタリング const filtered_items = events.items.filter(e => { return e.status == "confirmed" }) // 今回のTokenを保存する(次回のScript実行時に利用) saveSyncToken(events.nextSyncToken) filtered_items.forEach(e => { const descriptions = (e.description || "").split("\n") const dlen = descriptions.length let exist = false let id = "-" // 行が存在する場合 if (dlen > 0) { // 最後の行を取得 const last_line = descriptions[dlen - 1] // id を取得 const ids = last_line.match(/^id:(.*)$/) // 取得できた場合 if (ids != null && ids[1].length > 31) { // 取得した id id = ids[1]; exist = true } } // イベント日付を取得 const date_hash = eventToDateHash(e) // イベントに日付がある場合だけ実施 if (date_hash) { // 存在した場合は update if (exist) { const payload = updatePayload(e.summary, date_hash) updatePage(id, payload) } else { const payload = createPayload(e.summary, date_hash) const ans = createPage(payload) id = ans["id"] // 作成したページの id をイベントに追加 descriptions.push("id:" + id) e.description = descriptions.join("\n") Calendar.Events.patch(e, calendar_id, e.id) } } }) }
doCalendarPost

21.7 テスト実行

test 関数を追加
function test() { const calendar_id = calendarID() const token = getSyncToken(calendar_id) const events = Calendar.Events.list(calendar_id, {"syncToken": token}) const event = events.items[0] doCalendarPost(event) }
カレンダーの変更をトリガに設定
カレンダーにイベントを追加して、Notion データベースに追加されることを確認
 
⚠️
補足説明
今回、Google カレンダーから Notion に登録するアプリを GAS で作成しました。逆に Notion から Google カレンダーに登録するのを自動化するのは少し面倒です。ただし、特定のタスクを Google カレンダーに登録するのであれば、簡単に実装できます。これを実現するための手段として、最近 NotionToCalendar というショートカットアプリを作成しました。興味があったらブログ記事をご覧ください。
NotionToCalendar ショートカットアプリの作成 - hkob-astro-notion-blog
このドキュメントは、Notion と Google Calendar を連携させるショートカットアプリの作成について説明しています。Notion のタスクを Google Calendar に同期するためのシステムを作成し、そのスクリプトの紹介を行っています(by Notion AI)。
https://www2.metro-cit.ac.jp/~hkob/posts/2023040600/
NotionToCalendar ショートカットアプリの作成 - hkob-astro-notion-blog

🔹
この CHAPTER 内の SECTION
S18. Google Apps Script について
4
18
S19. Notion API アクセスのための関数作成
4
19
S20. Google Form 連携アプリ
4
20
S21. Google カレンダーからタスクを作成するアプリ
4
21
S22. Slack連携アプリ
4
22
🔶
CHAPTER LIST
C1. Notion APIの概要と利用準備
1
C2. Notion APIで理解するNotionのデータ構造
2
C3. Notion APIの基本(CRUD別の紹介)
3
C4. Google Apps Scriptによる応用
4
C5. ショートカットによる応用
5
C6. NotionRubyMappingを利用したツール
6