Apple Scriptできることがたくさんあります。ただドキュメントが難解です。スクリプトエディタには用語説明もありますが、ドキュメントの内容と実際の挙動が異なるというかドキュメントだけ更新されて実際は古いままってこともあるようです。
例えば以下のようなMessageアプリを使ったメッセージの送信がApple Scriptで実現できます。
*メッセージ.applescript*
tell application "Messages"
set targetService to id of first service whose service type = iMessage
set theBuddy to buddy "相手" of service id targetService
send "メッセージ" to theBuddy
end tell
id of first service whose service type = iMessageは用語説明から導き出すことができませんでした。複数のApple IDを持つ場合の対処方法の書式であることがわかったんですが、用語説明からは導き出すのは困難でした。
まずはググって実際にやりたいApple Scriptソースコードを見つけ出し、動作実例の見本とする
多分これが一番簡単で、確実な方法だとチャッピーも言っていました(チャッピーの話だから微妙な面もあります)。
先人達の方々が動くように色々調べて積み上がった結果です。Appleの公式ドキュメント等では公開されていないので、Appleの仕様変更で動かなくなるリスクはあります。
曖昧な構文は避ける
tell application "Messages"
send "テスト通知" to buddy "送信先アドレス" of service "iMessage"
end tell
これは実際にエラーとなる構文ですが、チャッピーから提案された構文です。実際スクリプトエディタにコピペし、送信先を書き換え実行で「キーフォームが正しくない」とエラーになります。
よくみるとコピペ後の実行でスクリプトエディタ上で自動的に書き換えが起こっています。
tell application "Messages"
send "テスト通知" to participant "送信先アドレス" of account "iMessage"
end tell
スクリプトエディタは何か曖昧と判断したものに対して自動的に補完してくれる機能が実装されています。この場合、buddy “送信先メールアドレス”が内部的にbuddyして紐づけられない。”iMessage”がservice id or Objectとして認識できないと判断され、近い構文に自動修正してくれたと思われます。
ただ、動く「メッセージ.applescript」のような構文には修正してくれません。自動修正してくれた構文を進めても、目的は達成できません。
自動的に補完されたら正しい構文をググるのがベターだと思います。
participant、accountが「キーフォームが正しくない」エラーになる理由は?
チャッピー曰く、Tahoeでは用語説明のparticipant、accountがあるが、未実装であるとのことでした。うーん本当かな?
対象を調査する
公式ドキュメントに記載されていない事が多く、またググってもピンポイントで見つけることが難しいことがあります。そんな場合は何が取れるかを探索します。
何がある?トップレベルの情報を探る
tell application "Keynote"
get every class
end tell
上記例では、結果「application」と表示されます。classを持たないパターンもあり、失敗することもあります。以下の書式は、そんな場合でも有効な方法です。
tell application "Keynote"
get properties of application "Keynote"
end tell
{frozen:true, class:application, playing:false, version:”14.4″, slide switcher visible:false, name:”Keynote”, frontmost:false}
get every 〇〇シリーズには以下のようなものもあります。対応していないアプリケーションもあります。
- get every item
- get every window
- get every document
- get every page
- get every chat
- get every track
- get every playlist
何ができる?各オブジェクトの属性(Properties)を確認
親要素から子要素を深堀していきます。この際 get properties of xxx構文を利用します。
例えばKeynoteはwindow → document → slide → [shape / text item / …]のような構造になっています。
tell applicaiton "Keynote"
get properties of window 1 -- ウィンドウ1の属性を確認
get properties of document of window 1 -- ドキュメントの属性を確認
get properties of slide of document of window 1 -- スライドの属性を確認
といった感じで深堀していくことができます。
見つけたシェープに対して文字列を変更したり、色を変えたりするようなことができます。
window 1のようにIDではなく番号でアクセスできるパターンは順序付きコレクションです。window / document / slide / shape / tab / item / paragraph / word / characterなどが該当します。
IDを直接指定するパターンは構文を理解する必要があります。用語説明を頼ります。
get every windowで得たIDを利用する場合get properties of window id 9999のようにします。
内部要素は?everyで探ります。
tell applicaiton "Keynote"
-- スライド1枚目の図形一覧
get every shape of slide 1 of document of window 1
-- スライド1枚目の線一覧
get every line of slide 1 of document of window 1
-- スライド1枚目のテーブル一覧
get every table of slide 1 of document of window 1
-- スライド1枚目の線一覧
get every image of slide 1 of document of window 1
-- スライド1枚目のイメージ一覧
get every text item of slide 1 of document of window 1 -- スライド1枚目の一覧
このようにslideの中に、どんな要素があるのか、知らないと追えません。これを知るには?(1)スクリプトエディタの用語説明(2)sdefコマンドです。
普段からターミナルを利用しているので、sdefコマンドは個人的には素早くアクセスでき、XML形式ですが、わかりやすいと感じました。
- システム標準のアプリは/System/Applications/下に存在します。
まとめ:対象をよく探求し、できることを知ることが近道でした。
get properitesや get everyで探求し、さらに用語説明、sdefコマンドで対象アプリの制御可能な項目を知っていくことで動かすことができました。
