クロスプラットフォームで動作するデスクトップ通知コマンド「@neos21/simple-notify」を作った
デスクトップ通知を CLI から行える npm パッケージ、なんて何百番煎じだよ、とは思うが、OS 判定に関するコードを作って残しておきたかったので、ちょっと作ってみた。
npm でグローバルインストールすると、$ simple-notify 'メッセージ' という感じでコマンド実行できる。
- Windows 環境では PowerShell を使って
ToastNotificationを実行 - MacOS 環境では AppleScript を使って
display notificationを実行- 過去記事 : Mac のデスクトップ通知をシェルスクリプトから送る
- Linux 環境では
notify-sendコマンドを実行- Ubuntu なんかだと最初からインストールされている
という感じで、内部では OS を判別して実行するコマンドを別けている。
PowerShell でトースト通知を送るコマンドを組み立てるのが大変だった。過去記事で BurntToast というモジュールを紹介したが、コレが内部で使っているような Windows API を使っている。
タイトルやアイコンなどを XML 形式で書いて実行したりとか、色んな呼び出し方があるのだが、ワンライナーで呼び出せているコードがどこにもなく、今回自分で頑張って組み立てた。
- 参考 : ASCII.jp : Windows PowerShellからスクリプトの完了をトースト通知で知らせる (1/2)
- 参考 : Generating Windows 10 Notifications With PowerShell | Den
- 参考 : ◇Windowsのバッチファイルでトーストを使って通知する - Qiita
- 参考 : Win向け通知アプリにトーストを使う - Qiita
OS 判定について、特に WSL 環境の見極めをできるようにしておきたいなと思ったのだが、os.release() を見れば microsoft の文字が出てくるので WSL かどうか区別が付く、というやり方が多いようだった。Bash だと $ uname -a に microsoft の文字列が登場するので見極められる。Sindre Sorhus 氏が is-wsl というパッケージを作っていて、まぁ大体同じだった。
npm (Node.js) の良いところは、コンパイルが要らない点だと思っていて、Windows のコマンドプロンプトでも PowerShell でも GitBash でも、MacOS でも Linux でも、Node.js が直接 JS コードを動かしてくれるので、リリース時にクロスコンパイルとかのことを考えずにコマンドが提供できるのが便利だと思っている。
最近は Go や Rust が人気で、Zig はクロスコンパイルが得意だとか言われているけど、それでもクロスプラットフォーム対応はまだ引っかかりやすいところがあり、「Windows でも Mac でも同じ JS ファイルがそのまま実行可能ファイルとしてコマンド化できる」というのは Node.js の強みだと思う。シェルスクリプト (.sh や .bash) もコマンドプロンプトや PowerShell では実行できないから、コマプロや PowerShell からの呼び出しでも動く方法としては Node.js でラッパースクリプトを書いてやるのが一番手っ取り早いだろう。
今回はデスクトップ通知をクロスプラットフォームで実現してみたが、他にも
- Windows における
startコマンド - MacOS における
openコマンド - Linux における
xdg-openコマンド
のそれぞれをラップするパッケージなんかを作ったら面白いかなーと思っている。wsl-open という WSL 向けのコマンドは既にあるが、コレの中身はシェルスクリプトだし (npm パッケージとして公開されているが JS ファイルは一切ない)、WSL から xdg-open や start コマンドを実行してもよしなにやってくれるので、簡単に動けば良いなら今回と似たようなコードで実現できそうだ。
- 参考 : cmdutils/google.cpp at master · rayalankenyon/cmdutils
- C++ ではあるが、OS 判定して上述のコマンドを使い分け、Google 検索をコマンドラインで実現するコードサンプルがあった
というワケで、クロスプラットフォーム対応コマンドを作るには Node.js スクリプトでラップするのが良いんじゃね?というお話でした。