たとえばSlackの Incoming Webhook でメッセージを送るときに、メッセージ部分だけを置き換えてJSONを組み立てたいことがあります。 プログラミング言語が使えるなら簡単なんですが、ちょっと大げさな気もするので jq だけでJSONを組み立てられるとべんりそうです。
{"text":"hi"}
このようなJSONを組み立てて送信したいとして、"hi"
の部分を変数にしてみます。
{"text":$text}
この $text
の部分を任意の文字列に置き換えるには --arg オプションを使います。(-n / -c)
$ jq -n -c --arg text hi '{"text":$text}' {"text":"hi"}
今回のケースでは不要ですが文字列以外の値に置き換えるには --argjson オプションを使うことが出来ます。
$ jq -n -c --argjson text 12345 '{"text":$text}' {"text":12345}
目的はこのJSONをSlackに投げることだったので生成結果を curl に食わせます。 -d @- で標準入力をbodyとして送信できるのではこれを利用します。
ちなみに Object Construction が使えるので { text: $text }
のような書き方が出来ることも覚えておくとよさそうです。
$ jq -n -c --arg text hi '{ text: $text }' | curl -H 'Content-Type: application/json' -d @- <Incoming Webhook URL>
これで目的は達することが出来ました。
Slackに投稿するときは、恐らくもうちょと 複雑なメッセージを組み立てる 必要があると思います。 そういった場合にはテンプレートとしてファイルを用意しておきそれを読み込むことも出来ます。
以下のような内容で template.js
というファイルを用意します。.js
拡張子なのは object っぽい書き方なのでシンタックスハイライトが効くから。。。
{ blocks: [ { type: "header", text: { type: "plain_text", text: "CI" }, }, { type: "section", fields: [ { type: "mrkdwn", text: "*Result:*\n\($result)" }, { type: "mrkdwn", text: "*SHA1:*\n\($sha1)" } ] } ] }
ファイルを受け取るには -f オプションが使えるので以下のようにして生成します。
jq -c -n --arg result Success --arg sha1 eeeaaa -f template.js | curl -S -H 'Content-Type: application/json' -d @- <Incoming Webhook URL>
ちなみに gojq でももちろん同じことが出来て圧倒的に速いので、大きなJSONを生成するときはおすすめです。
$ time gojq -c -n --arg result Success --arg sha1 eeeaaa -f template.js > /dev/null ________________________________________________________ Executed in 7.56 millis fish external usr time 2.54 millis 0.09 millis 2.45 millis sys time 3.83 millis 1.12 millis 2.71 millis
$ time jq -c -n --arg result Success --arg sha1 eeeaaa -f template.js > /dev/null ________________________________________________________ Executed in 31.71 millis fish external usr time 40.19 millis 0.12 millis 40.07 millis sys time 10.60 millis 1.06 millis 9.53 millis