Merge branch 'dev' of https://github.com/Neilpang/acme.sh into FreeDNS

This commit is contained in:
David Kerr 2019-08-09 21:05:08 -04:00
commit 9826b8ae69
14 changed files with 852 additions and 68 deletions

28
acme.sh
View File

@ -3035,11 +3035,13 @@ _clearupdns() {
d=$(_getfield "$entry" 1) d=$(_getfield "$entry" 1)
txtdomain=$(_getfield "$entry" 2) txtdomain=$(_getfield "$entry" 2)
aliasDomain=$(_getfield "$entry" 3) aliasDomain=$(_getfield "$entry" 3)
_currentRoot=$(_getfield "$entry" 4)
txt=$(_getfield "$entry" 5) txt=$(_getfield "$entry" 5)
d_api=$(_getfield "$entry" 6) d_api=$(_getfield "$entry" 6)
_debug "d" "$d" _debug "d" "$d"
_debug "txtdomain" "$txtdomain" _debug "txtdomain" "$txtdomain"
_debug "aliasDomain" "$aliasDomain" _debug "aliasDomain" "$aliasDomain"
_debug "_currentRoot" "$_currentRoot"
_debug "txt" "$txt" _debug "txt" "$txt"
_debug "d_api" "$d_api" _debug "d_api" "$d_api"
if [ "$d_api" = "$txt" ]; then if [ "$d_api" = "$txt" ]; then
@ -3263,6 +3265,11 @@ _on_issue_success() {
if [ "$_chk_post_hook" ]; then if [ "$_chk_post_hook" ]; then
_info "Run post hook:'$_chk_post_hook'" _info "Run post hook:'$_chk_post_hook'"
if ! ( if ! (
export CERT_PATH
export CERT_KEY_PATH
export CA_CERT_PATH
export CERT_FULLCHAIN_PATH
export Le_Domain="$_main_domain"
cd "$DOMAIN_PATH" && eval "$_chk_post_hook" cd "$DOMAIN_PATH" && eval "$_chk_post_hook"
); then ); then
_err "Error when run post hook." _err "Error when run post hook."
@ -3274,6 +3281,11 @@ _on_issue_success() {
if [ "$IS_RENEW" ] && [ "$_chk_renew_hook" ]; then if [ "$IS_RENEW" ] && [ "$_chk_renew_hook" ]; then
_info "Run renew hook:'$_chk_renew_hook'" _info "Run renew hook:'$_chk_renew_hook'"
if ! ( if ! (
export CERT_PATH
export CERT_KEY_PATH
export CA_CERT_PATH
export CERT_FULLCHAIN_PATH
export Le_Domain="$_main_domain"
cd "$DOMAIN_PATH" && eval "$_chk_renew_hook" cd "$DOMAIN_PATH" && eval "$_chk_renew_hook"
); then ); then
_err "Error when run renew hook." _err "Error when run renew hook."
@ -3621,7 +3633,7 @@ _ns_purge_cf() {
_cf_d="$1" _cf_d="$1"
_cf_d_type="$2" _cf_d_type="$2"
_debug "Cloudflare purge $_cf_d_type record for domain $_cf_d" _debug "Cloudflare purge $_cf_d_type record for domain $_cf_d"
_cf_purl="https://1.1.1.1/api/v1/purge?domain=$_cf_d&type=$_cf_d_type" _cf_purl="https://cloudflare-dns.com/api/v1/purge?domain=$_cf_d&type=$_cf_d_type"
response="$(_post "" "$_cf_purl")" response="$(_post "" "$_cf_purl")"
_debug2 response "$response" _debug2 response "$response"
} }
@ -3680,11 +3692,11 @@ _check_dns_entries() {
fi fi
_left=1 _left=1
_info "Not valid yet, let's wait 10 seconds and check next one." _info "Not valid yet, let's wait 10 seconds and check next one."
_sleep 10
__purge_txt "$txtdomain" __purge_txt "$txtdomain"
if [ "$txtdomain" != "$aliasDomain" ]; then if [ "$txtdomain" != "$aliasDomain" ]; then
__purge_txt "$aliasDomain" __purge_txt "$aliasDomain"
fi fi
_sleep 10
done done
if [ "$_left" ]; then if [ "$_left" ]; then
_info "Let's wait 10 seconds and check again". _info "Let's wait 10 seconds and check again".
@ -5930,8 +5942,12 @@ _send_notify() {
_send_err=0 _send_err=0
for _n_hook in $(echo "$_nhooks" | tr ',' " "); do for _n_hook in $(echo "$_nhooks" | tr ',' " "); do
_n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")" _n_hook_file="$(_findHook "" $_SUB_FOLDER_NOTIFY "$_n_hook")"
_info "Found $_n_hook_file" _info "Sending via: $_n_hook"
_debug "Found $_n_hook_file for $_n_hook"
if [ -z "$_n_hook_file" ]; then
_err "Can not find the hook file for $_n_hook"
continue
fi
if ! ( if ! (
if ! . "$_n_hook_file"; then if ! . "$_n_hook_file"; then
_err "Load file $_n_hook_file error. Please check your api file and try again." _err "Load file $_n_hook_file error. Please check your api file and try again."
@ -5966,7 +5982,7 @@ _set_notify_hook() {
_nhooks="$1" _nhooks="$1"
_test_subject="Hello, this is notification from $PROJECT_NAME" _test_subject="Hello, this is notification from $PROJECT_NAME"
_test_content="If you receive this email, your notification works." _test_content="If you receive this message, your notification works."
_send_notify "$_test_subject" "$_test_content" "$_nhooks" 0 _send_notify "$_test_subject" "$_test_content" "$_nhooks" 0
@ -6787,7 +6803,7 @@ _process() {
_debug "Using server: $_server" _debug "Using server: $_server"
fi fi
fi fi
_debug "Running cmd: ${_CMD}"
case "${_CMD}" in case "${_CMD}" in
install) install "$_nocron" "$_confighome" "$_noprofile" ;; install) install "$_nocron" "$_confighome" "$_noprofile" ;;
uninstall) uninstall "$_nocron" ;; uninstall) uninstall "$_nocron" ;;

View File

@ -126,6 +126,7 @@ docker_deploy() {
fi fi
if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then if [ "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD" ]; then
_info "Reloading: $DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"
if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then if ! _docker_exec "$_cid" "$DEPLOY_DOCKER_CONTAINER_RELOAD_CMD"; then
return 1 return 1
fi fi
@ -223,7 +224,8 @@ _docker_cp() {
_debug2 "_frompath" "$_frompath" _debug2 "_frompath" "$_frompath"
_toname="$(basename "$_to")" _toname="$(basename "$_to")"
_debug2 "_toname" "$_toname" _debug2 "_toname" "$_toname"
if ! tar --transform="s,$_frompath,$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then _debug2 "_from" "$_from"
if ! tar --transform="s,$(printf "%s" "$_frompath" | tr '*' .),$_toname," -cz "$_from" 2>/dev/null | _curl_unix_sock "$_DOCKER_SOCK" PUT "/containers/$_dcid/archive?noOverwriteDirNonDir=1&path=$(printf "%s" "$_dir" | _url_encode)" '@-' "Content-Type: application/octet-stream"; then
_err "copy error" _err "copy error"
return 1 return 1
fi fi

View File

@ -5,6 +5,9 @@
# #
#CF_Email="xxxx@sss.com" #CF_Email="xxxx@sss.com"
#CF_Token="xxxx"
#CF_Account_ID="xxxx"
CF_Api="https://api.cloudflare.com/client/v4" CF_Api="https://api.cloudflare.com/client/v4"
######## Public functions ##################### ######## Public functions #####################
@ -14,25 +17,32 @@ dns_cf_add() {
fulldomain=$1 fulldomain=$1
txtvalue=$2 txtvalue=$2
CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}"
CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}"
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
CF_Key=""
CF_Email=""
_err "You didn't specify a Cloudflare api key and email yet."
_err "You can get yours from here https://dash.cloudflare.com/profile."
return 1
fi
if ! _contains "$CF_Email" "@"; then if [ "$CF_Token" ]; then
_err "It seems that the CF_Email=$CF_Email is not a valid email address." _saveaccountconf_mutable CF_Token "$CF_Token"
_err "Please check and retry." _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID"
return 1 else
fi if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
CF_Key=""
CF_Email=""
_err "You didn't specify a Cloudflare api key and email yet."
_err "You can get yours from here https://dash.cloudflare.com/profile."
return 1
fi
#save the api key and email to the account conf file. if ! _contains "$CF_Email" "@"; then
_saveaccountconf_mutable CF_Key "$CF_Key" _err "It seems that the CF_Email=$CF_Email is not a valid email address."
_saveaccountconf_mutable CF_Email "$CF_Email" _err "Please check and retry."
return 1
fi
#save the api key and email to the account conf file.
_saveaccountconf_mutable CF_Key "$CF_Key"
_saveaccountconf_mutable CF_Email "$CF_Email"
fi
_debug "First detect the root zone" _debug "First detect the root zone"
if ! _get_root "$fulldomain"; then if ! _get_root "$fulldomain"; then
@ -71,19 +81,6 @@ dns_cf_add() {
fi fi
_err "Add txt record error." _err "Add txt record error."
return 1 return 1
# else
# _info "Updating record"
# record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1)
# _debug "record_id" "$record_id"
#
# _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}"
# if [ "$?" = "0" ]; then
# _info "Updated, OK"
# return 0
# fi
# _err "Update error"
# return 1
# fi
} }
@ -92,15 +89,10 @@ dns_cf_rm() {
fulldomain=$1 fulldomain=$1
txtvalue=$2 txtvalue=$2
CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}"
CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}"
CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}"
CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}"
if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
CF_Key=""
CF_Email=""
_err "You didn't specify a Cloudflare api key and email yet."
_err "You can get yours from here https://dash.cloudflare.com/profile."
return 1
fi
_debug "First detect the root zone" _debug "First detect the root zone"
if ! _get_root "$fulldomain"; then if ! _get_root "$fulldomain"; then
@ -157,8 +149,14 @@ _get_root() {
return 1 return 1
fi fi
if ! _cf_rest GET "zones?name=$h"; then if [ "$CF_Account_ID" ]; then
return 1 if ! _cf_rest GET "zones?name=$h&account.id=$CF_Account_ID"; then
return 1
fi
else
if ! _cf_rest GET "zones?name=$h"; then
return 1
fi
fi fi
if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then
@ -182,12 +180,17 @@ _cf_rest() {
data="$3" data="$3"
_debug "$ep" _debug "$ep"
email_trimmed=$(echo $CF_Email | tr -d '"') email_trimmed=$(echo "$CF_Email" | tr -d '"')
key_trimmed=$(echo $CF_Key | tr -d '"') key_trimmed=$(echo "$CF_Key" | tr -d '"')
token_trimmed=$(echo "$CF_Token" | tr -d '"')
export _H1="X-Auth-Email: $email_trimmed" export _H1="Content-Type: application/json"
export _H2="X-Auth-Key: $key_trimmed" if [ "$token_trimmed" ]; then
export _H3="Content-Type: application/json" export _H2="Authorization: Bearer $token_trimmed"
else
export _H2="X-Auth-Email: $email_trimmed"
export _H3="X-Auth-Key: $key_trimmed"
fi
if [ "$m" != "GET" ]; then if [ "$m" != "GET" ]; then
_debug data "$data" _debug data "$data"

View File

@ -25,8 +25,8 @@ dns_desec_add() {
if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then
DEDYN_TOKEN="" DEDYN_TOKEN=""
DEDYN_NAME="" DEDYN_NAME=""
_err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet."
_err "Please create you key and try again." _err "Please create your key and try again."
_err "e.g." _err "e.g."
_err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err "export DEDYN_NAME=foobar.dedyn.io" _err "export DEDYN_NAME=foobar.dedyn.io"
@ -92,8 +92,8 @@ dns_desec_rm() {
if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then
DEDYN_TOKEN="" DEDYN_TOKEN=""
DEDYN_NAME="" DEDYN_NAME=""
_err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet." _err "You did not specify DEDYN_TOKEN and DEDYN_NAME yet."
_err "Please create you key and try again." _err "Please create your key and try again."
_err "e.g." _err "e.g."
_err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e" _err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err "export DEDYN_NAME=foobar.dedyn.io" _err "export DEDYN_NAME=foobar.dedyn.io"

View File

@ -63,7 +63,7 @@ dns_dp_rm() {
return 0 return 0
fi fi
record_id=$(echo "$response" | tr "{" "\n" | grep "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2) record_id=$(echo "$response" | tr "{" "\n" | grep -- "$txtvalue" | grep '^"id"' | cut -d : -f 2 | cut -d '"' -f 2)
_debug record_id "$record_id" _debug record_id "$record_id"
if [ -z "$record_id" ]; then if [ -z "$record_id" ]; then
_err "Can not get record id." _err "Can not get record id."

View File

@ -134,9 +134,9 @@ _find_zone() {
_zone_ids=$(echo "$_matches" | _egrep_o "hosted_dns_zoneid=[0-9]*&" | cut -d = -f 2 | tr -d '&') _zone_ids=$(echo "$_matches" | _egrep_o "hosted_dns_zoneid=[0-9]*&" | cut -d = -f 2 | tr -d '&')
_zone_names=$(echo "$_matches" | _egrep_o "name=.*onclick" | cut -d '"' -f 2) _zone_names=$(echo "$_matches" | _egrep_o "name=.*onclick" | cut -d '"' -f 2)
_debug2 "These are the zones on this HE account:" _debug2 "These are the zones on this HE account:"
_debug2 "$_zone_names" _debug2 "_zone_names" "$_zone_names"
_debug2 "And these are their respective IDs:" _debug2 "And these are their respective IDs:"
_debug2 "$_zone_ids" _debug2 "_zone_ids" "$_zone_ids"
if [ -z "$_zone_names" ] || [ -z "$_zone_ids" ]; then if [ -z "$_zone_names" ] || [ -z "$_zone_ids" ]; then
_err "Can not get zone names." _err "Can not get zone names."
return 1 return 1
@ -154,10 +154,14 @@ _find_zone() {
_debug "Looking for zone \"${_attempted_zone}\"" _debug "Looking for zone \"${_attempted_zone}\""
line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone" | cut -d : -f 1)" line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone\$" | _head_n 1 | cut -d : -f 1)"
_debug2 line_num "$line_num"
if [ "$line_num" ]; then if [ "$line_num" ]; then
_zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p") _zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p")
if [ -z "$_zone_id" ]; then
_err "Can not find zone id."
return 1
fi
_debug "Found relevant zone \"$_attempted_zone\" with id \"$_zone_id\" - will be used for domain \"$_domain\"." _debug "Found relevant zone \"$_attempted_zone\" with id \"$_zone_id\" - will be used for domain \"$_domain\"."
return 0 return 0
fi fi

156
dnsapi/dns_hexonet.sh Executable file
View File

@ -0,0 +1,156 @@
#!/usr/bin/env sh
#
# Hexonet_Login="username!roleId"
#
# Hexonet_Password="rolePassword"
Hexonet_Api="https://coreapi.1api.net/api/call.cgi"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_hexonet_add() {
fulldomain=$1
txtvalue=$2
Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}"
Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}"
if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then
Hexonet_Login=""
Hexonet_Password=""
_err "You must export variables: Hexonet_Login and Hexonet_Password"
return 1
fi
if ! _contains "$Hexonet_Login" "!"; then
_err "It seems that the Hexonet_Login=$Hexonet_Login is not a restrivteed user."
_err "Please check and retry."
return 1
fi
#save the username and password to the account conf file.
_saveaccountconf_mutable Hexonet_Login "$Hexonet_Login"
_saveaccountconf_mutable Hexonet_Password "$Hexonet_Password"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT"
if ! _contains "$response" "CODE=200"; then
_err "Error"
return 1
fi
_info "Adding record"
if _hexonet_rest "command=UpdateDNSZone&dnszone=${_domain}.&addrr0=${_sub_domain}%20IN%20TXT%20${txtvalue}"; then
if _contains "$response" "CODE=200"; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#fulldomain txtvalue
dns_hexonet_rm() {
fulldomain=$1
txtvalue=$2
Hexonet_Login="${Hexonet_Login:-$(_readaccountconf_mutable Hexonet_Login)}"
Hexonet_Password="${Hexonet_Password:-$(_readaccountconf_mutable Hexonet_Password)}"
if [ -z "$Hexonet_Login" ] || [ -z "$Hexonet_Password" ]; then
Hexonet_Login=""
Hexonet_Password=""
_err "You must export variables: Hexonet_Login and Hexonet_Password"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug "Getting txt records"
_hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}.&RRTYPE=TXT&RR=${txtvalue}"
if ! _contains "$response" "CODE=200"; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o "PROPERTY[TOTAL][0]=" | cut -d = -f 2)
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Don't need to remove."
else
if ! _hexonet_rest "&command=UpdateDNSZone&dnszone=${_domain}.&delrr0='${_sub_domain}%20IN%20TXT%20\"${txtvalue}\""; then
_err "Delete record error."
return 1
fi
_contains "$response" "CODE=200"
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain=$1
i=1
p=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 ! _hexonet_rest "&command=QueryDNSZoneRRList&dnszone=${h}."; then
return 1
fi
if _contains "$response" "CODE=200"; 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
}
_hexonet_rest() {
query_params="$1"
_debug "$query_params"
response="$(_get "${Hexonet_Api}?s_login=${Hexonet_Login}&s_pw=${Hexonet_Password}&${query_params}")"
if [ "$?" != "0" ]; then
_err "error $query_params"
return 1
fi
_debug2 response "$response"
return 0
}

286
dnsapi/dns_jd.sh Normal file
View File

@ -0,0 +1,286 @@
#!/usr/bin/env sh
#
#JD_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
#JD_ACCESS_KEY_SECRET="xxxxxxx"
#JD_REGION="cn-north-1"
_JD_ACCOUNT="https://uc.jdcloud.com/account/accesskey"
_JD_PROD="clouddnsservice"
_JD_API="jdcloud-api.com"
_JD_API_VERSION="v1"
_JD_DEFAULT_REGION="cn-north-1"
_JD_HOST="$_JD_PROD.$_JD_API"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_jd_add() {
fulldomain=$1
txtvalue=$2
JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}"
JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}"
JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}"
if [ -z "$JD_ACCESS_KEY_ID" ] || [ -z "$JD_ACCESS_KEY_SECRET" ]; then
JD_ACCESS_KEY_ID=""
JD_ACCESS_KEY_SECRET=""
_err "You haven't specifed the jdcloud api key id or api key secret yet."
_err "Please create your key and try again. see $(__green $_JD_ACCOUNT)"
return 1
fi
_saveaccountconf_mutable JD_ACCESS_KEY_ID "$JD_ACCESS_KEY_ID"
_saveaccountconf_mutable JD_ACCESS_KEY_SECRET "$JD_ACCESS_KEY_SECRET"
if [ -z "$JD_REGION" ]; then
_debug "Using default region: $_JD_DEFAULT_REGION"
JD_REGION="$_JD_DEFAULT_REGION"
else
_saveaccountconf_mutable JD_REGION "$JD_REGION"
fi
_JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
#_debug "Getting getViewTree"
_debug "Adding records"
_addrr="{\"req\":{\"hostRecord\":\"$_sub_domain\",\"hostValue\":\"$txtvalue\",\"ttl\":300,\"type\":\"TXT\",\"viewValue\":-1},\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}"
#_addrr='{"req":{"hostRecord":"xx","hostValue":"\"value4\"","jcloudRes":false,"mxPriority":null,"port":null,"ttl":300,"type":"TXT","weight":null,"viewValue":-1},"regionId":"cn-north-1","domainId":"8824"}'
if jd_rest POST "domain/$_domain_id/RRAdd" "" "$_addrr"; then
_rid="$(echo "$response" | tr '{},' '\n' | grep '"id":' | cut -d : -f 2)"
if [ -z "$_rid" ]; then
_err "Can not find record id from the result."
return 1
fi
_info "TXT record added successfully."
_srid="$(_readdomainconf "JD_CLOUD_RIDS")"
if [ "$_srid" ]; then
_rid="$_srid,$_rid"
fi
_savedomainconf "JD_CLOUD_RIDS" "$_rid"
return 0
fi
return 1
}
dns_jd_rm() {
fulldomain=$1
txtvalue=$2
JD_ACCESS_KEY_ID="${JD_ACCESS_KEY_ID:-$(_readaccountconf_mutable JD_ACCESS_KEY_ID)}"
JD_ACCESS_KEY_SECRET="${JD_ACCESS_KEY_SECRET:-$(_readaccountconf_mutable JD_ACCESS_KEY_SECRET)}"
JD_REGION="${JD_REGION:-$(_readaccountconf_mutable JD_REGION)}"
if [ -z "$JD_REGION" ]; then
_debug "Using default region: $_JD_DEFAULT_REGION"
JD_REGION="$_JD_DEFAULT_REGION"
fi
_JD_BASE_URI="$_JD_API_VERSION/regions/$JD_REGION"
_info "Getting existing records for $fulldomain"
_srid="$(_readdomainconf "JD_CLOUD_RIDS")"
_debug _srid "$_srid"
if [ -z "$_srid" ]; then
_err "Not rid skip"
return 0
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_cleardomainconf JD_CLOUD_RIDS
_aws_tmpl_xml="{\"ids\":[$_srid],\"action\":\"del\",\"regionId\":\"$JD_REGION\",\"domainId\":\"$_domain_id\"}"
if jd_rest POST "domain/$_domain_id/RROperate" "" "$_aws_tmpl_xml" && _contains "$response" "\"code\":\"OK\""; then
_info "TXT record deleted successfully."
return 0
fi
return 1
}
#################### Private functions below ##################################
_get_root() {
domain=$1
i=1
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug2 "Checking domain: $h"
if ! jd_rest GET "domain"; then
_err "error get domain list"
return 1
fi
if [ -z "$h" ]; then
#not valid
_err "Invalid domain"
return 1
fi
if _contains "$response" "\"domainName\":\"$h\""; then
hostedzone="$(echo "$response" | tr '{}' '\n' | grep "\"domainName\":\"$h\"")"
_debug hostedzone "$hostedzone"
if [ "$hostedzone" ]; then
_domain_id="$(echo "$hostedzone" | tr ',' '\n' | grep "\"id\":" | cut -d : -f 2)"
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
fi
_err "Can't find domain with id: $h"
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
#method uri qstr data
jd_rest() {
mtd="$1"
ep="$2"
qsr="$3"
data="$4"
_debug mtd "$mtd"
_debug ep "$ep"
_debug qsr "$qsr"
_debug data "$data"
CanonicalURI="/$_JD_BASE_URI/$ep"
_debug2 CanonicalURI "$CanonicalURI"
CanonicalQueryString="$qsr"
_debug2 CanonicalQueryString "$CanonicalQueryString"
RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")"
#RequestDate="20190713T082155Z" ######################################################
_debug2 RequestDate "$RequestDate"
export _H1="X-Jdcloud-Date: $RequestDate"
RequestNonce="2bd0852a-8bae-4087-b2d5-$(_time)"
#RequestNonce="894baff5-72d4-4244-883a-7b2eb51e7fbe" #################################
_debug2 RequestNonce "$RequestNonce"
export _H2="X-Jdcloud-Nonce: $RequestNonce"
if [ "$data" ]; then
CanonicalHeaders="content-type:application/json\n"
SignedHeaders="content-type;"
else
CanonicalHeaders=""
SignedHeaders=""
fi
CanonicalHeaders="${CanonicalHeaders}host:$_JD_HOST\nx-jdcloud-date:$RequestDate\nx-jdcloud-nonce:$RequestNonce\n"
SignedHeaders="${SignedHeaders}host;x-jdcloud-date;x-jdcloud-nonce"
_debug2 CanonicalHeaders "$CanonicalHeaders"
_debug2 SignedHeaders "$SignedHeaders"
Hash="sha256"
RequestPayload="$data"
_debug2 RequestPayload "$RequestPayload"
RequestPayloadHash="$(printf "%s" "$RequestPayload" | _digest "$Hash" hex | _lower_case)"
_debug2 RequestPayloadHash "$RequestPayloadHash"
CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$RequestPayloadHash"
_debug2 CanonicalRequest "$CanonicalRequest"
HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)"
_debug2 HashedCanonicalRequest "$HashedCanonicalRequest"
Algorithm="JDCLOUD2-HMAC-SHA256"
_debug2 Algorithm "$Algorithm"
RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)"
_debug2 RequestDateOnly "$RequestDateOnly"
Region="$JD_REGION"
Service="$_JD_PROD"
CredentialScope="$RequestDateOnly/$Region/$Service/jdcloud2_request"
_debug2 CredentialScope "$CredentialScope"
StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest"
_debug2 StringToSign "$StringToSign"
kSecret="JDCLOUD2$JD_ACCESS_KEY_SECRET"
_secure_debug2 kSecret "$kSecret"
kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")"
_secure_debug2 kSecretH "$kSecretH"
kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)"
_debug2 kDateH "$kDateH"
kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)"
_debug2 kRegionH "$kRegionH"
kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)"
_debug2 kServiceH "$kServiceH"
kSigningH="$(printf "%s" "jdcloud2_request" | _hmac "$Hash" "$kServiceH" hex)"
_debug2 kSigningH "$kSigningH"
signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)"
_debug2 signature "$signature"
Authorization="$Algorithm Credential=$JD_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature"
_debug2 Authorization "$Authorization"
_H3="Authorization: $Authorization"
_debug _H3 "$_H3"
url="https://$_JD_HOST$CanonicalURI"
if [ "$qsr" ]; then
url="https://$_JD_HOST$CanonicalURI?$qsr"
fi
if [ "$mtd" = "GET" ]; then
response="$(_get "$url")"
else
response="$(_post "$data" "$url" "" "$mtd" "application/json")"
fi
_ret="$?"
_debug2 response "$response"
if [ "$_ret" = "0" ]; then
if _contains "$response" "\"error\""; then
_err "Response error:$response"
return 1
fi
fi
return "$_ret"
}

