いまやあって当たり前、macOSにおいても空気のような存在となりつつある「通知」。しかし、基本的にはアプリがユーザに対し発するイベントの一種であり、カレンダーやタイマーのようなスケジュール/時刻管理ソフトの機能を使わないかぎり、ユーザレベルではコントロールできない。思いどおりの内容・タイミングで発信することは難しいのだ。

しかし、「スクリプト」を使えば話は変わってくる。自分でアプリケーションを開発するとなると、Objective-CやSwiftの文法から始まりAPIの知識を身につけ、Xcodeの操作方法も覚えなければならないが、スクリプトではそのハードルが大きく下がる。

そのとき、GUIを使うのだからApple Scriptか……と結論付けてしまうのは早計。Yosemiteからサポートされた「JXA(JavaScript for Automation)」を利用すれば、通知ダイアログの自作など朝飯前、驚くほどかんたんに「通知」をコントロールできてしまう時代なのだ。前置きが長くなったが、今回はその作りかたから応用術までを紹介しよう。

Yosemiteからサポートされた「JXA(JavaScript for Automation)」を利用すれば、かなりのことをJavaScriptで実現できる

JXAで通知を表示する

JXAは、macOSに標準装備の「スクリプトエディタ」で利用できる。AppleScriptとJavaScriptのどちらでコーディングするかは、エディタ画面の上部でも選択できるが、環境設定画面の「一般」タブで「デフォルトの言語」にJavaScriptを選択しておくと後々手間がかからない。

通知ダイアログの作りかただが、まずはリスト1をコピー&ペーストしてほしい。ダブルクォーテーションで囲まれた部分が通知ダイアログに表示される文字列で、上から順に本文、タイトル、サブタイトル、表示されるときの効果音となる。かな漢字などマルチバイト文字も利用できるので、各項25文字以内をめやすに入力してみよう。

動作確認は再生ボタンをクリックすればOK。これで通知ダイアログが表示され、通知センターにも通知が残されているはずだ。

スクリプトエディタで「デフォルトの言語」をJavaScriptに変更しておく

スクリプトを実行すると、自作の通知ダイアログが表示された

アプリケーションとして保存後にバンドル内部を確認すれば、AppleScriptと同じ「アプレット」とわかる

リスト1:JavaScriptで実装した通知ダイアログ

var Notice = Application.currentApplication() //現在のアプリケーションオブジェクトを取得

Notice.includeStandardAdditions = true //標準機能をJXAで使う

Notice.displayNotification("次の工程に進んでください。", {
    withTitle: "処理が終わりました",
    subtitle: "無事完了です。",
    soundName: "Sosumi" //システムサウンド
})

通知ダイアログのバリエーションを増やす

JXAで記述したスクリプトは、アプリケーションとして保存すれば独立して実行できる。バンドル内部の構造はApple Scriptで記述したときと同様で、Resourcesフォルダ以下に(コンパイル済の)JavaScriptファイルやアイコンなどが収録されている。保存時にファイルフォーマットとして「アプリケーション」を指定するだけなので、ほとんど手間はかからない。

通知の用途を拡げるには、この「アプリケーション」を利用する。一般的に、決められた処理が終われば動作を終えるのがスクリプトだが、保存するときに「ハンドラの実行後に終了しない」オプションを有効にしておくと、同じ処理を繰り返すアプリケーションに仕立てることができる。

このしくみに着目すると、一定時間ごとに通知を繰り返すアプリケーションを作成できる。「カレンダー」や「リマインダー」を利用すると、決められた日時に通知を行うことができるが、30分や2時間といった短い間隔で通知を繰り返す用途には適さない。JXAの場合、idle関数を利用すると、そのような処理がかんたんに実現できるのだ(参考)。

リスト2は、先ほど作成した通知ダイアログのソースを改変したもの。idle関数で定義した内容は、returnで返した秒数ぶん待機してからもう一度実行されるので、この場合60秒後に再び通知ダイアログを表示することになる。ここでは、SECONDS変数に定義した秒数(60)を利用しているので、1分ごとに通知が繰り返される。SECONDS変数の60を1800にすれば30分ごとに、3600にすれば1時間ごとに通知されるというわけだ。

保存するとき「ハンドラの実行後に終了しない」にチェックを入れておく

idle関数を利用すると、定間隔で通知するアプリケーションを作成できる

リスト2:1分ごとに通知を繰り返す

var Notice = Application.currentApplication()
var SECONDS = 60

Notice.includeStandardAdditions = true

    function idle(){
Notice.displayNotification("では、また1分後に。", {
    withTitle: "前回の通知から1分経過しました。",
    subtitle: "きっかり60秒です。",
    soundName: "Funk"  //システムサウンド
})
    return SECONDS
}

今回は紙幅の都合で取りあげることはできないが、自作の通知は各種のシステムイベントを知る用途にも使えそうだ。パッと思いつくところでは、定期的にクリップボードの内容を表示したり、ネットワークの状態を報告したり、特定のキーが押されると通知したり……AppleScriptでも可能なことだが、同じことをJavaScriptで実現することに意味があると思うのだが、どうだろう?

クリップボードの内容を通知するアプリケーションを作成してみたが、実用にはもう少し作り込む必要がありそう