{"record":{"id":"31937638f1aa8ea9","repo":"XIU2/CloudflareSpeedTest","slug":"email-api-api","errorCode":null,"errorMessage":"[信息] 缺少配置项 [EMAIL]，由 [API 密钥] 方式转为 [API 令牌] 方式!","messagePattern":"\\[信息\\] 缺少配置项 \\[EMAIL\\]，由 \\[API 密钥\\] 方式转为 \\[API 令牌\\] 方式!","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"script/cfst_ddns.sh","lineNumber":23,"sourceCode":"#\t项目: CloudflareSpeedTest 自动更新域名解析记录\n#\t版本: 1.0.5\n#\t作者: XIU2\n#\t项目: https://github.com/XIU2/CloudflareSpeedTest\n# --------------------------------------------------------------\n\n_READ() {\n\t[[ ! -e \"cfst_ddns.conf\" ]] && echo -e \"[错误] 配置文件不存在 [cfst_ddns.conf] !\" && exit 1\n\tCONFIG=$(cat \"cfst_ddns.conf\")\n\tFOLDER=$(echo \"${CONFIG}\"|grep 'FOLDER='|awk -F '=' '{print $NF}')\n\t[[ -z \"${FOLDER}\" ]] && echo -e \"[错误] 缺少配置项 [FOLDER] !\" && exit 1\n\tZONE_ID=$(echo \"${CONFIG}\"|grep 'ZONE_ID='|awk -F '=' '{print $NF}')\n\t[[ -z \"${ZONE_ID}\" ]] && echo -e \"[错误] 缺少配置项 [ZONE_ID] !\" && exit 1\n\tDNS_RECORDS_ID=$(echo \"${CONFIG}\"|grep 'DNS_RECORDS_ID='|awk -F '=' '{print $NF}')\n\t[[ -z \"${DNS_RECORDS_ID}\" ]] && echo -e \"[错误] 缺少配置项 [DNS_RECORDS_ID] !\" && exit 1\n\tKEY=$(echo \"${CONFIG}\"|grep 'KEY='|awk -F '=' '{print $NF}')\n\t[[ -z \"${KEY}\" ]] && echo -e \"[错误] 缺少配置项 [KEY] !\" && exit 1\n\tEMAIL=$(echo \"${CONFIG}\"|grep 'EMAIL='|awk -F '=' '{print $NF}')\n\t[[ -z \"${EMAIL}\" ]] && echo -e \"[信息] 缺少配置项 [EMAIL]，由 [API 密钥] 方式转为 [API 令牌] 方式!\"\n\tTYPE=$(echo \"${CONFIG}\"|grep 'TYPE='|awk -F '=' '{print $NF}')\n\t[[ -z \"${TYPE}\" ]] && echo -e \"[错误] 缺少配置项 [TYPE] !\" && exit 1\n\tNAME=$(echo \"${CONFIG}\"|grep 'NAME='|awk -F '=' '{print $NF}')\n\t[[ -z \"${NAME}\" ]] && echo -e \"[错误] 缺少配置项 [NAME] !\" && exit 1\n\tTTL=$(echo \"${CONFIG}\"|grep 'TTL='|awk -F '=' '{print $NF}')\n\t[[ -z \"${TTL}\" ]] && echo -e \"[错误] 缺少配置项 [TTL] !\" && exit 1\n\tPROXIED=$(echo \"${CONFIG}\"|grep 'PROXIED='|awk -F '=' '{print $NF}')\n\t[[ -z \"${PROXIED}\" ]] && echo -e \"[错误] 缺少配置项 [PROXIED] !\" && exit 1\n}\n\n_UPDATE() {\n\t# 这里可以自己添加、修改 CFST 的运行参数\n\t./cfst -o \"result_ddns.txt\"\n\n\t# 判断结果文件是否存在，如果不存在说明结果为 0\n\t[[ ! -e \"result_ddns.txt\" ]] && echo \"CFST 测速结果 IP 数量为 0，跳过下面步骤...\" && exit 0\n\n\tCONTENT=$(sed -n \"2,1p\" result_ddns.txt | awk -F, '{print $1}')","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/XIU2/CloudflareSpeedTest/blob/1da0c025d7b6f9bf0b2b0cf47a547f65430deab2/script/cfst_ddns.sh#L5-L41","documentation":"This is informational, not fatal: when EMAIL is empty in cfst_ddns.conf, _READ() prints the [信息] message at script/cfst_ddns.sh:23 and continues. Empty EMAIL selects the API-token branch: _UPDATE() sends Authorization: Bearer ${KEY} (lines 54-59) instead of the X-Auth-Email/X-Auth-Key global-key pair (lines 47-53).","triggerScenarios":"EMAIL= line absent, commented, or empty in cfst_ddns.conf; the script never exits for this — it only switches the authentication mode of the Cloudflare API PUT.","commonSituations":"Intentional setup with a scoped API Token (no email needed); accidental omission when the user only has a Global API Key, which then fails later with HTTP 403/400 on the PUT because a global key was sent as a Bearer token.","solutions":["If you use an API Token: nothing to fix — verify the token has Zone -> DNS -> Edit rights on the zone and that KEY holds the token","If you use the Global API Key: add EMAIL=you@example.com and set KEY to the 37-character global key from My Profile -> API Tokens","Confirm the mode by checking which curl branch runs (Bearer vs X-Auth-* headers) or the Cloudflare API response"],"exampleFix":"# cfst_ddns.conf (before, token mode)\nEMAIL=\nKEY=<api-token>\n# (after, global-key mode)\nEMAIL=you@example.com\nKEY=<37-char-global-key>","handlingStrategy":"validation","validationCode":"email=$(grep '^EMAIL=' cfst_ddns.conf | head -1 | cut -d= -f2-)\nkey=$(grep '^KEY=' cfst_ddns.conf | head -1 | cut -d= -f2-)\n[ -z \"$email\" ] && echo 'token mode: KEY must be an API Token with Zone.DNS Edit' >&2\n[ -n \"$email\" ] && echo 'global-key mode: KEY must be the Global API Key' >&2","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick the auth mode deliberately: token mode = leave EMAIL empty; global-key mode = set both EMAIL and KEY","For tokens, create it with Zone -> DNS -> Edit scoped to the one zone, then verify with /user/tokens/verify","Test the exact curl the script will run (Bearer vs X-Auth-*) once before automating"],"tags":["shell","bash","cloudflare","ddns","configuration","authentication"],"backgroundTag":null,"analyzedSha":"1da0c025d7b6f9bf0b2b0cf47a547f65430deab2","analyzedAt":"2026-08-15T22:22:10.737Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}