ちなみに

火曜日の空は僕を押しつぶした。

jqで簡易テンプレート

たとえば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>

f:id:Sixeight:20210925170351p:plain

ちなみに 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