はじめに
hkob の雑記録の第449回目(通算23日目)は、年2回しか実施しない授業タスクの一括登録を実施します。
icsToNotion.rb のスクリプト修正
半年の間に Notion API もバージョンが上がっているので、スクリプトの修正が必要になりました。以前は Database に build_child_page していましたが、現在は DataSource に実行するようになっています。このため、Database.find が DataSource.find に変更になっています。
#! /usr/bin/env ruby require "notion_ruby_mapping" include NotionRubyMapping NotionRubyMapping.configure { |c| c.token = ENV["AMBASSADOR_NOTION_API_KEY"] } ds = DataSource.find "1f70ce2a-6520-80ce-bc36-000b08bc3b11" user_id = "fffd872b594c811b82180002b0392cd8" if ARGV.length == 0 print "Usage: icsToNotion.rb ics-file" exit else summary = nil start_date = nil end_date = nil previous = {} open(ARGV.first, "rt") do |f| while (line = f.gets) case line when /^BEGIN:VEVENT.*/ start_date = nil end_date = nil summary = nil when /^DTSTART.*(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})/ start_date = "#{$1}-#{$2}-#{$3}T#{$4}:#{$5}:00+0900" when /^DTEND.*(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})/ end_date = "#{$1}-#{$2}-#{$3}T#{$4}:#{$5}:00+0900" when /^SUMMARY:(.*)/ summary = $1 summary_sub = summary.split("[").first when /^END:VEVENT/ page = ds.build_child_page pp = page.properties pp["Date"].start_date = start_date pp["Date"].end_date = end_date pp["Assignee"].people = user_id pp["Task name"] << summary blocked_by_id = previous[summary_sub] pp["blocked by"].relation = blocked_by_id if blocked_by_id page.save previous[summary_sub] = page.id print "#{summary}\t#{start_date} #{end_date}\n" end end end end
ics の取得とスクリプト実行
本校の校務支援システムでは、自分の時間割のページから期間ごとの授業をイベントとしてカレンダーデータを取得することができます。カレンダー登録をクリックすると「プログラミングI_授業スケジュール.ics」のように授業名をファイル名に含んだ ics ファイルがダウンロードされます。

