notify.sh
· 3.5 KiB · Bash
Исходник
#!/usr/bin/env bash
#============================================================
# File: push-notify.sh
# Description: 推送消息到钉钉、飞书、Lark
# URL: https://fx4.cn/
# ORIGIN: https://gist.asfd.cn/jetsung/notify/raw/HEAD/notify.sh
# Author: Jetsung Chan <[email protected]>
# Version: 0.1.0
# CreatedAt: 2025-08-18
# UpdatedAt: 2025-08-18
#============================================================
if [[ -n "${DEBUG:-}" ]]; then
set -eux
else
set -euo pipefail
fi
judgment_parameters() {
while [[ "$#" -gt '0' ]]; do
case "$1" in
'-h' | '--help')
HELP='1'
break
;;
-m | --message)
if [[ -z "${2:?error: Please specify the correct message.}" ]]; then
exit 1
fi
MESSAGE="$2"
shift
;;
-s | --secret)
if [[ -z "${2:?error: Please specify the correct secret.}" ]]; then
exit 1
fi
SECRET="$2"
shift
;;
-t | --timestamp)
if [[ -z "${2:?error: Please specify the correct timestamp.}" ]]; then
exit 1
fi
TIMESTAMP="$2"
shift
;;
-u | --url)
if [[ -z "${2:?error: Please specify the correct url.}" ]]; then
exit 1
fi
URL="$2"
shift
;;
*)
echo "$0: unknown option -- -"
exit 1
;;
esac
shift
done
}
show_help() {
echo "usage: $0 [ options ]"
echo ' -h, --help Show help'
echo ' -m, --message Push message'
echo ' -s, --secret Push secret'
echo ' -t, --timestamp Push timestamp'
echo ' -u, --url Push url'
exit 0
}
send_message() {
SEND_TEMPLATE_DINGTALK='{
"msgtype": "text",
"text": {
"content": "消息通知: %s "
},
"at": {
"isAtAll": false
}
}'
SEND_TEMPLATE_FEISHU='{
"msg_type": "text",
"content": {"text": "消息通知: %s "},
"sign": "%s",
"timestamp": %d
}'
# shellcheck disable=SC2059
if [[ "$DOMAIN" == "oapi.dingtalk.com" ]]; then
[[ ${#TIMESTAMP} -eq 13 ]] || TIMESTAMP="${TIMESTAMP}000"
signature 1
message=$(printf "$SEND_TEMPLATE_DINGTALK" "$MESSAGE")
URL=$(printf "${URL}×tamp=%s&sign=%s" "$TIMESTAMP" "$SIGN")
else
signature 2
message=$(printf "$SEND_TEMPLATE_FEISHU" "$MESSAGE" "$SIGN" "$TIMESTAMP")
fi
curl -XPOST -s -L "$URL" -H "Content-Type:application/json" -H "charset:utf-8" -d "$message"
}
signature() {
if [[ -z "${SECRET:-}" ]]; then
SIGN=""
return
fi
string_to_sign="${TIMESTAMP}\n${SECRET}"
if [[ "${1:-1}" == 1 ]]; then
sign_str="$SECRET"
data="$string_to_sign"
else
sign_str="$string_to_sign"
data=""
fi
TMPPATH=$(mktemp "/tmp/notify.XXXXXX")
clearup() {
rm -rf "$TMPPATH"
}
trap clearup EXIT
# shellcheck disable=SC2059
printf "$sign_str" >"$TMPPATH"
# shellcheck disable=SC2059
SIGN=$(printf "$data" | openssl dgst -sha256 -hmac "$(cat "$TMPPATH")" -binary | base64)
}
main() {
judgment_parameters "$@"
[[ "${HELP:-}" -eq '1' ]] && show_help
if [[ -z "$MESSAGE" ]]; then
echo "error: Please specify the correct message."
exit 1
fi
if [[ -z "$URL" ]]; then
echo "error: Please specify the correct url."
exit 1
fi
DOMAIN=$(echo "$URL" | awk -F[/:] '{print $4}')
if [[ "$DOMAIN" != "oapi.dingtalk.com" ]] &&
[[ "$DOMAIN" != "open.feishu.cn" ]] &&
[[ "$DOMAIN" != "open.larksuite.com" ]]; then
echo "error: Please specify the correct url."
exit 1
fi
[[ -n "${TIMESTAMP:-}" ]] || TIMESTAMP="$(date +%s)"
send_message
}
main "$@"
| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | #============================================================ |
| 4 | # File: push-notify.sh |
| 5 | # Description: 推送消息到钉钉、飞书、Lark |
| 6 | # URL: https://fx4.cn/ |
| 7 | # ORIGIN: https://gist.asfd.cn/jetsung/notify/raw/HEAD/notify.sh |
| 8 | # Author: Jetsung Chan <[email protected]> |
| 9 | # Version: 0.1.0 |
| 10 | # CreatedAt: 2025-08-18 |
| 11 | # UpdatedAt: 2025-08-18 |
| 12 | #============================================================ |
| 13 | |
| 14 | |
| 15 | if [[ -n "${DEBUG:-}" ]]; then |
| 16 | set -eux |
| 17 | else |
| 18 | set -euo pipefail |
| 19 | fi |
| 20 | |
| 21 | judgment_parameters() { |
| 22 | while [[ "$#" -gt '0' ]]; do |
| 23 | case "$1" in |
| 24 | '-h' | '--help') |
| 25 | HELP='1' |
| 26 | break |
| 27 | ;; |
| 28 | -m | --message) |
| 29 | if [[ -z "${2:?error: Please specify the correct message.}" ]]; then |
| 30 | exit 1 |
| 31 | fi |
| 32 | MESSAGE="$2" |
| 33 | shift |
| 34 | ;; |
| 35 | -s | --secret) |
| 36 | if [[ -z "${2:?error: Please specify the correct secret.}" ]]; then |
| 37 | exit 1 |
| 38 | fi |
| 39 | SECRET="$2" |
| 40 | shift |
| 41 | ;; |
| 42 | -t | --timestamp) |
| 43 | if [[ -z "${2:?error: Please specify the correct timestamp.}" ]]; then |
| 44 | exit 1 |
| 45 | fi |
| 46 | TIMESTAMP="$2" |
| 47 | shift |
| 48 | ;; |
| 49 | -u | --url) |
| 50 | if [[ -z "${2:?error: Please specify the correct url.}" ]]; then |
| 51 | exit 1 |
| 52 | fi |
| 53 | URL="$2" |
| 54 | shift |
| 55 | ;; |
| 56 | *) |
| 57 | echo "$0: unknown option -- -" |
| 58 | exit 1 |
| 59 | ;; |
| 60 | esac |
| 61 | shift |
| 62 | done |
| 63 | } |
| 64 | |
| 65 | show_help() { |
| 66 | echo "usage: $0 [ options ]" |
| 67 | echo ' -h, --help Show help' |
| 68 | echo ' -m, --message Push message' |
| 69 | echo ' -s, --secret Push secret' |
| 70 | echo ' -t, --timestamp Push timestamp' |
| 71 | echo ' -u, --url Push url' |
| 72 | exit 0 |
| 73 | } |
| 74 | |
| 75 | send_message() { |
| 76 | SEND_TEMPLATE_DINGTALK='{ |
| 77 | "msgtype": "text", |
| 78 | "text": { |
| 79 | "content": "消息通知: %s " |
| 80 | }, |
| 81 | "at": { |
| 82 | "isAtAll": false |
| 83 | } |
| 84 | }' |
| 85 | |
| 86 | SEND_TEMPLATE_FEISHU='{ |
| 87 | "msg_type": "text", |
| 88 | "content": {"text": "消息通知: %s "}, |
| 89 | "sign": "%s", |
| 90 | "timestamp": %d |
| 91 | }' |
| 92 | |
| 93 | # shellcheck disable=SC2059 |
| 94 | if [[ "$DOMAIN" == "oapi.dingtalk.com" ]]; then |
| 95 | [[ ${#TIMESTAMP} -eq 13 ]] || TIMESTAMP="${TIMESTAMP}000" |
| 96 | signature 1 |
| 97 | message=$(printf "$SEND_TEMPLATE_DINGTALK" "$MESSAGE") |
| 98 | URL=$(printf "${URL}×tamp=%s&sign=%s" "$TIMESTAMP" "$SIGN") |
| 99 | else |
| 100 | signature 2 |
| 101 | message=$(printf "$SEND_TEMPLATE_FEISHU" "$MESSAGE" "$SIGN" "$TIMESTAMP") |
| 102 | fi |
| 103 | |
| 104 | curl -XPOST -s -L "$URL" -H "Content-Type:application/json" -H "charset:utf-8" -d "$message" |
| 105 | } |
| 106 | |
| 107 | signature() { |
| 108 | if [[ -z "${SECRET:-}" ]]; then |
| 109 | SIGN="" |
| 110 | return |
| 111 | fi |
| 112 | |
| 113 | string_to_sign="${TIMESTAMP}\n${SECRET}" |
| 114 | |
| 115 | if [[ "${1:-1}" == 1 ]]; then |
| 116 | sign_str="$SECRET" |
| 117 | data="$string_to_sign" |
| 118 | else |
| 119 | sign_str="$string_to_sign" |
| 120 | data="" |
| 121 | fi |
| 122 | |
| 123 | TMPPATH=$(mktemp "/tmp/notify.XXXXXX") |
| 124 | |
| 125 | clearup() { |
| 126 | rm -rf "$TMPPATH" |
| 127 | } |
| 128 | trap clearup EXIT |
| 129 | |
| 130 | # shellcheck disable=SC2059 |
| 131 | printf "$sign_str" >"$TMPPATH" |
| 132 | # shellcheck disable=SC2059 |
| 133 | SIGN=$(printf "$data" | openssl dgst -sha256 -hmac "$(cat "$TMPPATH")" -binary | base64) |
| 134 | } |
| 135 | |
| 136 | main() { |
| 137 | judgment_parameters "$@" |
| 138 | |
| 139 | [[ "${HELP:-}" -eq '1' ]] && show_help |
| 140 | |
| 141 | if [[ -z "$MESSAGE" ]]; then |
| 142 | echo "error: Please specify the correct message." |
| 143 | exit 1 |
| 144 | fi |
| 145 | |
| 146 | if [[ -z "$URL" ]]; then |
| 147 | echo "error: Please specify the correct url." |
| 148 | exit 1 |
| 149 | fi |
| 150 | |
| 151 | DOMAIN=$(echo "$URL" | awk -F[/:] '{print $4}') |
| 152 | if [[ "$DOMAIN" != "oapi.dingtalk.com" ]] && |
| 153 | [[ "$DOMAIN" != "open.feishu.cn" ]] && |
| 154 | [[ "$DOMAIN" != "open.larksuite.com" ]]; then |
| 155 | echo "error: Please specify the correct url." |
| 156 | exit 1 |
| 157 | fi |
| 158 | |
| 159 | [[ -n "${TIMESTAMP:-}" ]] || TIMESTAMP="$(date +%s)" |
| 160 | |
| 161 | send_message |
| 162 | } |
| 163 | |
| 164 | main "$@" |
| 165 |