(後日追加) ここで説明している Notion workflow はこちらで配布しています。 github.com
1. はじめに
一つ前の記事でカレンダーと Notion タスクを同期する記事を書きました。 hkob.hatenablog.com
ただ、Alfred から「ac」コマンドでカレンダー登録した時に、Notion タスクが二重化してしまう問題がまれに発生してしまいました。また、「ac」コマンドでは「an」コマンドと異なり、プロジェクトをつけることができません。そこで、「anc」という Notion タスクとカレンダーを同時に設定するコマンドを追加しました。この時、カレンダーの description に id を設定することで、カレンダーと Notion タスクが同期できるようになります。内容は前回の記事とあまり変わらないので、変更点だけ説明しようと思います。すでに Workflow のバージョンは 1.3 にあげているので、すでにインストール済の方のものは自動的にバージョンアップしていると思います。
2. workflow の外観
今回作成する anc は an の処理後にカレンダーも登録する形にしています。内容がほぼ一緒なので、Run Script などはすべて共通化し、Arg and Vars で処理を切り分けることにしました。
途中の 4 つの Arg and Vars は以下のようなパラメータ設定になっています。
属性 | an の上 | an の下 | anc の上 | anc の下 |
---|---|---|---|---|
calendar | false | false | true | true |
input | {query} | {query} | {query} | {query} |
reload | true | なし | なし | true |
また、この Arg and Vars で query を input 変数に入れているので、ac からの query も input に入れるように変更しました。
属性 | ac |
---|---|
calendar | true |
input | {query} |
3. Run Script の修正
3.1 Add Notion 側
もともと an は終了時間を設定していなかったのですが、カレンダーと同じ処理になるように終了時間も設定できるように変更しました。また、最後に id を次の処理に渡すようにしました。
require './notion.rb' project_id = ARGV[0] date = nil end_time = nil start_time = nil words = ENV["input"].split " " end_time = (words.pop + MY_TZ) if words[-1] =~ /\d+:\d+/ if end_time start_time = (words.pop + MY_TZ) if words[-1] =~ /\d+:\d+/ unless start_time start_time = end_time end_time = nil end end begin date = Date.parse words[-1] # If the above Date.parse was success, the last parameter will remove. words.pop rescue end date ||= Date.today datetime = {start: [date, start_time].compact.join(" ")} datetime[:end] = [date, end_time].join(" ") if end_time summary = words.join " " result = create_task(summary, datetime, project_id) print result["id"]
3.2 Add Calendar 側
「an」コマンドの場合にはcalendar
が false になっているので、カレンダーは登録しないようにしています。true の場合にはこれまで通り、カレンダー登録をおこないます。ただし、キーワードの入力を input からに変更しています。また、「anc」から実行している場合には、前の処理で「id」を受け渡されているので、この id をカレンダーの description に記録します。これにより前の記事の Notion タスクとの同期を実現しています。
ObjC.import("stdlib"); function run(argv) { if ($.getenv("calendar") == "true") { createCalendar(argv) } } function createCalendar(task_id) { let query = $.getenv("input") let Calendar = Application("Calendar") let cal = $.getenv("NOTION_CALENDAR") console.log(cal) let notionCal = Calendar.calendars["Notion"] var endTimeStr = null var startTimeStr = null // query を分割 let words = query.split(" ") // 最後のパラメータが時間かどうか var timeStr = words.slice(-1)[0] if (timeStr && timeStr.match("[0-9]+:[0-9]+")) { endTimeStr = words.pop() } // 時間が設定されていたら開始時間もあるかどうか調べる if (endTimeStr) { timeStr = words.slice(-1)[0] if (timeStr && timeStr.match("[0-9]+:[0-9]+")) { startTimeStr = words.pop() } else { startTimeStr = endTimeStr endTimeStr = null } } var dateStr = words.slice(-1)[0] // 日付が設定されていなければ今日にする if (dateStr.match("^[0-9]+/[0-9]+$")) { dateStr = new Date().getFullYear() + "/" + words.pop() } else if (dateStr.match("^[0-9]+/[0-9]+/[0-9]+/$")) { dateStr = words.pop() } else { let timeNow = new Date() dateStr = timeNow.getFullYear() + "/" + (timeNow.getMonth() + 1) + "/" + timeNow.getDate() } // 日付・時間を除いた文字列から summary を作成 event = {summary: words.join(" ")} if (task_id != "") { event["description"] = "id:" + task_id } if (startTimeStr) { // 開始時間が設定されていたら時間を含めた日付を設定 let startTime = new Date(dateStr + " " + startTimeStr) var endTime if (endTimeStr) { // 終了時間が設定されていたら時間を含めた日付を設定 endTime = new Date(dateStr + " " + endTimeStr) } else { // 終了時間が設定されていなかったら開始時間の1時間後を設定 endTime = new Date(dateStr + " " + startTimeStr) endTime.setHours(endTime.getHours()+1) } event["startDate"] = startTime event["endDate"] = endTime let newEvent = Calendar.Event(event) notionCal.events.push(newEvent) } else { let date = new Date(dateStr) event["startDate"] = date event["endDate"] = date event["alldayEvent"] = true let newEvent = Calendar.Event(event) notionCal.events.push(newEvent) } }
終わりに
anc コマンドではすでに Notion タスクが作成済みなため、GAS 側でカレンダートリガーがかかっても、Notion タスクが重複することはなくなりました。内容の更新処理は動きますが、同じ内容なので見た目は何も変わりません。これで、カレンダー作成時に Notion タスクが重複する問題を解決することができました。また、an コマンドと同じでプロジェクトも自動的に設定できて一石二鳥になりました。