Merge branch 'main' of https://git.hladu.xyz/scotty2586/obedy.git
This commit is contained in:
commit
fd5f5c667c
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -0,0 +1,218 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#### SCRIP USAGE FUNCTION ####
|
||||||
|
|
||||||
|
# Usage function.
|
||||||
|
usage() {
|
||||||
|
echo ""
|
||||||
|
echo "Usage: $0 [OPTIONS]"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " -m, --message <json-content> The Discord webhook message JSON to be checked."
|
||||||
|
echo " -d, --debug Turns on console output"
|
||||||
|
echo " -h, --help Show this help message and exit."
|
||||||
|
echo ""
|
||||||
|
echo "This script will check a Discord webhook message JSON string against content"
|
||||||
|
echo "limits set by Discord. The message data must be within the limits in order"
|
||||||
|
echo "to be successfully sent. The script will return an exit number based on the"
|
||||||
|
echo "results of the check."
|
||||||
|
echo ""
|
||||||
|
echo " 0) The message data is within the limimts."
|
||||||
|
echo " 1) The message data is outside limits, but can be sent in multiple messages."
|
||||||
|
echo " 2) The message data is outside limits and cannot be sent."
|
||||||
|
echo ""
|
||||||
|
echo "Refer to Discord Webook documentation for more details on the webhook limits:"
|
||||||
|
echo ""
|
||||||
|
echo " https://birdie0.github.io/discord-webhooks-guide/other/field_limits.html"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
#### PARSE ARGUMENTS ####
|
||||||
|
|
||||||
|
# Parsed from command line arguments.
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-m|--message)
|
||||||
|
jsonMessage="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-d|--debug)
|
||||||
|
debug=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid option: $1" >&2
|
||||||
|
usage
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if JSON is provided and not empty
|
||||||
|
if [ -z "${jsonMessage}" ]; then
|
||||||
|
echo "Error: The --message option is mandatory." >&2
|
||||||
|
usage
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
#### INITIALIZATION & PARAMETERS ####
|
||||||
|
|
||||||
|
# Character lenght limits & object count limits (the order is important!)
|
||||||
|
limits=(
|
||||||
|
'Username .username 80 char 1'
|
||||||
|
'Content .content 2000 char 1'
|
||||||
|
'Embeds .embeds 10 obj 0'
|
||||||
|
'Author .embeds[].author.name 256 char 1'
|
||||||
|
'Title .embeds[].title 256 char 1'
|
||||||
|
'Description .embeds[].description 1024 char 1'
|
||||||
|
'Fields .embeds[].fields 25 obj 1'
|
||||||
|
'Name .embeds[].fields[].name 256 char 1'
|
||||||
|
'Value .embeds[].fields[].value 1024 char 1'
|
||||||
|
'Footer .embeds[].footer.text 2048 char 1'
|
||||||
|
'Totals na 6000 char 1'
|
||||||
|
'Total na 6000 char 0'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set limit parameter names
|
||||||
|
limitParameters="name section value type critical count"
|
||||||
|
|
||||||
|
# Initialize result variables
|
||||||
|
criticalResult=false
|
||||||
|
outsideLimits=false
|
||||||
|
results=""
|
||||||
|
totalCharactersAllEmbeds=0
|
||||||
|
|
||||||
|
#### LIMIT CHECK & RESULTS FUNCTION ####
|
||||||
|
|
||||||
|
# Get count, check against limit and update results
|
||||||
|
function updateResults() {
|
||||||
|
|
||||||
|
local indexedSection="$1"
|
||||||
|
|
||||||
|
# Get the object/character count if section is an object
|
||||||
|
[ "${indexedSection}" != "na" ] && count=$(jq "$indexedSection | length" <<< "${jsonMessage}")
|
||||||
|
|
||||||
|
# Output info if debug enabled
|
||||||
|
[ ${debug} ] && echo "${name}: ${count} / ${value}" >&2
|
||||||
|
|
||||||
|
# Compare count with limit value
|
||||||
|
if [[ ${count} -gt ${value} ]]; then
|
||||||
|
|
||||||
|
# Set 'outside limit' flag
|
||||||
|
outsideLimits=true
|
||||||
|
|
||||||
|
# Check if limit is a critical one
|
||||||
|
if [ "${critical}" == "1" ]; then
|
||||||
|
|
||||||
|
# Set 'critical limit' flag
|
||||||
|
criticalResult=true
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Append to result if outside limit
|
||||||
|
results+="${name} ${indexedSection} ${value} ${type} ${critical} ${count}\n"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#### CHECK CONTENT ####
|
||||||
|
|
||||||
|
# Check content agains each limit
|
||||||
|
for limit in "${limits[@]}"; do
|
||||||
|
|
||||||
|
# Read parameters from limit
|
||||||
|
IFS=' ' read -r $limitParameters <<< "$limit"
|
||||||
|
|
||||||
|
# Check if limit relates to the embeds section
|
||||||
|
if [[ "${section}" == *"embeds[]"* ]]; then
|
||||||
|
|
||||||
|
# Check each embed section individually for applicable limits
|
||||||
|
for (( i=0; i<$(jq ".embeds | length" <<< "${jsonMessage}"); i++ )); do
|
||||||
|
|
||||||
|
# Inject array index in embeds element for correct parsing
|
||||||
|
embedSection="${section/embeds[]/embeds[${i}]}"
|
||||||
|
|
||||||
|
# Check if section is a field section as this is an array
|
||||||
|
if [[ "${section}" == *"fields[]"* ]]; then
|
||||||
|
|
||||||
|
# Check each field section individually for applicable limits
|
||||||
|
for (( j=0; j<$(jq ".embeds[$i].fields | length" <<< "${jsonMessage}"); j++ )); do
|
||||||
|
|
||||||
|
# Inject array index in fields element for correct parsing
|
||||||
|
fieldSection="${embedSection/fields[]/fields[${j}]}"
|
||||||
|
|
||||||
|
# Check limits and update results
|
||||||
|
updateResults "${fieldSection}"
|
||||||
|
|
||||||
|
# Add to total characters if character type
|
||||||
|
[ "${type}" == "char" ] && ((embedTotals[$i]+=count))
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Check limits and update results
|
||||||
|
updateResults "${embedSection}"
|
||||||
|
|
||||||
|
# Add to total characters if character type
|
||||||
|
[ "${type}" == "char" ] && ((embedTotals[$i]+=count))
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
elif [[ "${name}" == "Totals" ]]; then
|
||||||
|
|
||||||
|
# Read the total character count for each embed section
|
||||||
|
for count in "${embedTotals[@]}"; do
|
||||||
|
|
||||||
|
# Check agains limit and update result
|
||||||
|
updateResults "${section}" ${count}
|
||||||
|
|
||||||
|
# Add to the overall total character count
|
||||||
|
((totalCharactersAllEmbeds+=count))
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
elif [[ "${name}" == "Total" ]]; then
|
||||||
|
|
||||||
|
# Get the total character count for all embeds
|
||||||
|
count=${totalCharactersAllEmbeds}
|
||||||
|
|
||||||
|
# Check agains limit and update result
|
||||||
|
updateResults "${section}" ${count}
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Check agains limit and update result
|
||||||
|
updateResults "${section}"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
#### RETURN RESULTS ####
|
||||||
|
|
||||||
|
# Output results
|
||||||
|
[ ${debug} ] && [ -n "${results}" ] && echo -e "${results%??}" >&2
|
||||||
|
|
||||||
|
# Exit with appropriate status
|
||||||
|
if ${criticalResult}; then
|
||||||
|
|
||||||
|
exit 2
|
||||||
|
|
||||||
|
elif ${outsideLimits}; then
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
fi
|
|
@ -0,0 +1,191 @@
|
||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
#### SET PATHS ####
|
||||||
|
|
||||||
|
# Get path to where script is located.
|
||||||
|
scriptPath=$(echo "${0%/*}")
|
||||||
|
|
||||||
|
# Set other paths.
|
||||||
|
limitCheckScrip=${scriptPath}/discord-webhook-data-limit-check.sh
|
||||||
|
lastMessageFile=${scriptPath}/discord-webhook-last-message.json
|
||||||
|
|
||||||
|
#### SCRIP USAGE FUNCTION ####
|
||||||
|
|
||||||
|
# Usage function.
|
||||||
|
usage() {
|
||||||
|
echo ""
|
||||||
|
echo "Usage: $0 [OPTIONS]"
|
||||||
|
echo ""
|
||||||
|
echo "Options:"
|
||||||
|
echo " -c, --content <content> Set the content of the Discord message."
|
||||||
|
echo " -e, --embeds <embeds> Set the embeds of the Discord message."
|
||||||
|
echo " -f, --file <file-path> Set the file attachment path (optional)."
|
||||||
|
echo " -d, --debug Turns on console output"
|
||||||
|
echo " -h, --help Show this help message and exit."
|
||||||
|
echo ""
|
||||||
|
echo "Refer to the Discord documentation for more information on Webhooks"
|
||||||
|
echo ""
|
||||||
|
echo " https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
### SEND WEBHOOK FUNCTION ###
|
||||||
|
|
||||||
|
# Send Discord notification with or without payloaad.
|
||||||
|
sendWebhook() {
|
||||||
|
|
||||||
|
local discordJsonData="$1"
|
||||||
|
local includeAttachment="$2"
|
||||||
|
|
||||||
|
# Write last message that was attmepted to be sent to file
|
||||||
|
echo "${discordJsonData}" > ${lastMessageFile}
|
||||||
|
|
||||||
|
# Check if attachment pathe exits and if is should be included in the message
|
||||||
|
if [ -z "${discordAttachmentPath}" ] || [ "${includeAttachment}" = "false" ]; then
|
||||||
|
|
||||||
|
# Send message without attachment
|
||||||
|
echo ${discordWebhookBase}"/"${discordID}"/"${discordToken}
|
||||||
|
echo "$discordJsonData"
|
||||||
|
response=$(curl -H "Content-Type: application/json" -d "$discordJsonData" ${discordWebhookBase}"/"${discordID}"/"${discordToken})
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# Send message with attachment
|
||||||
|
response=$(curl -s -F payload_json="${discordJsonData}" -F "file1=@${discordAttachmentPath}" ${discordWebhookBase}"/"${discordID}"/"${discordToken})
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if curl was successful
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to send webhook message." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Output curl reposnse if debug enabled
|
||||||
|
[ ${debug} ] && echo "${response}" >&2
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#### PARSE ARGUMENTS ####
|
||||||
|
|
||||||
|
# Parsed from command line arguments.
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-c|--content)
|
||||||
|
discordMessageContent="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-e|--embeds)
|
||||||
|
discordMessageEmbeds="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-f|--file)
|
||||||
|
discordAttachmentPath="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-d|--debug)
|
||||||
|
debug=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid option: $1" >&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if JSON is provided and not empty
|
||||||
|
if [ -z "${discordMessageContent}" ] && [ -z "${discordMessageEmbeds}" ]; then
|
||||||
|
echo "Error: Either a message 'content' or message 'embed' is required." >&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#### DISCORD VARIABLES ####
|
||||||
|
|
||||||
|
# Discord webhook address base.
|
||||||
|
discordWebhookBase="https://discord.com/api/webhooks"
|
||||||
|
|
||||||
|
# Import secret variables.
|
||||||
|
source ${scriptPath}/discord-variables.sh
|
||||||
|
|
||||||
|
# Discord secret variables.
|
||||||
|
discordToken=${DISCORD_TOKEN}
|
||||||
|
discordID=${DISCORD_ID}
|
||||||
|
discordUsername=${DISCORD_USER}
|
||||||
|
discordAvatarURL=${DISCORD_AVATAR_URL}
|
||||||
|
discordRoleID=${DISCORD_ROLE_ID}
|
||||||
|
|
||||||
|
#### REPLACE ROLES ####
|
||||||
|
|
||||||
|
# Replace @admin mention with correct ID.
|
||||||
|
discordMessageEmbeds=$(echo "${discordMessageEmbeds}" | sed 's/\@admin/\<\@\&'${discordRoleID}'/g')
|
||||||
|
|
||||||
|
#### BUILD DISCORD MESSAGE ####
|
||||||
|
|
||||||
|
# Complete the Discord JSON string.
|
||||||
|
discordJson='{
|
||||||
|
"username":"'"${discordUsername}"'",
|
||||||
|
"content":"'"${discordMessageContent}"'",
|
||||||
|
"avatar_url":"'"${discordAvatarURL}"'",
|
||||||
|
"embeds": [ '${discordMessageEmbeds%?}' ]
|
||||||
|
}'
|
||||||
|
|
||||||
|
#### MESSAGE LIMIT CHECK & SEND ####
|
||||||
|
|
||||||
|
# Call script to perform limit checks (pass on debug argument if debug enabled)
|
||||||
|
${limitCheckScrip} -m "${discordJson}" ${debug:+-d}
|
||||||
|
|
||||||
|
# Send full, split or drop message based in limit check
|
||||||
|
case ${?} in
|
||||||
|
|
||||||
|
# Send full message
|
||||||
|
0)
|
||||||
|
# Output info if debug enabled
|
||||||
|
[ ${debug} ] && echo "Content within limits. Sending full webhook message." >&2
|
||||||
|
|
||||||
|
# Send full Json
|
||||||
|
sendWebhook "${discordJson}" true
|
||||||
|
;;
|
||||||
|
|
||||||
|
# Split message in multiple webhooks
|
||||||
|
1)
|
||||||
|
# Output info if debug enabled
|
||||||
|
[ ${debug} ] && echo "Content to large, but within manageable limits. Splitting webhook message" >&2
|
||||||
|
|
||||||
|
# Remove embeds section
|
||||||
|
discordJsonMinusEmbeds=$(jq "del(.embeds)" <<< "${discordJson}")
|
||||||
|
|
||||||
|
# Send message without embeds
|
||||||
|
sendWebhook "${discordJsonMinusEmbeds}" true
|
||||||
|
|
||||||
|
# Get number of embeds in original message
|
||||||
|
embedsCount=$(jq ".embeds | length" <<< "${discordJson}")
|
||||||
|
|
||||||
|
# Send each embed as a separate message
|
||||||
|
for (( index=0; index<$embedsCount; index++ )); do
|
||||||
|
|
||||||
|
# Get current embed in embeds section
|
||||||
|
embed=$(jq ".embeds[$index]" <<< "${discordJson}")
|
||||||
|
|
||||||
|
# Replace embeds in orignal message with current single embed and remove content section
|
||||||
|
discordJsonSingleEmbed=$(jq ".embeds=[$embed] | del(.content)" <<< "${discordJson}")
|
||||||
|
|
||||||
|
# Send message with single embed and without the rest of the data
|
||||||
|
sendWebhook "${discordJsonSingleEmbed}" false
|
||||||
|
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
|
||||||
|
# Drop message and exit with error
|
||||||
|
*)
|
||||||
|
echo "Error: Limit check failed or content outside manageable limits. Unable to send webhook." >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
Loading…
Reference in New Issue