あとは先ほどのスクリプトを実行するだけです。6つのカレンダーデータから Notion のタスクを一括作成しました。上のスクリプトを見ればわかりますが、授業同士は依存関係で接続されています。
hkob@hM4proMini ~/Downloads> icsToNotion.rb プログラミングI_授業スケジュール.ics プログラミングI(24)[1] 2026-04-08T10:25:00+0900 2026-04-08T11:55:00+0900 プログラミングI(24)[2] 2026-04-15T10:25:00+0900 2026-04-15T11:55:00+0900 プログラミングI(24)[3] 2026-04-22T10:25:00+0900 2026-04-22T11:55:00+0900 プログラミングI(24)[4] 2026-04-29T10:25:00+0900 2026-04-29T11:55:00+0900 プログラミングI(24)[5] 2026-05-20T10:25:00+0900 2026-05-20T11:55:00+0900 プログラミングI(24)[6] 2026-05-27T10:25:00+0900 2026-05-27T11:55:00+0900 プログラミングI(24)[7] 2026-06-03T10:25:00+0900 2026-06-03T11:55:00+0900 プログラミングI(24)[8] 2026-06-10T10:25:00+0900 2026-06-10T11:55:00+0900 プログラミングI(24)[9] 2026-06-17T10:25:00+0900 2026-06-17T11:55:00+0900 プログラミングI(24)[10] 2026-06-24T10:25:00+0900 2026-06-24T11:55:00+0900 プログラミングI(24)[11] 2026-07-01T10:25:00+0900 2026-07-01T11:55:00+0900 プログラミングI(24)[12] 2026-07-08T10:25:00+0900 2026-07-08T11:55:00+0900 プログラミングI(24)[13] 2026-07-15T10:25:00+0900 2026-07-15T11:55:00+0900 プログラミングI(24)[14] 2026-07-22T10:25:00+0900 2026-07-22T11:55:00+0900 プログラミングI(24)[15] 2026-08-05T10:25:00+0900 2026-08-05T11:55:00+0900 hkob@hM4proMini ~/Downloads> icsToNotion.rb プログラミングII_授業スケジュール.ics プログラミングII(34)[1] 2026-04-10T08:40:00+0900 2026-04-10T10:10:00+0900 プログラミングII(34)[2] 2026-04-17T08:40:00+0900 2026-04-17T10:10:00+0900 プログラミングII(34)[3] 2026-04-24T08:40:00+0900 2026-04-24T10:10:00+0900 プログラミングII(34)[4] 2026-05-01T08:40:00+0900 2026-05-01T10:10:00+0900 プログラミングII(34)[5] 2026-05-08T08:40:00+0900 2026-05-08T10:10:00+0900 プログラミングII(34)[6] 2026-05-15T08:40:00+0900 2026-05-15T10:10:00+0900 プログラミングII(34)[7] 2026-05-29T08:40:00+0900 2026-05-29T10:10:00+0900 プログラミングII(34)[8] 2026-06-12T08:40:00+0900 2026-06-12T10:10:00+0900 プログラミングII(34)[9] 2026-06-19T08:40:00+0900 2026-06-19T10:10:00+0900 プログラミングII(34)[10] 2026-06-26T08:40:00+0900 2026-06-26T10:10:00+0900 プログラミングII(34)[11] 2026-07-03T08:40:00+0900 2026-07-03T10:10:00+0900 プログラミングII(34)[12] 2026-07-10T08:40:00+0900 2026-07-10T10:10:00+0900 プログラミングII(34)[13] 2026-07-17T08:40:00+0900 2026-07-17T10:10:00+0900 プログラミングII(34)[14] 2026-07-24T08:40:00+0900 2026-07-24T10:10:00+0900 プログラミングII(34)[15] 2026-08-07T08:40:00+0900 2026-08-07T10:10:00+0900 hkob@hM4proMini ~/Downloads> icsToNotion.rb マルチメディア処理_授業スケジュール.ics マルチメディア処理(専攻科)[1] 2026-04-08T08:40:00+0900 2026-04-08T10:10:00+0900 マルチメディア処理(専攻科)[2] 2026-04-15T08:40:00+0900 2026-04-15T10:10:00+0900 マルチメディア処理(専攻科)[3] 2026-04-22T08:40:00+0900 2026-04-22T10:10:00+0900 マルチメディア処理(専攻科)[4] 2026-04-29T08:40:00+0900 2026-04-29T10:10:00+0900 マルチメディア処理(専攻科)[5] 2026-05-20T08:40:00+0900 2026-05-20T10:10:00+0900 マルチメディア処理(専攻科)[6] 2026-05-27T08:40:00+0900 2026-05-27T10:10:00+0900 マルチメディア処理(専攻科)[7] 2026-06-03T08:40:00+0900 2026-06-03T10:10:00+0900 マルチメディア処理(専攻科)[8] 2026-06-10T08:40:00+0900 2026-06-10T10:10:00+0900 マルチメディア処理(専攻科)[9] 2026-06-17T08:40:00+0900 2026-06-17T10:10:00+0900 マルチメディア処理(専攻科)[10] 2026-06-24T08:40:00+0900 2026-06-24T10:10:00+0900 マルチメディア処理(専攻科)[11] 2026-07-01T08:40:00+0900 2026-07-01T10:10:00+0900 マルチメディア処理(専攻科)[12] 2026-07-08T08:40:00+0900 2026-07-08T10:10:00+0900 マルチメディア処理(専攻科)[13] 2026-07-15T08:40:00+0900 2026-07-15T10:10:00+0900 マルチメディア処理(専攻科)[14] 2026-07-22T08:40:00+0900 2026-07-22T10:10:00+0900 マルチメディア処理(専攻科)[15] 2026-07-29T08:40:00+0900 2026-07-29T10:10:00+0900 マルチメディア処理(専攻科)[16] 2026-08-05T08:40:00+0900 2026-08-05T10:10:00+0900 hkob@hM4proMini ~/Downloads> icsToNotion.rb 情報工学実験実習I_授業スケジュール.ics 情報工学実験実習I(24)[1] 2026-04-13T12:45:00+0900 2026-04-13T16:00:00+0900 情報工学実験実習I(24)[2] 2026-04-20T12:45:00+0900 2026-04-20T16:00:00+0900 情報工学実験実習I(24)[3] 2026-04-27T12:45:00+0900 2026-04-27T16:00:00+0900 情報工学実験実習I(24)[4] 2026-05-11T12:45:00+0900 2026-05-11T16:00:00+0900 情報工学実験実習I(24)[5] 2026-05-18T12:45:00+0900 2026-05-18T16:00:00+0900 情報工学実験実習I(24)[6] 2026-05-25T12:45:00+0900 2026-05-25T16:00:00+0900 情報工学実験実習I(24)[7] 2026-06-01T12:45:00+0900 2026-06-01T16:00:00+0900 情報工学実験実習I(24)[8] 2026-06-15T12:45:00+0900 2026-06-15T16:00:00+0900 情報工学実験実習I(24)[9] 2026-06-22T12:45:00+0900 2026-06-22T16:00:00+0900 情報工学実験実習I(24)[10] 2026-06-29T12:45:00+0900 2026-06-29T16:00:00+0900 情報工学実験実習I(24)[11] 2026-07-06T12:45:00+0900 2026-07-06T16:00:00+0900 情報工学実験実習I(24)[12] 2026-07-13T12:45:00+0900 2026-07-13T16:00:00+0900 情報工学実験実習I(24)[13] 2026-07-20T12:45:00+0900 2026-07-20T16:00:00+0900 情報工学実験実習I(24)[14] 2026-07-27T12:45:00+0900 2026-07-27T16:00:00+0900 情報工学実験実習I(24)[15] 2026-08-03T12:45:00+0900 2026-08-03T16:00:00+0900 hkob@hM4proMini ~/Downloads> icsToNotion.rb データベース_授業スケジュール.ics データベース(44)[1] 2026-04-13T08:40:00+0900 2026-04-13T10:10:00+0900 データベース(44)[2] 2026-04-20T08:40:00+0900 2026-04-20T10:10:00+0900 データベース(44)[3] 2026-04-27T08:40:00+0900 2026-04-27T10:10:00+0900 データベース(44)[4] 2026-05-11T08:40:00+0900 2026-05-11T10:10:00+0900 データベース(44)[5] 2026-05-18T08:40:00+0900 2026-05-18T10:10:00+0900 データベース(44)[6] 2026-05-25T08:40:00+0900 2026-05-25T10:10:00+0900 データベース(44)[7] 2026-06-01T08:40:00+0900 2026-06-01T10:10:00+0900 データベース(44)[8] 2026-06-15T08:40:00+0900 2026-06-15T10:10:00+0900 データベース(44)[9] 2026-06-22T08:40:00+0900 2026-06-22T10:10:00+0900 データベース(44)[10] 2026-06-29T08:40:00+0900 2026-06-29T10:10:00+0900 データベース(44)[11] 2026-07-06T08:40:00+0900 2026-07-06T10:10:00+0900 データベース(44)[12] 2026-07-13T08:40:00+0900 2026-07-13T10:10:00+0900 データベース(44)[13] 2026-07-20T08:40:00+0900 2026-07-20T10:10:00+0900 データベース(44)[14] 2026-07-27T08:40:00+0900 2026-07-27T10:10:00+0900 データベース(44)[15] 2026-08-03T08:40:00+0900 2026-08-03T10:10:00+0900 hkob@hM4proMini ~/Downloads> icsToNotion.rb 卒業研究_授業スケジュール.ics 卒業研究(54)[1] 2026-04-10T10:25:00+0900 2026-04-10T16:00:00+0900 卒業研究(54)[2] 2026-04-17T10:25:00+0900 2026-04-17T16:00:00+0900 卒業研究(54)[3] 2026-04-24T10:25:00+0900 2026-04-24T16:00:00+0900 卒業研究(54)[4] 2026-05-01T10:25:00+0900 2026-05-01T16:00:00+0900 卒業研究(54)[5] 2026-05-08T10:25:00+0900 2026-05-08T16:00:00+0900 卒業研究(54)[6] 2026-05-15T10:25:00+0900 2026-05-15T16:00:00+0900 卒業研究(54)[7] 2026-05-29T10:25:00+0900 2026-05-29T16:00:00+0900 卒業研究(54)[8] 2026-06-05T10:25:00+0900 2026-06-05T16:00:00+0900 卒業研究(54)[9] 2026-06-12T10:25:00+0900 2026-06-12T16:00:00+0900 卒業研究(54)[10] 2026-06-19T10:25:00+0900 2026-06-19T16:00:00+0900 卒業研究(54)[11] 2026-06-26T10:25:00+0900 2026-06-26T16:00:00+0900 卒業研究(54)[12] 2026-07-03T10:25:00+0900 2026-07-03T16:00:00+0900 卒業研究(54)[13] 2026-07-10T10:25:00+0900 2026-07-10T16:00:00+0900 卒業研究(54)[14] 2026-07-17T10:25:00+0900 2026-07-17T16:00:00+0900 卒業研究(54)[15] 2026-07-24T10:25:00+0900 2026-07-24T16:00:00+0900 卒業研究(54)[16] 2026-07-31T10:25:00+0900 2026-07-31T16:00:00+0900
カレンダーへの登録
授業前にカレンダーアプリから通知して欲しいので、Google Calendar にも登録します。macOS の場合には、ics ファイルをダブルクリックするとカレンダーアプリが取り込んでくれます。カレンダーアプリには Google Calendar が接続されているので、このまま Google Calendar の Notion というカレンダーに登録がされます。

