diff --git a/README.md b/README.md index 92b63f0..6616347 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,8 @@ - [bats][bats] (tests) - [curl][curl] (http requests) - [jq][jq] (JSON parsing) +- [base64][base64] (webhook avatar modification) +- [file][file] (MIME type retrieval for webhook avatar modification) ## Usage @@ -132,6 +134,24 @@ $ ./discord.sh \ ![](https://i.imgur.com/lni4fI3.png) +### • `--modify` +> You can permanently change the username and avatar of the webhook. +> The following options are valid: `--username` and `--modify` + +> **Warning:** +> No other options may be passed, including those for sending messages. + +#### Example +```bash +$ ./discord.sh \ + --modify \ + --username "NotifBot" \ + --avatar "https://i.imgur.com/12jyR5Q.png" +``` + +Once executed, all other webhook messages by default will contain the username and avatar set. + +![](https://i.imgur.com/ZYUBiil.png) ## Advanced Options Now we're going to look at how to setup a custom embed message. @@ -300,6 +320,8 @@ Made with 💖 by [ChaoticWeg][weg] & [fieu][fieu] || Documentation and design b [cut]: https://linux.die.net/man/1/cut [coreutils]: https://www.gnu.org/software/coreutils/coreutils.html [util-linux]: https://en.wikipedia.org/wiki/Util-linux +[base64]: https://wiki.openssl.org/index.php/Command_Line_Utilities#Base64_Encoding_Strings +[file]: https://github.com/file/file [webhook]: https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks diff --git a/discord.sh b/discord.sh index e556ed6..22cbe99 100755 --- a/discord.sh +++ b/discord.sh @@ -59,6 +59,7 @@ File options: Identity options: --username Set username to --avatar Set avatar to image located at + --modify Modify webhook (pass with avatar/username permanantly update webhook) Embedded content options: Main: @@ -136,6 +137,8 @@ while (( "$#" )); do --webhook-url=*) webhook_url=${1/--webhook-url=/''}; shift;; --webhook-url*) webhook_url=${2}; shift; shift;; + --modify*) modify=1; shift;; + --username=*) username=${1/--username=/''}; shift;; --username*) username=${2}; shift; shift;; @@ -331,6 +334,28 @@ build_embed() { echo ", \"embeds\": [{ \"_\": \"_\"${_title}${_desc}${_eurl}${_color}${_ts}${_author}${_thumb}${_image}${_fields}${_footer} }]" } +convert_image_link_to_base64() { + local _image + local _image_type + local _image_base64 + + # save image to temp file + _image="$(mktemp)" + curl -s "${1}" > "${_image}" + + # get image type + _image_type="$(file -b --mime-type "${_image}")" + + # convert to base64 + _image_base64=$(<"$_image" base64) + + # remove temp file + rm "${_image}" + + # output + echo "data:${_image_type};base64,${_image_base64}" +} + build() { local _content @@ -344,8 +369,16 @@ build() { [[ -z "${embed_title}" ]] && \ [[ -z "${embed_description}" ]] && \ [[ -z "${embed_imageurl}" ]] && \ + [[ -z "${modify}" ]] && \ + [[ -z "${username}" ]] && \ + [[ -z "${avatar_url}" ]] && \ echo "fatal: nothing to build" && exit 1 - + + # if only specified modify but not username/avatar, exit with error + [[ -n "${modify}" ]] && \ + [[ -z "${username}" ]] && \ + [[ -z "${avatar_url}" ]] && \ + echo "fatal: must pass --username or --avatar with --modify" && exit 1 # strip 0x prefix and convert hex to dec if necessary [[ -n "${embed_color}" ]] && [[ "${embed_color}" =~ ^0x[0-9a-fA-F]+$ ]] && embed_color="$(( embed_color ))" @@ -356,8 +389,14 @@ build() { # let's build, boys [[ -n "${is_tts}" ]] && _tts=", \"tts\": true" [[ -n "${text}" ]] && _content=", \"content\": \"${text}\"" - [[ -n "${username}" ]] && _username=", \"username\": \"${username}\"" - [[ -n "${avatar_url}" ]] && _avatar=", \"avatar_url\": \"${avatar_url}\"" + # if we're modifying, change the username field to name + [[ -n "${username}" ]] && [[ -n "${modify}" ]] && _username=", \"name\": \"${username}\"" + [[ -n "${username}" ]] && [[ -z "${modify}" ]] && _username=", \"username\": \"${username}\"" + # if avatar_url is set and modify is set, change the avatar_url field to avatar and convert to base64 + # if avatar_url is set and modify is not set, change the avatar_url field to avatar + [[ -n "${avatar_url}" ]] && [[ -n "${modify}" ]] && _avatar=", \"avatar\": \"$(convert_image_link_to_base64 "${avatar_url}")\"" + [[ -n "${avatar_url}" ]] && [[ -z "${modify}" ]] && _avatar=", \"avatar_url\": \"${avatar_url}\"" + [[ -n "${embedding}" ]] && _embed="$(build_embed)" local _prefix="\"wait\": true${_tts}${_content}${_username}${_avatar}${_embed}" @@ -378,6 +417,17 @@ send() # dry run? [[ -n "${is_dry}" ]] && [[ "${is_dry}" -ne 0 ]] && echo "${1}" && exit 0; + # If any arguments except for username, modify and avatar are specified (modify option required), then exit with an error + if [[ -n "${username}" ]] || [[ -n "${avatar_url}" ]] && [[ "${modify}" = 1 ]]; then + if [[ -n "${text}" ]] && [[ -n "${embed_title}" ]] && [[ -n "${embed_description}" ]] && [[ -n "${embed_url}" ]] && [[ -n "${embed_color}" ]] && [[ -n "${embed_timestamp}" ]] && [[ -n "${embed_authorurl}" ]] && [[ -n "${embed_authoricon}" ]] && [[ -n "${embed_authorname}" ]] && [[ -n "${embed_thumbnail}" ]] && [[ -n "${embed_imageheight}" ]] && [[ -n "${embed_imagewidth}" ]] && [[ -n "${embed_imageurl}" ]] && [[ -n "${embed_footertext}" ]] && [[ -n "${embed_footericon}" ]] && [[ -n "${fields}" ]] && [[ -n "${file_path}" ]]; then + echo "fatal: no arguments specified (except for username, modify and avatar)"; exit 1; + fi + _result=$(curl -H "Content-Type: application/json" -H "Expect: application/json" -X PATCH "${webhook_url}" -d "${_sendme}" 2>/dev/null) + send_ok=$? + [[ "${send_ok}" -ne 0 ]] && echo "fatal: curl failed with code ${send_ok}" && exit $send_ok + exit 0; + fi + # make the POST request and parse the results # results should be empty if there's no problem. otherwise, there should be code and message local _result diff --git a/tests/04.modify.bats b/tests/04.modify.bats new file mode 100644 index 0000000..bdb4823 --- /dev/null +++ b/tests/04.modify.bats @@ -0,0 +1,69 @@ +#!/usr/bin/env bats + +load pre + +# Modify without username or avatar +@test "modify: --modify (should fail)" { + run bash discord.sh --modify + [ "${lines[0]}" = "fatal: must pass --username or --avatar with --modify" ] + [ "$status" -eq 1 ] +} +# Modify with username +@test "modify: --modify --username --gnu-style <>" { + run bash discord.sh --modify --username "Modify with username" + [ "$status" -eq 0 ] +} +@test "modify: verify --modify ---username --gnu-style <>" { + run bash discord.sh --text "verify" + [ "$status" -eq 0 ] +} +@test "modify: --modify --username --gnu-style=<>" { + run bash discord.sh --modify --username="Modify with username" + [ "$status" -eq 0 ] +} +@test "modify: verify --modify ---username --gnu-style=<>" { + run bash discord.sh --text "verify" + [ "$status" -eq 0 ] +} +# Modify with avatar +@test "modify: --modify --avatar --gnu-style <>" { + run bash discord.sh --modify --avatar "https://i.imgur.com/12jyR5Q.png" + [ "$status" -eq 0 ] +} +@test "modify: verify --modify ---avatar --gnu-style <>" { + run bash discord.sh --text "verify" + [ "$status" -eq 0 ] +} +@test "modify: --modify --avatar --gnu-style=<>" { + run bash discord.sh --modify --avatar="https://i.imgur.com/12jyR5Q.png" + [ "$status" -eq 0 ] +} +@test "modify: verify --modify ---avatar --gnu-style=<>" { + run bash discord.sh --text "verify" + [ "$status" -eq 0 ] +} +# Modify with username and avatar +@test "modify: --modify --username --avatar --gnu-style <>" { + run bash discord.sh --modify --username "Modify with username and avatar" --avatar "https://i.imgur.com/12jyR5Q.png" + [ "$status" -eq 0 ] +} +@test "modify: verify --modify --username --avatar --gnu-style <>" { + run bash discord.sh --text "verify" + [ "$status" -eq 0 ] +} +@test "modify: --modify --username --avatar --gnu-style=<>" { + run bash discord.sh --modify --username "Modify with username and avatar" --avatar "https://i.imgur.com/12jyR5Q.png" + [ "$status" -eq 0 ] +} +@test "modify: verify --modify --username --avatar --gnu-style=<>" { + run bash discord.sh --text "verify" + [ "$status" -eq 0 ] +} +@test "modify: --modify --username --avatar --gnu-style varied" { + run bash discord.sh --modify --username "Modify with username and avatar" --avatar="https://i.imgur.com/12jyR5Q.png" + [ "$status" -eq 0 ] +} +@test "modify: verify --modify --username --avatar --gnu-style varied" { + run bash discord.sh --text "verify" + [ "$status" -eq 0 ] +} \ No newline at end of file