定期的に通知を出すAppleScript


この記事はDTP Advent Calendar 2018の3日目の記事です。

macOSにはMountain Lion以降、通知センター機能が搭載されています。この機能を利用して定期的に通知を出すAppleScriptの紹介です。
なお、動作確認は10.12で行なっています。

風邪の季節ですので今回は予防効果が期待される(?)水分補給をうながすメッセージを15分ごとに、また、60分ごとに休憩をうながすメッセージを通知します。
これで、作業に集中しすげて数時間も椅子に座りっぱなしだった!!なんてことが防げるようになるのでは?

コード

(*
    定期的に通知を出す
    2018-12-03
*)

property f : 1

on idle

    set aTime to 15 --分単位で指定

    my main()
    return aTime * minutes

end idle

on main()

    set aTitle to "カサカサ警報"
    set aMess1 to "水分補給の時間です"
    set aMess2 to "そろそろ休憩を取りませんか?"

    if f is not 4 then
        display notification aMess1 with title aTitle
        set f to f + 1
    else
        display notification aMess2 with title aTitle
        set f to 1
    end if

end main

使い方

上記コードをスクリプトエディタにペーストし、アプリケーション形式で任意の場所に保存します。

その際、下図のようにハンドラの実行後に終了しないのチェックを忘れないようにしましょう。
忘れると1度の実行で終了してしまいます。

ダブルクリックで起動します。起動直度に1度目のメッセージがでます。その後、15分置きに通知が出ますので、終了させる場合はアプリケーションを最前面にし、終了させてください。

解説

というほどのことはしていないのですが……

on idleを使うことで定期的に処理を実行させることができます。
returnの後ろの数値で実行間隔を秒単位で指定します。今回は分単位で実行するのでminutes定数を掛けています。

それぞれの変数は下記の通り指定します。

display notification "通知したい本文" with title "タイトル" subtitle "サブタイトル" sound name "Glass"

サウンドは/System/Library/Soundsにある音源を指定します。

おまけ

通知センターのメッセージはSystem Eventsで取得できます。
通知メッセージごとに別の処理を走らせるなんて使い方ができるのではないでしょうか?

display notification "メインタイトルが取れない!" subtitle "サブタイトル"
delay 1

tell application "System Events"
    tell process "通知センター"

        set notificationWindow to window 1 whose subrole is "AXNotificationCenterAlert" or subrole is "AXNotificationCenterBanner"

        tell notificationWindow's scroll area 1
            set aSub to static text 1's the value
            set aMessage to static text 2's the value
        end tell

        tell application "Finder" to display dialog aSub & return & aMessage buttons {"OK"} default button "OK"

    end tell
end tell

と、思ったのですが以前できたようには取得できない……
参考のサンプルは動作するので確認できるのですが、これをon idleでリピート処理しようとすると取得できないようで、あれこれ試しているうちに時間切れ。
返り値も変わった気がするし当時とはOSのバージョンが違うからなのかな〜

リンク

最後に公式ドキュメント(2018-12-12現在)のリンクを紹介して結びにしたいと思います。