View File

@ -164,7 +164,7 @@ _namecheap_set_publicip() {
_debug sourceip "$NAMECHEAP_SOURCEIP" _debug sourceip "$NAMECHEAP_SOURCEIP"
ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') ip=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https)://.*') addr=$(echo "$NAMECHEAP_SOURCEIP" | _egrep_o '(http|https):\/\/.*')
_debug2 ip "$ip" _debug2 ip "$ip"
_debug2 addr "$addr" _debug2 addr "$addr"

View File

@ -59,9 +59,14 @@ dns_namesilo_rm() {
if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then if _namesilo_rest GET "dnsListRecords?version=1&type=xml&key=$Namesilo_Key&domain=$_domain"; then
retcode=$(printf "%s\n" "$response" | _egrep_o "<code>300") retcode=$(printf "%s\n" "$response" | _egrep_o "<code>300")
if [ "$retcode" ]; then if [ "$retcode" ]; then
_record_id=$(printf "%s\n" "$response" | _egrep_o "<record_id>([^<]*)</record_id><type>TXT</type><host>$fulldomain</host>" | _egrep_o "<record_id>([^<]*)</record_id>" | sed -r "s/<record_id>([^<]*)<\/record_id>/\1/" | tail -n 1) _record_id=$(echo "$response" | _egrep_o "<record_id>([^<]*)</record_id><type>TXT</type><host>$fulldomain</host>" | _egrep_o "<record_id>([^<]*)</record_id>" | sed -r "s/<record_id>([^<]*)<\/record_id>/\1/" | tail -n 1)
_debug record_id "$_record_id" _debug _record_id "$_record_id"
_info "Successfully retrieved the record id for ACME challenge." if [ "$_record_id" ]; then
_info "Successfully retrieved the record id for ACME challenge."
else
_info "Empty record id, it seems no such record."
return 0
fi
else else
_err "Unable to retrieve the record id." _err "Unable to retrieve the record id."
return 1 return 1

163
dnsapi/dns_vultr.sh Normal file
View File

@ -0,0 +1,163 @@
#!/usr/bin/env sh
#
#VULTR_API_KEY=000011112222333344445555666677778888
VULTR_Api="https://api.vultr.com/v1"
######## Public functions #####################
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_vultr_add() {
fulldomain=$1
txtvalue=$2
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}"
if test -z "$VULTR_API_KEY"; then
VULTR_API_KEY=''
_err 'VULTR_API_KEY was not exported'
return 1
fi
_saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY"
_debug 'First detect the root zone'
if ! _get_root "$fulldomain"; then
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug 'Getting txt records'
_vultr_rest GET "dns/records?domain=$_domain"
if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
_err 'Error'
return 1
fi
if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then
_err "$response"
return 1
fi
_debug2 _response "$response"
return 0
}
#fulldomain txtvalue
dns_vultr_rm() {
fulldomain=$1
txtvalue=$2
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
VULTR_API_KEY="${VULTR_API_KEY:-$(_readaccountconf_mutable VULTR_API_KEY)}"
if test -z "$VULTR_API_KEY"; then
VULTR_API_KEY=""
_err 'VULTR_API_KEY was not exported'
return 1
fi
_saveaccountconf_mutable VULTR_API_KEY "$VULTR_API_KEY"
_debug 'First detect the root zone'
if ! _get_root "$fulldomain"; then
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
_debug 'Getting txt records'
_vultr_rest GET "dns/records?domain=$_domain"
if printf "%s\n" "$response" | grep "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
_err 'Error'
return 1
fi
_record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)"
_debug _record_id "$_record_id"
if [ "$_record_id" ]; then
_info "Successfully retrieved the record id for ACME challenge."
else
_info "Empty record id, it seems no such record."
return 0
fi
if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then
_err "$response"
return 1
fi
_debug2 _response "$response"
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=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
return 1
fi
if ! _vultr_rest GET "dns/list"; then
return 1
fi
if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then
if _contains "$response" "\"domain\":\"$_domain\""; then
_sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
_domain=$_domain
return 0
else
_err 'Invalid domain'
return 1
fi
else
_err "$response"
return 1
fi
i=$(_math "$i" + 1)
done
return 1
}
_vultr_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"')
export _H1="Api-Key: $api_key_trimmed"
export _H2='Content-Type: application/x-www-form-urlencoded'
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$VULTR_Api/$ep" "" "$m")"
else
response="$(_get "$VULTR_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "Error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

