lufi42
3 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1000 additions and 602 deletions
-
2.github/FUNDING.yml
-
10.github/workflows/FreeBSD.yml
-
1.github/workflows/Linux.yml
-
10.github/workflows/MacOS.yml
-
10.github/workflows/Solaris.yml
-
10.github/workflows/Windows.yml
-
3Dockerfile
-
1README.md
-
318acme.sh
-
28deploy/mailcow.sh
-
4deploy/qiniu.sh
-
68deploy/routeros.sh
-
72deploy/truenas.sh
-
14dnsapi/dns_1984hosting.sh
-
52dnsapi/dns_aws.sh
-
11dnsapi/dns_cf.sh
-
185dnsapi/dns_cx.sh
-
2dnsapi/dns_cyon.sh
-
4dnsapi/dns_edgedns.sh
-
146dnsapi/dns_fornex.sh
-
4dnsapi/dns_gcloud.sh
-
177dnsapi/dns_gdnsdk.sh
-
11dnsapi/dns_geoscaling.sh
-
30dnsapi/dns_ionos.sh
-
2dnsapi/dns_ispconfig.sh
-
46dnsapi/dns_loopia.sh
-
4dnsapi/dns_mydevil.sh
-
4dnsapi/dns_namecheap.sh
-
10dnsapi/dns_nederhost.sh
-
2dnsapi/dns_netlify.sh
-
2dnsapi/dns_oci.sh
-
2dnsapi/dns_ovh.sh
-
4dnsapi/dns_selectel.sh
-
16dnsapi/dns_simply.sh
-
21dnsapi/dns_ultra.sh
-
142dnsapi/dns_vercel.sh
-
24dnsapi/dns_world4you.sh
-
44notify/callmebotWhatsApp.sh
-
57notify/discord.sh
-
49notify/weixin_work.sh
@ -1,185 +0,0 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
# CloudXNS Domain api |
|||
# |
|||
#CX_Key="1234" |
|||
# |
|||
#CX_Secret="sADDsdasdgdsf" |
|||
|
|||
CX_Api="https://www.cloudxns.net/api2" |
|||
|
|||
#REST_API |
|||
######## Public functions ##################### |
|||
|
|||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_cx_add() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
|
|||
CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}" |
|||
CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}" |
|||
if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ]; then |
|||
CX_Key="" |
|||
CX_Secret="" |
|||
_err "You don't specify cloudxns.net api key or secret yet." |
|||
_err "Please create you key and try again." |
|||
return 1 |
|||
fi |
|||
|
|||
REST_API="$CX_Api" |
|||
|
|||
#save the api key and email to the account conf file. |
|||
_saveaccountconf_mutable CX_Key "$CX_Key" |
|||
_saveaccountconf_mutable CX_Secret "$CX_Secret" |
|||
|
|||
_debug "First detect the root zone" |
|||
if ! _get_root "$fulldomain"; then |
|||
_err "invalid domain" |
|||
return 1 |
|||
fi |
|||
|
|||
add_record "$_domain" "$_sub_domain" "$txtvalue" |
|||
} |
|||
|
|||
#fulldomain txtvalue |
|||
dns_cx_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
CX_Key="${CX_Key:-$(_readaccountconf_mutable CX_Key)}" |
|||
CX_Secret="${CX_Secret:-$(_readaccountconf_mutable CX_Secret)}" |
|||
REST_API="$CX_Api" |
|||
if _get_root "$fulldomain"; then |
|||
record_id="" |
|||
existing_records "$_domain" "$_sub_domain" "$txtvalue" |
|||
if [ "$record_id" ]; then |
|||
_rest DELETE "record/$record_id/$_domain_id" "{}" |
|||
_info "Deleted record ${fulldomain}" |
|||
fi |
|||
fi |
|||
} |
|||
|
|||
#usage: root sub |
|||
#return if the sub record already exists. |
|||
#echos the existing records count. |
|||
# '0' means doesn't exist |
|||
existing_records() { |
|||
_debug "Getting txt records" |
|||
root=$1 |
|||
sub=$2 |
|||
if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100"; then |
|||
return 1 |
|||
fi |
|||
|
|||
seg=$(printf "%s\n" "$response" | _egrep_o '"record_id":[^{]*host":"'"$_sub_domain"'"[^}]*\}') |
|||
_debug seg "$seg" |
|||
if [ -z "$seg" ]; then |
|||
return 0 |
|||
fi |
|||
|
|||
if printf "%s" "$response" | grep '"type":"TXT"' >/dev/null; then |
|||
record_id=$(printf "%s\n" "$seg" | _egrep_o '"record_id":"[^"]*"' | cut -d : -f 2 | tr -d \" | _head_n 1) |
|||
_debug record_id "$record_id" |
|||
return 0 |
|||
fi |
|||
|
|||
} |
|||
|
|||
#add the txt record. |
|||
#usage: root sub txtvalue |
|||
add_record() { |
|||
root=$1 |
|||
sub=$2 |
|||
txtvalue=$3 |
|||
fulldomain="$sub.$root" |
|||
|
|||
_info "Adding record" |
|||
|
|||
if ! _rest POST "record" "{\"domain_id\": $_domain_id, \"host\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"type\":\"TXT\",\"ttl\":600, \"line_id\":1}"; then |
|||
return 1 |
|||
fi |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
#_acme-challenge.www.domain.com |
|||
#returns |
|||
# _sub_domain=_acme-challenge.www |
|||
# _domain=domain.com |
|||
# _domain_id=sdjkglgdfewsdfg |
|||
_get_root() { |
|||
domain=$1 |
|||
i=2 |
|||
p=1 |
|||
|
|||
if ! _rest GET "domain"; then |
|||
return 1 |
|||
fi |
|||
|
|||
while true; do |
|||
h=$(printf "%s" "$domain" | cut -d . -f $i-100) |
|||
_debug h "$h" |
|||
if [ -z "$h" ]; then |
|||
#not valid |
|||
return 1 |
|||
fi |
|||
|
|||
if _contains "$response" "$h."; then |
|||
seg=$(printf "%s\n" "$response" | _egrep_o '"id":[^{]*"'"$h"'."[^}]*}') |
|||
_debug seg "$seg" |
|||
_domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") |
|||
_debug _domain_id "$_domain_id" |
|||
if [ "$_domain_id" ]; then |
|||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) |
|||
_debug _sub_domain "$_sub_domain" |
|||
_domain="$h" |
|||
_debug _domain "$_domain" |
|||
return 0 |
|||
fi |
|||
return 1 |
|||
fi |
|||
p="$i" |
|||
i=$(_math "$i" + 1) |
|||
done |
|||
return 1 |
|||
} |
|||
|
|||
#Usage: method URI data |
|||
_rest() { |
|||
m=$1 |
|||
ep="$2" |
|||
_debug ep "$ep" |
|||
url="$REST_API/$ep" |
|||
_debug url "$url" |
|||
|
|||
cdate=$(date -u "+%Y-%m-%d %H:%M:%S UTC") |
|||
_debug cdate "$cdate" |
|||
|
|||
data="$3" |
|||
_debug data "$data" |
|||
|
|||
sec="$CX_Key$url$data$cdate$CX_Secret" |
|||
_debug sec "$sec" |
|||
hmac=$(printf "%s" "$sec" | _digest md5 hex) |
|||
_debug hmac "$hmac" |
|||
|
|||
export _H1="API-KEY: $CX_Key" |
|||
export _H2="API-REQUEST-DATE: $cdate" |
|||
export _H3="API-HMAC: $hmac" |
|||
export _H4="Content-Type: application/json" |
|||
|
|||
if [ "$data" ]; then |
|||
response="$(_post "$data" "$url" "" "$m")" |
|||
else |
|||
response="$(_get "$url")" |
|||
fi |
|||
|
|||
if [ "$?" != "0" ]; then |
|||
_err "error $ep" |
|||
return 1 |
|||
fi |
|||
_debug2 response "$response" |
|||
|
|||
_contains "$response" '"code":1' |
|||
|
|||
} |
@ -0,0 +1,146 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
#Author: Timur Umarov <inbox@tumarov.com> |
|||
|
|||
FORNEX_API_URL="https://fornex.com/api/dns/v0.1" |
|||
|
|||
######## Public functions ##################### |
|||
|
|||
#Usage: dns_fornex_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_fornex_add() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
|
|||
if ! _Fornex_API; then |
|||
return 1 |
|||
fi |
|||
|
|||
if ! _get_root "$fulldomain"; then |
|||
_err "Unable to determine root domain" |
|||
return 1 |
|||
else |
|||
_debug _domain "$_domain" |
|||
fi |
|||
|
|||
_info "Adding record" |
|||
if _rest POST "$_domain/entry_set/add/" "host=$fulldomain&type=TXT&value=$txtvalue&apikey=$FORNEX_API_KEY"; then |
|||
_debug _response "$response" |
|||
if _contains "$response" '"ok": true' || _contains "$response" 'Такая запись уже существует.'; then |
|||
_info "Added, OK" |
|||
return 0 |
|||
fi |
|||
fi |
|||
_err "Add txt record error." |
|||
return 1 |
|||
} |
|||
|
|||
#Usage: dns_fornex_rm _acme-challenge.www.domain.com |
|||
dns_fornex_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
|
|||
if ! _Fornex_API; then |
|||
return 1 |
|||
fi |
|||
|
|||
if ! _get_root "$fulldomain"; then |
|||
_err "Unable to determine root domain" |
|||
return 1 |
|||
else |
|||
_debug _domain "$_domain" |
|||
fi |
|||
|
|||
_debug "Getting txt records" |
|||
_rest GET "$_domain/entry_set.json?apikey=$FORNEX_API_KEY" |
|||
|
|||
if ! _contains "$response" "$txtvalue"; then |
|||
_err "Txt record not found" |
|||
return 1 |
|||
fi |
|||
|
|||
_record_id="$(echo "$response" | _egrep_o "{[^{]*\"value\"*:*\"$txtvalue\"[^}]*}" | sed -n -e 's#.*"id": \([0-9]*\).*#\1#p')" |
|||
_debug "_record_id" "$_record_id" |
|||
if [ -z "$_record_id" ]; then |
|||
_err "can not find _record_id" |
|||
return 1 |
|||
fi |
|||
|
|||
if ! _rest POST "$_domain/entry_set/$_record_id/delete/" "apikey=$FORNEX_API_KEY"; then |
|||
_err "Delete record error." |
|||
return 1 |
|||
fi |
|||
return 0 |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
|
|||
#_acme-challenge.www.domain.com |
|||
#returns |
|||
# _sub_domain=_acme-challenge.www |
|||
# _domain=domain.com |
|||
_get_root() { |
|||
domain=$1 |
|||
|
|||
i=1 |
|||
while true; do |
|||
h=$(printf "%s" "$domain" | cut -d . -f $i-100) |
|||
_debug h "$h" |
|||
if [ -z "$h" ]; then |
|||
#not valid |
|||
return 1 |
|||
fi |
|||
|
|||
if ! _rest GET "domain_list.json?q=$h&apikey=$FORNEX_API_KEY"; then |
|||
return 1 |
|||
fi |
|||
|
|||
if _contains "$response" "\"$h\"" >/dev/null; then |
|||
_domain=$h |
|||
return 0 |
|||
else |
|||
_debug "$h not found" |
|||
fi |
|||
i=$(_math "$i" + 1) |
|||
done |
|||
|
|||
return 1 |
|||
} |
|||
|
|||
_Fornex_API() { |
|||
FORNEX_API_KEY="${FORNEX_API_KEY:-$(_readaccountconf_mutable FORNEX_API_KEY)}" |
|||
if [ -z "$FORNEX_API_KEY" ]; then |
|||
FORNEX_API_KEY="" |
|||
|
|||
_err "You didn't specify the Fornex API key yet." |
|||
_err "Please create your key and try again." |
|||
|
|||
return 1 |
|||
fi |
|||
|
|||
_saveaccountconf_mutable FORNEX_API_KEY "$FORNEX_API_KEY" |
|||
} |
|||
|
|||
#method method action data |
|||
_rest() { |
|||
m=$1 |
|||
ep="$2" |
|||
data="$3" |
|||
_debug "$ep" |
|||
|
|||
export _H1="Accept: application/json" |
|||
|
|||
if [ "$m" != "GET" ]; then |
|||
_debug data "$data" |
|||
response="$(_post "$data" "$FORNEX_API_URL/$ep" "" "$m")" |
|||
else |
|||
response="$(_get "$FORNEX_API_URL/$ep" | _normalizeJson)" |
|||
fi |
|||
|
|||
_ret="$?" |
|||
if [ "$_ret" != "0" ]; then |
|||
_err "error $ep" |
|||
return 1 |
|||
fi |
|||
_debug2 response "$response" |
|||
return 0 |
|||
} |
@ -1,177 +0,0 @@ |
|||
#!/usr/bin/env sh |
|||
#Author: Herman Sletteng |
|||
#Report Bugs here: https://github.com/loial/acme.sh |
|||
# |
|||
# |
|||
# Note, gratisdns requires a login first, so the script needs to handle |
|||
# temporary cookies. Since acme.sh _get/_post currently don't directly support |
|||
# cookies, I've defined wrapper functions _myget/_mypost to set the headers |
|||
|
|||
GDNSDK_API="https://admin.gratisdns.com" |
|||
######## Public functions ##################### |
|||
#Usage: dns_gdnsdk_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_gdnsdk_add() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
_info "Using gratisdns.dk" |
|||
_debug fulldomain "$fulldomain" |
|||
_debug txtvalue "$txtvalue" |
|||
if ! _gratisdns_login; then |
|||
_err "Login failed!" |
|||
return 1 |
|||
fi |
|||
#finding domain zone |
|||
if ! _get_domain; then |
|||
_err "No matching root domain for $fulldomain found" |
|||
return 1 |
|||
fi |
|||
# adding entry |
|||
_info "Adding the entry" |
|||
_mypost "action=dns_primary_record_added_txt&user_domain=$_domain&name=$fulldomain&txtdata=$txtvalue&ttl=1" |
|||
if _successful_update; then return 0; fi |
|||
_err "Couldn't create entry!" |
|||
return 1 |
|||
} |
|||
|
|||
#Usage: fulldomain txtvalue |
|||
#Remove the txt record after validation. |
|||
dns_gdnsdk_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
_info "Using gratisdns.dk" |
|||
_debug fulldomain "$fulldomain" |
|||
_debug txtvalue "$txtvalue" |
|||
if ! _gratisdns_login; then |
|||
_err "Login failed!" |
|||
return 1 |
|||
fi |
|||
if ! _get_domain; then |
|||
_err "No matching root domain for $fulldomain found" |
|||
return 1 |
|||
fi |
|||
_findentry "$fulldomain" "$txtvalue" |
|||
if [ -z "$_id" ]; then |
|||
_info "Entry doesn't exist, nothing to delete" |
|||
return 0 |
|||
fi |
|||
_debug "Deleting record..." |
|||
_mypost "action=dns_primary_delete_txt&user_domain=$_domain&id=$_id" |
|||
# removing entry |
|||
|
|||
if _successful_update; then return 0; fi |
|||
_err "Couldn't delete entry!" |
|||
return 1 |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
|
|||
_checkcredentials() { |
|||
GDNSDK_Username="${GDNSDK_Username:-$(_readaccountconf_mutable GDNSDK_Username)}" |
|||
GDNSDK_Password="${GDNSDK_Password:-$(_readaccountconf_mutable GDNSDK_Password)}" |
|||
|
|||
if [ -z "$GDNSDK_Username" ] || [ -z "$GDNSDK_Password" ]; then |
|||
GDNSDK_Username="" |
|||
GDNSDK_Password="" |
|||
_err "You haven't specified gratisdns.dk username and password yet." |
|||
_err "Please add credentials and try again." |
|||
return 1 |
|||
fi |
|||
#save the credentials to the account conf file. |
|||
_saveaccountconf_mutable GDNSDK_Username "$GDNSDK_Username" |
|||
_saveaccountconf_mutable GDNSDK_Password "$GDNSDK_Password" |
|||
return 0 |
|||
} |
|||
|
|||
_checkcookie() { |
|||
GDNSDK_Cookie="${GDNSDK_Cookie:-$(_readaccountconf_mutable GDNSDK_Cookie)}" |
|||
if [ -z "$GDNSDK_Cookie" ]; then |
|||
_debug "No cached cookie found" |
|||
return 1 |
|||
fi |
|||
_myget "action=" |
|||
if (echo "$_result" | grep -q "logmeout"); then |
|||
_debug "Cached cookie still valid" |
|||
return 0 |
|||
fi |
|||
_debug "Cached cookie no longer valid" |
|||
GDNSDK_Cookie="" |
|||
_saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie" |
|||
return 1 |
|||
} |
|||
|
|||
_gratisdns_login() { |
|||
if ! _checkcredentials; then return 1; fi |
|||
|
|||
if _checkcookie; then |
|||
_debug "Already logged in" |
|||
return 0 |
|||
fi |
|||
_debug "Logging into GratisDNS with user $GDNSDK_Username" |
|||
|
|||
if ! _mypost "login=$GDNSDK_Username&password=$GDNSDK_Password&action=logmein"; then |
|||
_err "GratisDNS login failed for user $GDNSDK_Username bad RC from _post" |
|||
return 1 |
|||
fi |
|||
|
|||
GDNSDK_Cookie="$(grep -A 15 '302 Found' "$HTTP_HEADER" | _egrep_o 'Cookie: [^;]*' | _head_n 1 | cut -d ' ' -f2)" |
|||
|
|||
if [ -z "$GDNSDK_Cookie" ]; then |
|||
_err "GratisDNS login failed for user $GDNSDK_Username. Check $HTTP_HEADER file" |
|||
return 1 |
|||
fi |
|||
export GDNSDK_Cookie |
|||
_saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie" |
|||
return 0 |
|||
} |
|||
|
|||
_myget() { |
|||
#Adds cookie to request |
|||
export _H1="Cookie: $GDNSDK_Cookie" |
|||
_result=$(_get "$GDNSDK_API?$1") |
|||
} |
|||
_mypost() { |
|||
#Adds cookie to request |
|||
export _H1="Cookie: $GDNSDK_Cookie" |
|||
_result=$(_post "$1" "$GDNSDK_API") |
|||
} |
|||
|
|||
_get_domain() { |
|||
_myget 'action=dns_primarydns' |
|||
_domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:]._-]+' | sed 's/^.*"//') |
|||
if [ -z "$_domains" ]; then |
|||
_err "Primary domain list not found!" |
|||
return 1 |
|||
fi |
|||
for _domain in $_domains; do |
|||
if (_endswith "$fulldomain" "$_domain"); then |
|||
_debug "Root domain: $_domain" |
|||
return 0 |
|||
fi |
|||
done |
|||
return 1 |
|||
} |
|||
|
|||
_successful_update() { |
|||
if (echo "$_result" | grep -q 'table-success'); then return 0; fi |
|||
return 1 |
|||
} |
|||
|
|||
_findentry() { |
|||
#args $1: fulldomain, $2: txtvalue |
|||
#returns id of dns entry, if it exists |
|||
_myget "action=dns_primary_changeDNSsetup&user_domain=$_domain" |
|||
_debug3 "_result: $_result" |
|||
|
|||
_tmp_result=$(echo "$_result" | tr -d '\n\r' | _egrep_o "<td>$1</td>\s*<td>$2</td>[^?]*[^&]*&id=[^&]*") |
|||
_debug _tmp_result "$_tmp_result" |
|||
if [ -z "${_tmp_result:-}" ]; then |
|||
_debug "The variable is _tmp_result is not supposed to be empty, there may be something wrong with the script" |
|||
fi |
|||
|
|||
_id=$(echo "$_tmp_result" | sed 's/^.*=//') |
|||
if [ -n "$_id" ]; then |
|||
_debug "Entry found with _id=$_id" |
|||
return 0 |
|||
fi |
|||
return 1 |
|||
} |
@ -0,0 +1,142 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
# Vercel DNS API |
|||
# |
|||
# This is your API token which can be acquired on the account page. |
|||
# https://vercel.com/account/tokens |
|||
# |
|||
# VERCEL_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje" |
|||
|
|||
VERCEL_API="https://api.vercel.com" |
|||
|
|||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" |
|||
dns_vercel_add() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
_debug fulldomain "$fulldomain" |
|||
_debug txtvalue "$txtvalue" |
|||
|
|||
VERCEL_TOKEN="${VERCEL_TOKEN:-$(_readaccountconf_mutable VERCEL_TOKEN)}" |
|||
|
|||
if [ -z "$VERCEL_TOKEN" ]; then |
|||
VERCEL_TOKEN="" |
|||
_err "You have not set the Vercel API token yet." |
|||
_err "Please visit https://vercel.com/account/tokens to generate it." |
|||
return 1 |
|||
fi |
|||
|
|||
_saveaccountconf_mutable VERCEL_TOKEN "$VERCEL_TOKEN" |
|||
|
|||
if ! _get_root "$fulldomain"; then |
|||
_err "invalid domain" |
|||
return 1 |
|||
fi |
|||
|
|||
_debug _sub_domain "$_sub_domain" |
|||
_debug _domain "$_domain" |
|||
|
|||
_info "Adding record" |
|||
if _vercel_rest POST "v2/domains/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}"; then |
|||
if printf -- "%s" "$response" | grep "\"uid\":\"" >/dev/null; then |
|||
_info "Added" |
|||
return 0 |
|||
else |
|||
_err "Unexpected response while adding text record." |
|||
return 1 |
|||
fi |
|||
fi |
|||
_err "Add txt record error." |
|||
} |
|||
|
|||
dns_vercel_rm() { |
|||
fulldomain=$1 |
|||
txtvalue=$2 |
|||
|
|||
if ! _get_root "$fulldomain"; then |
|||
_err "invalid domain" |
|||
return 1 |
|||
fi |
|||
|
|||
_vercel_rest GET "v2/domains/$_domain/records" |
|||
|
|||
count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\"" | wc -l | tr -d " ") |
|||
|
|||
if [ "$count" = "0" ]; then |
|||
_info "Don't need to remove." |
|||
else |
|||
_record_id=$(printf "%s" "$response" | _egrep_o "\"id\":[^,]*,\"slug\":\"[^,]*\",\"name\":\"$_sub_domain\",[^{]*\"type\":\"TXT\",\"value\":\"$txtvalue\"" | cut -d: -f2 | cut -d, -f1 | tr -d '"') |
|||
|
|||
if [ "$_record_id" ]; then |
|||
echo "$_record_id" | while read -r item; do |
|||
if _vercel_rest DELETE "v2/domains/$_domain/records/$item"; then |
|||
_info "removed record" "$item" |
|||
return 0 |
|||
else |
|||
_err "failed to remove record" "$item" |
|||
return 1 |
|||
fi |
|||
done |
|||
fi |
|||
fi |
|||
} |
|||
|
|||
#################### Private functions below ################################## |
|||
#_acme-challenge.www.domain.com |
|||
#returns |
|||
# _sub_domain=_acme-challenge.www |
|||
# _domain=domain.com |
|||
_get_root() { |
|||
domain="$1" |
|||
ep="$2" |
|||
i=1 |
|||
p=1 |
|||
while true; do |
|||
h=$(printf "%s" "$domain" | cut -d . -f $i-100) |
|||
if [ -z "$h" ]; then |
|||
#not valid |
|||
return 1 |
|||
fi |
|||
|
|||
if ! _vercel_rest GET "v4/domains/$h"; then |
|||
return 1 |
|||
fi |
|||
|
|||
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then |
|||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) |
|||
_domain=$h |
|||
return 0 |
|||
fi |
|||
p=$i |
|||
i=$(_math "$i" + 1) |
|||
done |
|||
return 1 |
|||
} |
|||
|
|||
_vercel_rest() { |
|||
m="$1" |
|||
ep="$2" |
|||
data="$3" |
|||
|
|||
path="$VERCEL_API/$ep" |
|||
|
|||
export _H1="Content-Type: application/json" |
|||
export _H2="Authorization: Bearer $VERCEL_TOKEN" |
|||
|
|||
if [ "$m" != "GET" ]; then |
|||
_secure_debug2 data "$data" |
|||
response="$(_post "$data" "$path" "" "$m")" |
|||
else |
|||
response="$(_get "$path")" |
|||
fi |
|||
_ret="$?" |
|||
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" |
|||
_debug "http response code $_code" |
|||
_secure_debug2 response "$response" |
|||
if [ "$_ret" != "0" ]; then |
|||
_err "error $ep" |
|||
return 1 |
|||
fi |
|||
|
|||
response="$(printf "%s" "$response" | _normalizeJson)" |
|||
return 0 |
|||
} |
@ -0,0 +1,44 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
#Support CallMeBot Whatsapp webhooks |
|||
|
|||
#CALLMEBOT_YOUR_PHONE_NO="" |
|||
#CALLMEBOT_API_KEY="" |
|||
|
|||
callmebotWhatsApp_send() { |
|||
_subject="$1" |
|||
_content="$2" |
|||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped |
|||
_debug "_statusCode" "$_statusCode" |
|||
|
|||
CALLMEBOT_YOUR_PHONE_NO="${CALLMEBOT_YOUR_PHONE_NO:-$(_readaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO)}" |
|||
if [ -z "$CALLMEBOT_YOUR_PHONE_NO" ]; then |
|||
CALLMEBOT_YOUR_PHONE_NO="" |
|||
_err "You didn't specify a Slack webhook url CALLMEBOT_YOUR_PHONE_NO yet." |
|||
return 1 |
|||
fi |
|||
_saveaccountconf_mutable CALLMEBOT_YOUR_PHONE_NO "$CALLMEBOT_YOUR_PHONE_NO" |
|||
|
|||
CALLMEBOT_API_KEY="${CALLMEBOT_API_KEY:-$(_readaccountconf_mutable CALLMEBOT_API_KEY)}" |
|||
if [ "$CALLMEBOT_API_KEY" ]; then |
|||
_saveaccountconf_mutable CALLMEBOT_API_KEY "$CALLMEBOT_API_KEY" |
|||
fi |
|||
|
|||
_waUrl="https://api.callmebot.com/whatsapp.php" |
|||
|
|||
_Phone_No="$(printf "%s" "$CALLMEBOT_YOUR_PHONE_NO" | _url_encode)" |
|||
_apikey="$(printf "%s" "$CALLMEBOT_API_KEY" | _url_encode)" |
|||
_message="$(printf "*%s*\\n%s" "$_subject" "$_content" | _url_encode)" |
|||
|
|||
_finalUrl="$_waUrl?phone=$_Phone_No&apikey=$_apikey&text=$_message" |
|||
response="$(_get "$_finalUrl")" |
|||
|
|||
if [ "$?" = "0" ] && _contains ".<p><b>Message queued.</b> You will receive it in a few seconds."; then |
|||
_info "wa send success." |
|||
return 0 |
|||
fi |
|||
_err "wa send error." |
|||
_debug "URL" "$_finalUrl" |
|||
_debug "Response" "$response" |
|||
return 1 |
|||
} |
@ -0,0 +1,57 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
#Support Discord webhooks |
|||
|
|||
# Required: |
|||
#DISCORD_WEBHOOK_URL="" |
|||
# Optional: |
|||
#DISCORD_USERNAME="" |
|||
#DISCORD_AVATAR_URL="" |
|||
|
|||
discord_send() { |
|||
_subject="$1" |
|||
_content="$2" |
|||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped |
|||
_debug "_statusCode" "$_statusCode" |
|||
|
|||
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-$(_readaccountconf_mutable DISCORD_WEBHOOK_URL)}" |
|||
if [ -z "$DISCORD_WEBHOOK_URL" ]; then |
|||
DISCORD_WEBHOOK_URL="" |
|||
_err "You didn't specify a Discord webhook url DISCORD_WEBHOOK_URL yet." |
|||
return 1 |
|||
fi |
|||
_saveaccountconf_mutable DISCORD_WEBHOOK_URL "$DISCORD_WEBHOOK_URL" |
|||
|
|||
DISCORD_USERNAME="${DISCORD_USERNAME:-$(_readaccountconf_mutable DISCORD_USERNAME)}" |
|||
if [ "$DISCORD_USERNAME" ]; then |
|||
_saveaccountconf_mutable DISCORD_USERNAME "$DISCORD_USERNAME" |
|||
fi |
|||
|
|||
DISCORD_AVATAR_URL="${DISCORD_AVATAR_URL:-$(_readaccountconf_mutable DISCORD_AVATAR_URL)}" |
|||
if [ "$DISCORD_AVATAR_URL" ]; then |
|||
_saveaccountconf_mutable DISCORD_AVATAR_URL "$DISCORD_AVATAR_URL" |
|||
fi |
|||
|
|||
export _H1="Content-Type: application/json" |
|||
|
|||
_content="$(printf "**%s**\n%s" "$_subject" "$_content" | _json_encode)" |
|||
_data="{\"content\": \"$_content\" " |
|||
if [ "$DISCORD_USERNAME" ]; then |
|||
_data="$_data, \"username\": \"$DISCORD_USERNAME\" " |
|||
fi |
|||
if [ "$DISCORD_AVATAR_URL" ]; then |
|||
_data="$_data, \"avatar_url\": \"$DISCORD_AVATAR_URL\" " |
|||
fi |
|||
_data="$_data}" |
|||
|
|||
if _post "$_data" "$DISCORD_WEBHOOK_URL?wait=true"; then |
|||
# shellcheck disable=SC2154 |
|||
if [ "$response" ]; then |
|||
_info "discord send success." |
|||
return 0 |
|||
fi |
|||
fi |
|||
_err "discord send error." |
|||
_err "$response" |
|||
return 1 |
|||
} |
@ -0,0 +1,49 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
#Support weixin work webhooks api |
|||
|
|||
#WEIXIN_WORK_WEBHOOK="xxxx" |
|||
|
|||
#optional |
|||
#WEIXIN_WORK_KEYWORD="yyyy" |
|||
|
|||
#`WEIXIN_WORK_SIGNING_KEY`="SEC08ffdbd403cbc3fc8a65xxxxxxxxxxxxxxxxxxxx" |
|||
|
|||
# subject content statusCode |
|||
weixin_work_send() { |
|||
_subject="$1" |
|||
_content="$2" |
|||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped |
|||
_debug "_subject" "$_subject" |
|||
_debug "_content" "$_content" |
|||
_debug "_statusCode" "$_statusCode" |
|||
|
|||
WEIXIN_WORK_WEBHOOK="${WEIXIN_WORK_WEBHOOK:-$(_readaccountconf_mutable WEIXIN_WORK_WEBHOOK)}" |
|||
if [ -z "$WEIXIN_WORK_WEBHOOK" ]; then |
|||
WEIXIN_WORK_WEBHOOK="" |
|||
_err "You didn't specify a weixin_work webhooks WEIXIN_WORK_WEBHOOK yet." |
|||
_err "You can get yours from https://work.weixin.qq.com/api/doc/90000/90136/91770" |
|||
return 1 |
|||
fi |
|||
_saveaccountconf_mutable WEIXIN_WORK_WEBHOOK "$WEIXIN_WORK_WEBHOOK" |
|||
|
|||
WEIXIN_WORK_KEYWORD="${WEIXIN_WORK_KEYWORD:-$(_readaccountconf_mutable WEIXIN_WORK_KEYWORD)}" |
|||
if [ "$WEIXIN_WORK_KEYWORD" ]; then |
|||
_saveaccountconf_mutable WEIXIN_WORK_KEYWORD "$WEIXIN_WORK_KEYWORD" |
|||
fi |
|||
|
|||
_content=$(echo "$_content" | _json_encode) |
|||
_subject=$(echo "$_subject" | _json_encode) |
|||
_data="{\"msgtype\": \"text\", \"text\": {\"content\": \"[$WEIXIN_WORK_KEYWORD]\n$_subject\n$_content\"}}" |
|||
|
|||
response="$(_post "$_data" "$WEIXIN_WORK_WEBHOOK" "" "POST" "application/json")" |
|||
|
|||
if [ "$?" = "0" ] && _contains "$response" "errmsg\":\"ok"; then |
|||
_info "weixin_work webhooks event fired success." |
|||
return 0 |
|||
fi |
|||
|
|||
_err "weixin_work webhooks event fired error." |
|||
_err "$response" |
|||
return 1 |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue