添加json解析

This commit is contained in:
DESKTOP-DDTRVOR\asus 2025-01-09 15:26:37 +08:00
parent 91aedfe56b
commit afd3bee6b7

View File

@ -1,9 +1,6 @@
package main package main
import ( import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -14,6 +11,7 @@ import (
openApiSdkClient "github.com/bytedance/douyin-openapi-sdk-go/client" openApiSdkClient "github.com/bytedance/douyin-openapi-sdk-go/client"
) )
// 定义抖音 API 响应的结构体
type APIResponse struct { type APIResponse struct {
BaseResp struct { BaseResp struct {
StatusCode int `json:"StatusCode"` StatusCode int `json:"StatusCode"`
@ -58,79 +56,12 @@ func GetAccessToken() (string, error) {
// 调用 SDK 获取 access_token // 调用 SDK 获取 access_token
sdkResponse, err := sdkClient.AppsV2Token(sdkRequest) sdkResponse, err := sdkClient.AppsV2Token(sdkRequest)
if err != nil { if err != nil {
fmt.Println("sdk call err:", err) return "", fmt.Errorf("SDK 调用失败: %v", err)
return "", nil
} }
fmt.Println("sdk数据", sdkResponse.Data)
// 返回 access_token // 返回 access_token
return *sdkResponse.Data.AccessToken, nil return *sdkResponse.Data.AccessToken, nil
} }
func DecryptAES128CBC(encryptedData, sessionKey, iv string) ([]byte, error) {
// Base64 解码 key 和 iv
aesKey, err := base64.StdEncoding.DecodeString(sessionKey)
if err != nil {
return nil, fmt.Errorf("sessionKey Base64 解码失败: %v", err)
}
initialVector, err := base64.StdEncoding.DecodeString(iv)
if err != nil {
return nil, fmt.Errorf("iv Base64 解码失败: %v", err)
}
// 检查 key 和 iv 长度是否为 16 字节
if len(aesKey) != 16 {
return nil, fmt.Errorf("AES key 长度必须为 16 字节")
}
if len(initialVector) != 16 {
return nil, fmt.Errorf("IV 长度必须为 16 字节")
}
// Base64 解码密文
ciphertext, err := base64.StdEncoding.DecodeString(encryptedData)
if err != nil {
return nil, fmt.Errorf("encryptedData Base64 解码失败: %v", err)
}
// 创建 AES 块
block, err := aes.NewCipher(aesKey)
if err != nil {
return nil, fmt.Errorf("创建 AES Cipher 失败: %v", err)
}
// 检查密文长度是否为块大小的倍数
if len(ciphertext)%aes.BlockSize != 0 {
return nil, fmt.Errorf("密文长度必须是 AES 块大小的倍数")
}
// 创建 CBC 解密器
mode := cipher.NewCBCDecrypter(block, initialVector)
// 解密数据
decrypted := make([]byte, len(ciphertext))
mode.CryptBlocks(decrypted, ciphertext)
// 去除 PKCS#7 填充
decrypted, err = PKCS7Unpad(decrypted)
if err != nil {
return nil, fmt.Errorf("去除 PKCS#7 填充失败: %v", err)
}
return decrypted, nil
}
// PKCS#7 填充去除函数
func PKCS7Unpad(data []byte) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, fmt.Errorf("解密后数据长度为 0")
}
padding := int(data[length-1])
if padding > length || padding == 0 {
return nil, fmt.Errorf("无效的填充数据")
}
return data[:length-padding], nil
}
func main() { func main() {
// 定义 HTTP 路由和处理函数 // 定义 HTTP 路由和处理函数
@ -142,25 +73,27 @@ func main() {
} }
// 从请求中获取参数 // 从请求中获取参数
openID := r.URL.Query().Get("open_id") // 获取 open_id openID := r.URL.Query().Get("open_id") // 获取 open_id 参数
mpID := r.URL.Query().Get("mp_id") // 获取 mp_id mpID := r.URL.Query().Get("mp_id") // 获取 mp_id 参数
dateHour := r.URL.Query().Get("date_hour") // 获取 date_hour dateHour := r.URL.Query().Get("date_hour") // 获取 date_hour 参数
pageNo := r.URL.Query().Get("pageNo") // 获取 date_hour pageNo := r.URL.Query().Get("pageNo") // 获取 pageNo 参数
pageSize := r.URL.Query().Get("pageSize") // 获取 date_hour pageSize := r.URL.Query().Get("pageSize") // 获取 pageSize 参数
// 检查是否缺少参数 // 检查是否缺少必要参数
if mpID == "" || dateHour == "" { if mpID == "" || dateHour == "" {
http.Error(w, "缺少必要的参数", http.StatusBadRequest) http.Error(w, "缺少必要的参数 mp_id 或 date_hour", http.StatusBadRequest)
return return
} }
// 动态获取 access_token
// 获取动态的 access_token
accessToken, err := GetAccessToken() accessToken, err := GetAccessToken()
apiURL := "https://minigame.zijieapi.com/mgplatform/api/apps/data/get_ecpm"
if err != nil { if err != nil {
http.Error(w, fmt.Sprintf("获取 access_token 失败: %v", err), http.StatusInternalServerError) http.Error(w, fmt.Sprintf("获取 access_token 失败: %v", err), http.StatusInternalServerError)
return return
} }
fmt.Println("动态token为", accessToken)
// 构造抖音 API 请求的 URL
apiURL := "https://minigame.zijieapi.com/mgplatform/api/apps/data/get_ecpm"
params := url.Values{} params := url.Values{}
params.Add("open_id", openID) params.Add("open_id", openID)
params.Add("mp_id", mpID) params.Add("mp_id", mpID)
@ -168,22 +101,10 @@ func main() {
params.Add("access_token", accessToken) params.Add("access_token", accessToken)
params.Add("page_no", pageNo) params.Add("page_no", pageNo)
params.Add("page_size", pageSize) params.Add("page_size", pageSize)
// 构造请求体
// requestBody := map[string]string{
// "open_id": openID,
// "mp_id": mpID,
// "date_hour": dateHour,
// "access_token": accessToken,
// "page_no": pageNo,
// "page_size": pageSize,
// }
fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode())
// requestBodyJSON, err := json.Marshal(requestBody) // 转为 JSON 格式
// if err != nil {
// http.Error(w, "请求体编码失败", http.StatusInternalServerError)
// return
// }
fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode())
// 调用抖音 API
resp, err := http.Get(fullURL) resp, err := http.Get(fullURL)
if err != nil { if err != nil {
http.Error(w, "调用抖音 API 失败", http.StatusInternalServerError) http.Error(w, "调用抖音 API 失败", http.StatusInternalServerError)
@ -191,22 +112,28 @@ func main() {
} }
defer resp.Body.Close() defer resp.Body.Close()
// 读取抖音 API 响应 // 读取抖音 API 响应数据
responseBody, err := ioutil.ReadAll(resp.Body) responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
http.Error(w, "读取抖音 API 响应失败", http.StatusInternalServerError) http.Error(w, "读取抖音 API 响应失败", http.StatusInternalServerError)
return return
} }
// 解析抖音 API 响应数据
var apiResponse APIResponse var apiResponse APIResponse
err = json.Unmarshal(responseBody, &apiResponse) err = json.Unmarshal(responseBody, &apiResponse)
if err != nil { if err != nil {
fmt.Printf("Error while parsing response JSON: %v\n", err) http.Error(w, "解析 API 响应数据失败", http.StatusInternalServerError)
return return
} }
// 检查 API 是否返回错误
if apiResponse.ErrNo != 0 { if apiResponse.ErrNo != 0 {
fmt.Printf("API Error: %s (ErrNo: %d)\n", apiResponse.ErrMsg, apiResponse.ErrNo) http.Error(w, fmt.Sprintf("抖音 API 返回错误: %s (错误码: %d)", apiResponse.ErrMsg, apiResponse.ErrNo), http.StatusInternalServerError)
return return
} }
// 计算 ECPM
totalCost := 0 totalCost := 0
totalRecords := len(apiResponse.Data.Records) totalRecords := len(apiResponse.Data.Records)
@ -214,75 +141,30 @@ func main() {
totalCost += record.Cost totalCost += record.Cost
} }
// 如果没有记录,则返回错误
if totalRecords == 0 { if totalRecords == 0 {
fmt.Println("No records found. Unable to calculate ECPM.") http.Error(w, "未找到记录,无法计算 ECPM", http.StatusOK)
return return
} }
ecpm := float64(totalCost) / 100000 * 1000 / float64(totalRecords) ecpm := float64(totalCost) / 100000 * 1000 / float64(totalRecords)
fmt.Println("返回值为", responseBody)
// 根据key返回相应的值这里可以替换为实际的业务逻辑 // 构造返回的 JSON 数据
value := fmt.Sprintf("Value for key '%s'", ecpm) result := map[string]interface{}{
// 将抖音 API 的响应返回给客户端 "total_cost": float64(totalCost) / 100000,
w.Header().Set("Content-Type", "application/json") "total_records": totalRecords,
w.WriteHeader(resp.StatusCode) "ecpm": ecpm,
w.Write([]byte(value))
})
http.HandleFunc("/Login", func(w http.ResponseWriter, r *http.Request) {
// 检查请求方法是否为GET
if r.Method != http.MethodGet {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
} }
resultJSON, err := json.Marshal(result)
// 从请求参数中获取"code"和"Anonymous"
code := r.URL.Query().Get("code")
Anonymous := r.URL.Query().Get("Anonymous")
fmt.Println("code:", code)
fmt.Println("Anonymous:", Anonymous)
// 参数校验
if code == "" {
http.Error(w, "Missing 'code' or 'Anonymous' parameter", http.StatusBadRequest)
return
}
// 初始化 SDK 客户端
opt := new(credential.Config).
SetClientKey("tt8b32fd8f14071db707").
SetClientSecret("44018e80b1bde34395a52de67ce1e0c37c572d80")
sdkClient, err := openApiSdkClient.NewClient(opt)
if err != nil { if err != nil {
fmt.Println("sdk init err:", err) http.Error(w, "生成返回 JSON 数据失败", http.StatusInternalServerError)
http.Error(w, "SDK 初始化失败", http.StatusInternalServerError)
return return
} }
// 构建请求参数 // 返回 JSON 格式的 ECPM 数据
sdkRequest := &openApiSdkClient.V2Jscode2sessionRequest{}
sdkRequest.SetAnonymousCode(Anonymous)
sdkRequest.SetAppid("tt8b32fd8f14071db707")
sdkRequest.SetCode(code)
sdkRequest.SetSecret("44018e80b1bde34395a52de67ce1e0c37c572d80")
// 调用 SDK
sdkResponse, err := sdkClient.V2Jscode2session(sdkRequest)
if err != nil {
fmt.Println("sdk call err:", err)
http.Error(w, "SDK 调用失败", http.StatusInternalServerError)
return
}
// 打印登录数据
fmt.Println("登录数据:", sdkResponse)
// 返回响应
value := fmt.Sprintf("Session Data: %v", sdkResponse.Data)
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(value)) w.Write(resultJSON)
}) })
// 启动 HTTP 服务器 // 启动 HTTP 服务器