前置き
Yahoo! デベロッパーネットワークのテキスト解析APIがV2になったという話題が前回のもくもく会で出ました。
これに伴いリクエストとレスポンスの内容が変わるため、このAPIを利用していたスクリプト等は改修を余儀なくされることになります。
今回はこのバージョンアップしたAPIをExtendScriptから利用する方法を紹介します。
ちなみにこの記事で紹介するものは基本Macでしか動きませんので予めご了承ください。
事前に必要なもの
Yahoo! APIのClient IDを取得しておいてください。本記事はClient IDを既に取得してある前提です*1。
APIにPOSTリクエストする
前掲のもくもく会開催報告記事にも書いたように、パラメーターを&
で区切ってURLに記述するだけのGETリクエストが使えなくなりました。適宜パラメーターを設定したPOSTリクエストを送る必要があります。
ExtendScriptからAPIにリクエストを送る方法として、今回はシェルのcurl
コマンドを叩く方法を採用しました。
ExtendScriptからは直接curl
コマンドは実行できないので、ExtendScript → doScript
でAppleScriptを実行 → do shell script
でcurl
コマンドを実行、という流れになります。
GETではなくPOSTでリクエストする
何もオプションを付けずにリクエストするとGETリクエストになりますが、明示的にリクエストメソッドを変更する場合は-X
オプションをつけます*2。
リクエストするURLは末尾に記します。
curl
コマンドにリクエストヘッダを指定する
POSTリクエストは-H
コマンドでリクエストヘッダを指定できます。今回のリクエストにはレスポンスの形式を指定するContent-Typeのみを指定します。
ほかにUser-Agentの指定も必要ですが、こちらは-A
オプションで指定します*3。
Content-Typeにはapplication/jsonを指定します。
また、User-Agentには既に取得したClient IDを指定しますが、Yahoo AppID: <アプリケーションID>
という形で指定する必要があります*4。
リクエストボディ
肝心のボディのパラメータは公式を参考にしてください。
上記にありますがこっちにも載せておきます。
パラメータ | 型 | 説明 |
---|---|---|
id |
string, integer | 値は任意で、指定した値がレスポンスのidにも返ります。今回は適当にしました |
jsonrpc |
string | 2.0(固定) |
method |
string | jlp.furiganaservice.furigana(固定) |
params |
object | 下記2つのパラメータをもたせたオブジェクトです |
q |
string | ふりがなを付ける対象のテキストです |
grade |
integer | 1〜8の整数で指定します(詳細は公式ヘルプ参照) |
これらをJSONの形(key: value)で-d
オプションをつけて指定します。params
は値がオブジェクトになるのでparams: { q: hoge, grade: 1}
みたいになります。
curl
コマンドで送る内容の整理
ここまでを整理すると、このようになります。
curl -H 'content-type: application/json' -A 'Yahoo AppID: <アプリケーションID>' -X POST -d '{"id": "1234", "jsonrpc": "2.0", "method": "jlp.furiganaservice.furigana", "params": {"q": "彗星が僕の頭上を翔んだ", "grade": "1"}}' https://jlp.yahooapis.jp/FuriganaService/V2/furigana
ご自分のClient IDを入れてターミナルを叩いてみてください。params
のq
に指定した文字列のルビ情報などが含まれたJSONが返ってくれば成功です。
AppleScriptからPOSTリクエストする
AppleScriptからシェルスクリプトを叩くにはdo shell script
を使います。先ほどのスクリプトをdo shell script
の引数に渡すのですが、文字列として渡すためdo shell script "curl ..."
という形になります。これはつまりダブルクオーテーションは全部エスケープする必要があるということです。
ということでスクリプトエディタでダブルクオーテーションをエスケープして、do shell script
を使ってみてください。
do shell script "curl -H 'content-type: application/json' -A 'Yahoo AppID: <アプリケーションID>' -X POST -d '{\"id\": \"1234\",\"jsonrpc\": \"2.0\",\"method\": \"jlp.furiganaservice.furigana\",\"params\": {\"q\": \"彗星が僕の頭上を翔んだ\",\"grade\": \"1\"}}' https://jlp.yahooapis.jp/FuriganaService/V2/furigana"
ここまでできたらあと一息です。
ExtendScriptからPOSTリクエストする
InDesignのApplication.doScript()
メソッドはAppleScriptを実行できる*5のでそれを利用します。ちょっとだけ使いやすく加工したのが以下のスクリプトです。
解説
テキストを囲むメソッドを自前で用意
テキストを引用符で囲むのが面倒臭すぎたのでプロトタイプ拡張しました(String.surroundQuotes()
メソッド)。引数に渡した文字列で元のテキストを囲むだけのものです。
"hoge".surroundQuotes("X"); //結果は XhogeX
みたいに使います。
リクエストパラメータを記述するオブジェクト
サンプルコードではp
オブジェクトとしてそこにリクエストしたいパラメータをまとめてJSONで記述しています。特にp.body
プロパティは、リクエストパラメータ: 値
という形式で記述します。後でそのままリクエストボディとしてテキスト化するのを楽にするためです。
AppleScriptを文字列として用意する
scpt
変数に"do shell script "
と記述し、続けてシェルスクリプトを記述しています。
コマンドやオプションを細かくスペースで区切るのが手間なので、一旦配列で必要な文字列だけ準備して、最後にArray.join(" ")
としてすべてスペースでつないで1行にします。
リクエストボディに記述するJSONのテキストを用意する関数
getParamString()
メソッドは、渡したオブジェクトのキーと値を\"key\": \"value\"
の形にするためのものです。それぞれを\"
で挟む処理が面倒くさすぎたため、冒頭のプロトタイプ拡張と合わせて導入しました。入れ子のオブジェクトは再帰的に処理するようにしています。
レスポンスを加工する
レスポンスはJSONなので、eval("(" + result + ")")
で無理やりパースします。公式のレスポンスフィールドの項の通り、JSON.result.word
プロパティにふりがなを含んだ単語の配列が得られます。
ちなみに、「彗星が僕の頭上を翔んだ」という文字列のレスポンスは以下のようになります。
{ "id": "1234", "jsonrpc": "2.0", "result": { "word": [{ "furigana": "すいせい", "roman": "suisei", "surface": "彗星" }, { "furigana": "が", "roman": "ga", "surface": "が" }, { "furigana": "ぼく", "roman": "boku", "surface": "僕" }, { "furigana": "の", "roman": "no", "surface": "の" }, { "furigana": "ずじょう", "roman": "zuzyou", "surface": "頭上" }, { "furigana": "を", "roman": "wo", "surface": "を" }, { "furigana": "かけん", "roman": "kaken", "subword": [{ "furigana": "かけ", "roman": "kake", "surface": "翔" }, { "furigana": "ん", "roman": "n", "surface": "ん" } ], "surface": "翔ん" }, { "furigana": "だ", "roman": "da", "surface": "だ" } ] } }
ご覧の通り「翔(と)んだ」みたいな変わった読み方には対応できませんが、結果がしっかりJSONで得られています。
これを利用してInDesignのルビを設定していくわけですね。記事が長くなったので、得られたJSONを基にしてルビをつける部分の解説は割愛しますが、InDesignでのルビの処理に必要なプロパティなどは過去に解説した記事があるのでそちらも参照ください。
以上、Yahoo! のテキスト解析APIにInDesignのExtendScriptからPOSTリクエストする方法でした。
*2:リクエストメソッドの変更にはこちらを参考にしました
curlコマンドでちょこっとHTTPリクエストを試すだけの記事 - Qiita
*3:curlコマンドのリクエストヘッダについてはこちらを参考にしました
curlコマンドでHTTPヘッダを扱うレシピ - Qiita
*4:下記URLの「アプリケーションIDについて」を参照
WebAPIの使い方(POSTリクエスト) - Yahoo!デベロッパーネットワーク
本記事はUser-Agent方式にしました
*5:Macの場合。Winの場合はVBSが実行できる代わりにAppleScriptは使えません