package main import ( "encoding/json" "fmt" "io" "log" "net/http" "strings" ) // NameSiloAPIResponse 严格对应你提供的 JSON 返回 type NameSiloAPIResponse struct { Request struct { Operation string `json:"operation"` IP string `json:"ip"` } `json:"request"` Reply struct { Code int `json:"code"` Detail string `json:"detail"` ResourceRecords []struct { RecordID string `json:"record_id"` Type string `json:"type"` Host string `json:"host"` Value string `json:"value"` TTL int `json:"ttl"` // JSON 中显示为数字 Distance int `json:"distance"` // JSON 中显示为数字 0 } `json:"resource_record"` } `json:"reply"` } // RetrieveDNSRecords 使用 Namesilo API 获取指定域名的所有 DNS 记录 func RetrieveDNSRecords(apiKey, domain string) (*NameSiloAPIResponse, error) { url := fmt.Sprintf("https://www.namesilo.com/api/dnsListRecords?version=1&type=json&key=%s&domain=%s", apiKey, domain) // log.Println("Requesting URL:", url) // 调试用,如果需要隐藏 Key 请注释 resp, err := http.Get(url) if err != nil { return nil, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } var apiResponse NameSiloAPIResponse if err := json.Unmarshal(body, &apiResponse); err != nil { log.Printf("JSON 解析错误: %v\n原始数据: %s\n", err, string(body)) return nil, err } return &apiResponse, nil } // FetchSubdomainRecord 获取指定子域名的 DNS 记录 ID // Subdomain 参数通常是完整域名,如 "v6.aixiao.me" func FetchSubdomainRecord(key string, domain string, Subdomain string) string { // 获取 DNS 记录列表 response, err := RetrieveDNSRecords(key, domain) if err != nil { log.Println("获取 DNS 记录网络请求失败:", err) return "NULL" } // 检查 API 返回码 if response.Reply.Code != 300 { log.Printf("NameSilo API 错误: Code %d, Detail: %s\n", response.Reply.Code, response.Reply.Detail) return "NULL" } // 计算主机头 (Host Prefix) // 如果 Subdomain 是 "v6.aixiao.me",Domain 是 "aixiao.me" // 那么我们需要匹配的 Host 应该是 "v6" targetHost := Subdomain if strings.HasSuffix(Subdomain, "."+domain) { targetHost = strings.TrimSuffix(Subdomain, "."+domain) } // 遍历查找 for _, record := range response.Reply.ResourceRecords { // 1. 匹配主机名 (Host) // 2. 匹配记录类型 (Type) 必须为 AAAA (IPv6) if record.Host == targetHost && record.Type == "AAAA" { log.Printf("匹配成功! RecordID: %s | Host: %s | Type: %s | Current Value: %s\n", record.RecordID, record.Host, record.Type, record.Value) return record.RecordID } } log.Printf("未在 NameSilo 找到主机头为 [%s] 的 AAAA 记录。\n", targetHost) log.Println("请检查 NameSilo 后台是否已手动创建了该域名的 AAAA 记录。") return "NULL" }