macOS から iPhone で通知を受け取りたい
macOS で、重い処理を実行するも下手に他の作業を並行して進めると、スワップ地獄で共倒れになるケースが最近増えてきました。
そこで処理を実行している間は席を離れ、処理が終わったら通知を受け取り、席へ戻るタイミングを知る事ができるようにしたと思いました。
具体的には、以下のように処理が exit 0 で終了したら iPhone に通知が届くようにしたいのです。
$ [重い実行作業のコマンド] && notify-me "⚪︎⚪︎⚪︎の作業が完了しました!"
しかも、Line、Telegram や Discord といった 3rd パーティーの API を叩かずに macOS の標準機能で通知を受け取りたいのです。
TL; DR (今北産業)
-
osascriptを使って「リマインダー」アプリを叩き、現在時刻のリマインドを作成する - 同じ Apple ID でログインし、iCloud 同期でリマインダーが同期していること
- macOS 側の実行許可確認と、iPhone 側のリマインダー通知設定を忘れない
osascript -e 'tell application "Reminders" to make new reminder with properties {name:"⚪︎⚪︎⚪︎の作業が完了しました!", due date:(current date)}'
TS; DR (kwsk)
-
以下のスクリプトを、パスの通ったディレクトリにコマンド名(例:
notify-me)で設置し、chmod +x notify-meで実行権限を与えます(AI エージェントに使わせる場合はnotify-userがいいかも)#!/usr/bin/env zsh # ヘルプ表示 usage() { cat <<'EOF' Usage: notify-me MESSAGE notify-me -h | --help macOS のリマインダーを介してユーザーに即時通知します。 iPhone への通知には、リマインダーの同期と通知設定が必要です。 Options: -h, --help このヘルプを表示します Examples: notify-me "計算が完了しました!" notify-me '引用符 "付き" のメッセージ' notify-me $'1行目\n2行目' python train.py && notify2user "モデル学習終了" EOF } # 引数なし、ヘルプ指定 if (( $# == 0 )) || [[ "$1" == "-h" || "$1" == "--help" ]]; then usage exit 0 fi # 引数なし if (( $# != 1 )); then print -ru2 -- 'エラー: 通知文を引用符で囲み、1つの引数として指定してください。' exit 2 fi # 通知文なし if [[ -z "$1" ]]; then print -ru2 -- 'エラー: 通知文が空です。' exit 2 fi # osascript に AppleScript で第一引数を通知文として渡す。 exec /usr/bin/osascript - "$1" <<'APPLESCRIPT' on run argv set notificationMessage to item 1 of argv tell application "Reminders" make new reminder with properties ¬ {name:notificationMessage, due date:(current date)} end tell end run APPLESCRIPT -
./notify-me "テスト送信"を実行すると、初回実行時に許可を求めるポップアップが出るので、許可します-
確認画面が出ない場合:「システム設定」>「プライバシーとセキュリティ」>「リマインダー」で、通知を依頼したアプリ(「ターミナル」や「iTerm2」など)が「オフ」になっていないか確認
- Codex などのコーディング・エージェントに実行させる場合は、そのコーディング・エージェントのアプリ
-
追加されていない場合: アプリ自体(ここでは「ターミナル」)がセキュリティでブロックされている(許可されていない)ので以下を確認し追加する
- 「システム設定」>「プライバシーとセキュリティ」>「オートメーション」
- 「システム設定」>「プライバシーとセキュリティ」>「フルディスクアクセス」
「フルディスクアクセス」に追加されたアプリ(およびそのアプリ内で実行されるコマンドやスクリプト)は、個人データ領域やシステム・アプリケーション領域などの通常保護されているデータへ制限なくアクセスできるようになるので注意。
-
確認画面が出ない場合:「システム設定」>「プライバシーとセキュリティ」>「リマインダー」で、通知を依頼したアプリ(「ターミナル」や「iTerm2」など)が「オフ」になっていないか確認
-
無事リマインダーに追加されると ID が発行され iPhone のリマインダーと同期が始まります
実行例% notify-me "テスト送信" reminder id x-apple-reminder://BC8DE75D-42E1-4F0E-A484-509B26CA55FA -
iPhone 側のリマインダー通知が反応します
- 反応しない場合、リマインダーを確認します。リマインドが追加されているのに通知しない場合は、iPhone の「設定」>「アプリ」>「リマインダー」で設定内容を確認し、iCould 同期に「リマインダー」が含まれているかなどを確認します。
osascript とは
osascript とは、macOS に標準搭載されているコマンドライン・ツールで、ターミナル(などのシェル)から実行できます。
osascript の osa は、Open Scripting Architecture の略で、「Apple イベント」をスクリプト言語を使ってアプリを操作するための仕様です。osa の仕様に準拠したスクリプト言語は osascript を介して実行でき、主な対応言語は、AppleScript と JavaScript ベースの JXA です。
AppleScript は、その名の通り Apple 社が開発した macOS 上でアプリケーションやシステムを自動操作するためのスクリプト言語で、JXA(JavaScript for Automation)は、その JavaScript 構文版とも言えるものです。
AppleScript は JavaScript と比較して、より英文の構文で記述できるようになっています。そのため、既存のスクリプトを読む時は理解しやすいのですが、自由言語ではないため構文を把握していないと戸惑う事があります。
詳しい構文は割愛しますが、「ブロックで考える」とスクリプトを組みやすいです。
osascript -e 'tell application "Reminders" to make new reminder with properties {name:"⚪︎⚪︎⚪︎の作業が完了しました!", due date:(current date)}'
上記の -e の(ステートメントと呼ばれる)中身をブロック毎に分けたものが以下です。
tell
application "Reminders"
to
make new reminder
with
properties {name:"⚪︎⚪︎⚪︎の作業が完了しました!", due date:(current date)}
「リマインダー」アプリは、内部的には(アプリケーション・フォルダー内では) "Reminders" です。
そして、このアプリが受け取る「作成」("make")の API には「新規通知」("new reminder")があり、通知に「添える情報」("properties")も渡す事ができるので、通知内容("name:")および「通知時間」("due date:")を指定できるという塩梅です。
例えば、"Finder" アプリに以下のように通知依頼すると、(許可後)"Finder" アプリがピコピコ反応して通知ダイアログが表示されます。
osascript -e 'tell Application "Finder" to display dialog "処理が完了しました"'
tell
application "Finder"
to
display
dialog "処理が完了しました"
ぶっちゃけ、macOS でしか使えないため Bash や Zsh や Python などのスクリプトと比べ汎用性は低いです。
しかし、macOS 内で完結する自動化スクリプトを組みたい場合には、逆に強力な武器となります。特に、「ショートカット」アプリ(旧 Automator)で任意のショートカットを作成し、osascript と併用するなどです。