How to Generate JSON with jq and Send Slack Messages via Webhook.

ara-ta3ara-ta3
3 min read

When parsing JSON to extract information, I’ve often used the jq command. This time, I realized it can also be used to generate JSON, so I decided to write this as a quick memo.

While I was casually writing a script that processes a string retrieved via curl and sends a notification to Slack, I found that using jq -n (or --null-input) and --arg was convenient for generating JSON and directly sending it to Slack’s Incoming Webhook.

Here’s the version of jq I used at the time:

jq --version
jq-1.7.1

Generate JSON with jq --null-input and --arg

The -n (or --null-input) option in jq is handy when generating JSON from scratch without requiring any input data.
Using the --arg option, you can name variables and insert them into JSON fields like this:

jq -n --arg name "Foo" --arg age "30" '{name: $name, age: $age}'
{
  "name": "Foo",
  "age": "30"
}

--argjson

--argjson is similar to --arg, but it allows the value to be treated as JSON:

jq -n --argjson data '{"foo": "bar"}' '{user: $data}'
{
  "user": {
    "foo": "bar"
  }
}

Of course, you can also insert JSON generated by another jq command:

jq -n --argjson data "$(jq -n --arg name Foo --arg age 30 '{name: $name, age: $age}' )" '{user: $data}'
{
  "user": {
    "name": "Foo",
    "age": "30"
  }
}

--args

The --args option allows you to pass multiple values and access them using $ARGS.positional as an array:

jq -n --args '$ARGS.positional' hoge fuga piyo
[
  "hoge",
  "fuga",
  "piyo"
]

It seems that when you use --args, the values are passed under the positional key in $ARGS.
Also, values passed via --arg go under the named key:

jq -n --args '$ARGS' hoge fuga piyo
{
  "positional": [
    "hoge",
    "fuga",
    "piyo"
  ],
  "named": {}
}

jq -n --args '$ARGS' hoge fuga piyo --arg hoge fuga
{
  "positional": [
    "hoge",
    "fuga",
    "piyo"
  ],
  "named": {
    "hoge": "fuga"
  }
}

--jsonargs

Just like how --argjson relates to --arg, use --jsonargs if you want the values passed to --args to be treated as JSON:

jq -n --jsonargs '$ARGS.positional' '{"name": "foo"}' '{"name": "bar"}'
[
  {
    "name": "foo"
  },
  {
    "name": "bar"
  }
]

Send the Generated JSON to a Webhook in One-liner

Use curl to send the generated JSON to Slack’s Incoming Webhook like this:

jq -n --arg text "Foo" '{text: $text}' | curl -X POST -H 'Content-type: application/json' --data @- https://hooks.slack.com/services/your/webhook/url

Use @- to Pass stdin as --data to curl

Using @- as the argument for --data allows you to pass standard input.
This is something I learned through this process—it’s also usable in other places.

https://curl.se/docs/manpage.html

If you start the data with the letter @, the rest should be a filename to read the data from, or - if you want curl to read the data from stdin.

Conclusion

This was about using jq --null-input and --arg to generate JSON and send it to Slack.
I found it really convenient for sending simple notifications and plan to use it more in the future.

References

Note: This article is an English translation of the original Japanese post published on Zenn: https://zenn.dev/ara_ta3/articles/send-incoming-webhook-with-jq

1
Subscribe to my newsletter

Read articles from ara-ta3 directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ara-ta3
ara-ta3