さらに、Google Calendar の Notion カレンダーにイベントが登録されると、ワークフローにより Outlook のカレンダーにもイベントが自動的に生成されます。Outlook のカレンダーにイベントが入っていないと隙間を見つけて会議を入れられてしまうので、防御のために Outlook への登録は重要です(Outlook のカレンダー自体を自分で活用しているわけではないです)。

準備タスク作成(make_prepare_tasks.rb) のスクリプト修正
こちらも Database が DataSource に変わるのですが、スクリプト的には変更が必要ありませんでした。lecture_page.parent で取得されるものが Database から DataSource に変わっているからです。ただ、気持ちが悪いので変数名だけ db から ds に変更はしています。
#!/usr/bin/env ruby require "notion_ruby_mapping" include NotionRubyMapping user_id = "fffd872b594c811b82180002b0392cd8" NotionRubyMapping.configure { |c| c.token = ENV["AMBASSADOR_NOTION_API_KEY"] } if ARGV.length != 1 puts "Usage: make_prepare_tasks.rb <page_id>" exit end lecture_page = Page.find ARGV.first pre_lecture_page = nil ds = lecture_page.parent while lecture_page do title = lecture_page.title puts "Page: #{title}" ds.create_child_page do |_, pp| pp["Task name"] << "#{title}のレジュメ作成" pp["blocking"].add_relation lecture_page.id pp["Assignee"].people = user_id pp["blocked by"].add_relation pre_lecture_page.id if pre_lecture_page end pre_lecture_page = lecture_page lecture_page_id = lecture_page.properties["blocking"].relation.map { |r| r["id"] }.first lecture_page = lecture_page_id && Page.find(lecture_page_id) end
準備タスク作成スクリプト実行
あとはスクリプトを実行するだけです。一番先頭の授業タスクを指定すると依存関係から全ての授業のレジュメ作成タスクが生成されます。
hkob@hM4proMini ~/Downloads> make_prepare_tasks.rb "https://www.notion.so/hkob-private/1-3340ce2a6520819f9b3eed578eeb6073?v=1f70ce2a6520803898c6000cba4ffa66&source=copy_link" Page: マルチメディア処理(専攻科)[1] Page: マルチメディア処理(専攻科)[2] Page: マルチメディア処理(専攻科)[3] Page: マルチメディア処理(専攻科)[4] Page: マルチメディア処理(専攻科)[5] Page: マルチメディア処理(専攻科)[6] Page: マルチメディア処理(専攻科)[7] Page: マルチメディア処理(専攻科)[8] Page: マルチメディア処理(専攻科)[9] Page: マルチメディア処理(専攻科)[10] Page: マルチメディア処理(専攻科)[11] Page: マルチメディア処理(専攻科)[12] Page: マルチメディア処理(専攻科)[13] Page: マルチメディア処理(専攻科)[14] Page: マルチメディア処理(専攻科)[15] Page: マルチメディア処理(専攻科)[16] hkob@hM4proMini ~/Downloads> make_prepare_tasks.rb "https://www.notion.so/hkob-private/I-24-1-3340ce2a65208190a7bfe7e5facc7580?v=1f70ce2a6520803898c6000cba4ffa66&source=copy_link" Page: プログラミングI(24)[1] Page: プログラミングI(24)[2] Page: プログラミングI(24)[3] Page: プログラミングI(24)[4] Page: プログラミングI(24)[5] Page: プログラミングI(24)[6] Page: プログラミングI(24)[7] Page: プログラミングI(24)[8] Page: プログラミングI(24)[9] Page: プログラミングI(24)[10] Page: プログラミングI(24)[11] Page: プログラミングI(24)[12] Page: プログラミングI(24)[13] Page: プログラミングI(24)[14] Page: プログラミングI(24)[15] hkob@hM4proMini ~/Downloads> make_prepare_tasks.rb "https://www.notion.so/hkob-private/II-34-1-3340ce2a6520811296bdf69f4496621b?v=1f70ce2a6520803898c6000cba4ffa66&source=copy_link" Page: プログラミングII(34)[1] Page: プログラミングII(34)[2] Page: プログラミングII(34)[3] Page: プログラミングII(34)[4] Page: プログラミングII(34)[5] Page: プログラミングII(34)[6] Page: プログラミングII(34)[7] Page: プログラミングII(34)[8] Page: プログラミングII(34)[9] Page: プログラミングII(34)[10] Page: プログラミングII(34)[11] Page: プログラミングII(34)[12] Page: プログラミングII(34)[13] Page: プログラミングII(34)[14] Page: プログラミングII(34)[15] hkob@hM4proMini ~/Downloads> make_prepare_tasks.rb "https://www.notion.so/hkob-private/54-1-3340ce2a652081f3aebce3510a718fa7?v=1f70ce2a6520803898c6000cba4ffa66&source=copy_link" Page: 卒業研究(54)[1] Page: 卒業研究(54)[2] Page: 卒業研究(54)[3] Page: 卒業研究(54)[4] Page: 卒業研究(54)[5] Page: 卒業研究(54)[6] Page: 卒業研究(54)[7] Page: 卒業研究(54)[8] Page: 卒業研究(54)[9] Page: 卒業研究(54)[10] Page: 卒業研究(54)[11] Page: 卒業研究(54)[12] Page: 卒業研究(54)[13] Page: 卒業研究(54)[14] Page: 卒業研究(54)[15] Page: 卒業研究(54)[16] hkob@hM4proMini ~/Downloads> make_prepare_tasks.rb "https://www.notion.so/hkob-private/44-1-3340ce2a652081e1aaeaf5873d848caa?v=1f70ce2a6520803898c6000cba4ffa66&source=copy_link" Page: データベース(44)[1] Page: データベース(44)[2] Page: データベース(44)[3] Page: データベース(44)[4] Page: データベース(44)[5] Page: データベース(44)[6] Page: データベース(44)[7] Page: データベース(44)[8] Page: データベース(44)[9] Page: データベース(44)[10] Page: データベース(44)[11] Page: データベース(44)[12] Page: データベース(44)[13] Page: データベース(44)[14] Page: データベース(44)[15] hkob@hM4proMini ~/Downloads> make_prepare_tasks.rb "https://www.notion.so/hkob-private/I-24-1-3340ce2a6520817b977ed993428ac10d?v=1f70ce2a6520803898c6000cba4ffa66&source=copy_link" Page: 情報工学実験実習I(24)[1] Page: 情報工学実験実習I(24)[2] Page: 情報工学実験実習I(24)[3] Page: 情報工学実験実習I(24)[4] Page: 情報工学実験実習I(24)[5] Page: 情報工学実験実習I(24)[6] Page: 情報工学実験実習I(24)[7] Page: 情報工学実験実習I(24)[8] Page: 情報工学実験実習I(24)[9] Page: 情報工学実験実習I(24)[10] Page: 情報工学実験実習I(24)[11] Page: 情報工学実験実習I(24)[12] Page: 情報工学実験実習I(24)[13] Page: 情報工学実験実習I(24)[14] Page: 情報工学実験実習I(24)[15]
レジュメ作成タスクは前の授業に依存し、該当授業から依存されます。これによって、前の授業が終わるまでは表示がされないように工夫されています。blocked by のところを見るとうまく依存関係が設定されていることがわかります。レジュメ作成タスクは日付が設定されていない「いつかやる」タスクとなっています。

いつかやるタスク
この結果、「いつかやる」タスクには最初の授業のレジュメ作成タスクが並んでいます。Remain の欄には授業までの残り日数が出ています。もうあと 8 日で授業が始まってしまうのですね。

おわりに
来年度の情報システム工学コースの moodle も本日設置が完了したので、いよいよ来年度の授業準備ができるようになりました。今年度は 5.1 まで上げたために、これまでの ansible ではうまく動作せず少し時間がかかってしまいました。こちらに時間がかかってしまっていて、タスク登録が年度末ギリギリになってしまいました。ただ、以前作成したスクリプトのおかげで、正味 10分くらいで全ての作業が終わってしまうのは本当に助かります。