86
notify/ifttt.sh Normal file
View File

@ -0,0 +1,86 @@
#!/usr/bin/env sh
#Support ifttt.com webhooks api
#IFTTT_API_KEY="xxxx"
#IFTTT_EVENT_NAME="yyyy"
#IFTTT_SUBJECT_KEY="value1|value2|value3" #optional, use "value1" as default
#IFTTT_CONTENT_KEY="value1|value2|value3" #optional, use "value2" as default
_IFTTT_AVAIL_MSG_KEYS="value1,value2,value3"
# subject content statusCode
ifttt_send() {
_subject="$1"
_content="$2"
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
_debug "_subject" "$_subject"
_debug "_content" "$_content"
_debug "_statusCode" "$_statusCode"
IFTTT_API_KEY="${IFTTT_API_KEY:-$(_readaccountconf_mutable IFTTT_API_KEY)}"
if [ -z "$IFTTT_API_KEY" ]; then
IFTTT_API_KEY=""
_err "You didn't specify a ifttt webhooks api key IFTTT_API_KEY yet."
_err "You can get yours from https://ifttt.com"
return 1
fi
_saveaccountconf_mutable IFTTT_API_KEY "$IFTTT_API_KEY"
IFTTT_EVENT_NAME="${IFTTT_EVENT_NAME:-$(_readaccountconf_mutable IFTTT_EVENT_NAME)}"
if [ -z "$IFTTT_EVENT_NAME" ]; then
IFTTT_EVENT_NAME=""
_err "You didn't specify a ifttt webhooks event name IFTTT_EVENT_NAME yet."
return 1
fi
_saveaccountconf_mutable IFTTT_EVENT_NAME "$IFTTT_EVENT_NAME"
IFTTT_SUBJECT_KEY="${IFTTT_SUBJECT_KEY:-$(_readaccountconf_mutable IFTTT_SUBJECT_KEY)}"
if [ -z "$IFTTT_SUBJECT_KEY" ]; then
IFTTT_SUBJECT_KEY="value1"
_info "The IFTTT_SUBJECT_KEY is not set, so use the default value1 as key."
elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$IFTTT_SUBJECT_KEY"; then
_err "The IFTTT_SUBJECT_KEY \"$IFTTT_SUBJECT_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS"
IFTTT_SUBJECT_KEY=""
return 1
else
_saveaccountconf_mutable IFTTT_SUBJECT_KEY "$IFTTT_SUBJECT_KEY"
fi
IFTTT_CONTENT_KEY="${IFTTT_CONTENT_KEY:-$(_readaccountconf_mutable IFTTT_CONTENT_KEY)}"
if [ -z "$IFTTT_CONTENT_KEY" ]; then
IFTTT_CONTENT_KEY="value2"
_info "The IFTTT_CONTENT_KEY is not set, so use the default value2 as key."
elif ! _hasfield "$_IFTTT_AVAIL_MSG_KEYS" "$IFTTT_CONTENT_KEY"; then
_err "The IFTTT_CONTENT_KEY \"$IFTTT_CONTENT_KEY\" is not available, should be one of $_IFTTT_AVAIL_MSG_KEYS"
IFTTT_CONTENT_KEY=""
return 1
else
_saveaccountconf_mutable IFTTT_CONTENT_KEY "$IFTTT_CONTENT_KEY"
fi
if [ "$IFTTT_SUBJECT_KEY" = "$IFTTT_CONTENT_KEY" ]; then
IFTTT_SUBJECT_KEY=""
IFTTT_CONTENT_KEY=""
_err "The IFTTT_SUBJECT_KEY must not be same as IFTTT_CONTENT_KEY."
return 1
fi
IFTTT_API_URL="https://maker.ifttt.com/trigger/$IFTTT_EVENT_NAME/with/key/$IFTTT_API_KEY"
_content=$(echo "$_content" | _json_encode)
_subject=$(echo "$_subject" | _json_encode)
_data="{\"$IFTTT_SUBJECT_KEY\": \"$_subject\", \"$IFTTT_CONTENT_KEY\": \"$_content\"}"
response="$(_post "$_data" "$IFTTT_API_URL" "" "POST" "application/json")"
if [ "$?" = "0" ] && _contains "$response" "Congratulations"; then
_info "IFTTT webhooks event fired success."
return 0
fi
_err "IFTTT webhooks event fired error."
_err "$response"
return 1
}

