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