63
notify/pushover.sh Normal file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env sh
#Support for pushover.net's api. Push notification platform for multiple platforms
#PUSHOVER_TOKEN="" Required, pushover application token
#PUSHOVER_USER="" Required, pushover userkey
#PUSHOVER_DEVICE="" Optional, Specific device or devices by hostnames, joining multiples with a comma (such as device=iphone,nexus5)
#PUSHOVER_PRIORITY="" Optional, Lowest Priority (-2), Low Priority (-1), Normal Priority (0), High Priority (1)
PUSHOVER_URI="https://api.pushover.net/1/messages.json"
pushover_send() {
_subject="$1"
_content="$2"
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
_debug "_statusCode" "$_statusCode"
PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-$(_readaccountconf_mutable PUSHOVER_TOKEN)}"
if [ -z "$PUSHOVER_TOKEN" ]; then
PUSHOVER_TOKEN=""
_err "You didn't specify a PushOver application token yet."
return 1
fi
_saveaccountconf_mutable PUSHOVER_TOKEN "$PUSHOVER_TOKEN"
PUSHOVER_USER="${PUSHOVER_USER:-$(_readaccountconf_mutable PUSHOVER_USER)}"
if [ -z "$PUSHOVER_USER" ]; then
PUSHOVER_USER=""
_err "You didn't specify a PushOver UserKey yet."
return 1
fi
_saveaccountconf_mutable PUSHOVER_USER "$PUSHOVER_USER"
PUSHOVER_DEVICE="${PUSHOVER_DEVICE:-$(_readaccountconf_mutable PUSHOVER_DEVICE)}"
if [ "$PUSHOVER_DEVICE" ]; then
_saveaccountconf_mutable PUSHOVER_DEVICE "$PUSHOVER_DEVICE"
fi
PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-$(_readaccountconf_mutable PUSHOVER_PRIORITY)}"
if [ "$PUSHOVER_PRIORITY" ]; then
_saveaccountconf_mutable PUSHOVER_PRIORITY "$PUSHOVER_PRIORITY"
fi
PUSHOVER_SOUND="${PUSHOVER_SOUND:-$(_readaccountconf_mutable PUSHOVER_SOUND)}"
if [ "$PUSHOVER_SOUND" ]; then
_saveaccountconf_mutable PUSHOVER_SOUND "$PUSHOVER_SOUND"
fi
export _H1="Content-Type: application/json"
_content="$(printf "*%s*\n" "$_content" | _json_encode)"
_subject="$(printf "*%s*\n" "$_subject" | _json_encode)"
_data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}"
response="$(_post "$_data" "$PUSHOVER_URI")"
if [ "$?" = "0" ] && _contains "$response" "{\"status\":1"; then
_info "PUSHOVER send success."
return 0
fi
_err "PUSHOVER send error."
_err "$response"
return 1
}

View File

@ -42,13 +42,13 @@ sendgrid_send() {
_content="$(echo "$_content" | _json_encode)" _content="$(echo "$_content" | _json_encode)"
_data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}" _data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}"
response="" #just make shellcheck happy response="$(_post "$_data" "https://api.sendgrid.com/v3/mail/send")"
if _post "$_data" "https://api.sendgrid.com/v3/mail/send"; then
if [ -z "$response" ]; then if [ "$?" = "0" ] && [ -z "$response" ]; then
_info "sendgrid send sccess." _info "sendgrid send sccess."
return 0 return 0
fi
fi fi
_err "sendgrid send error." _err "sendgrid send error."
_err "$response" _err "$response"
return 1 return 1