package spark import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "encoding/json" "fmt" "io" "net/http" "net/url" "os" "strings" "time" "github.com/gorilla/websocket" ) var ( hostUrl = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image" appid = "XXXXXXXX" apiKey = "XXXXXXXXXXXXXXXXXXXXXXXX" apiSecret = "XXXXXXXXXXXXXXXXXXXXXXXX" ) func sparkImage() { d := websocket.Dialer{ HandshakeTimeout: 20 * time.Second, } conn, resp, err := d.Dial(assembleAuthUrl(hostUrl, apiKey, apiSecret), nil) if err != nil { panic(readResp(resp) + err.Error()) return } else if resp.StatusCode != 101 { panic(readResp(resp) + err.Error()) } //璇诲彇鍥剧墖 image, err := os.ReadFile("./1.png") messages := []Message{ {Role: "user", Content: base64.StdEncoding.EncodeToString(image), ContentType: "image"}, // 棣栨潯蹇呴』鏄浘鐗� {Role: "user", Content: "鍥剧墖鏈夊嚑涓汉", ContentType: "text"}, {Role: "assistant", Content: "鍥剧墖閲岄潰鏈変竴涓汉", ContentType: "text"}, {Role: "user", Content: "杩欎釜浜虹┛浠€涔堣。鏈�", ContentType: "text"}, } data := map[string]interface{}{ "header": map[string]interface{}{ "app_id": appid, }, "parameter": map[string]interface{}{ "chat": map[string]interface{}{ "domain": "imagev3", }, }, "payload": map[string]interface{}{ // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚� "message": map[string]interface{}{ // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚� "text": messages, // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚� }, }, } conn.WriteJSON(data) var answer = "" //鑾峰彇杩斿洖鐨勬暟鎹� for { _, msg, err := conn.ReadMessage() if err != nil { fmt.Println("read message error:", err) break } var data map[string]interface{} err1 := json.Unmarshal(msg, &data) if err1 != nil { fmt.Println("Error parsing JSON:", err) return } fmt.Println(string(msg)) //瑙f瀽鏁版嵁 payload := data["payload"].(map[string]interface{}) choices := payload["choices"].(map[string]interface{}) header := data["header"].(map[string]interface{}) code := header["code"].(float64) if code != 0 { fmt.Println(data["payload"]) return } status := choices["status"].(float64) fmt.Println(status) text := choices["text"].([]interface{}) content := text[0].(map[string]interface{})["content"].(string) if status != 2 { answer += content } else { fmt.Println("鏀跺埌鏈€缁堢粨鏋�") answer += content usage := payload["usage"].(map[string]interface{}) temp := usage["text"].(map[string]interface{}) totalTokens := temp["total_tokens"].(float64) fmt.Println("total_tokens:", totalTokens) conn.Close() break } } //杈撳嚭杩斿洖缁撴灉 fmt.Println(answer) time.Sleep(1 * time.Second) } // 鍒涘缓閴存潈url apikey 鍗� hmac username func assembleAuthUrl(hosturl string, apiKey, apiSecret string) string { ul, err := url.Parse(hosturl) if err != nil { fmt.Println(err) } //绛惧悕鏃堕棿 date := time.Now().UTC().Format(time.RFC1123) //date = "Tue, 28 May 2019 09:10:42 MST" //鍙備笌绛惧悕鐨勫瓧娈� host ,date, request-line signString := []string{"host: " + ul.Host, "date: " + date, "GET " + ul.Path + " HTTP/1.1"} //鎷兼帴绛惧悕瀛楃涓� sgin := strings.Join(signString, "\n") // fmt.Println(sgin) //绛惧悕缁撴灉 sha := HmacWithShaTobase64("hmac-sha256", sgin, apiSecret) // fmt.Println(sha) //鏋勫缓璇锋眰鍙傛暟 姝ゆ椂涓嶉渶瑕乽rlencoding authUrl := fmt.Sprintf("hmac username=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha) //灏嗚姹傚弬鏁颁娇鐢╞ase64缂栫爜 authorization := base64.StdEncoding.EncodeToString([]byte(authUrl)) v := url.Values{} v.Add("host", ul.Host) v.Add("date", date) v.Add("authorization", authorization) //灏嗙紪鐮佸悗鐨勫瓧绗︿覆url encode鍚庢坊鍔犲埌url鍚庨潰 callurl := hosturl + "?" + v.Encode() return callurl } func HmacWithShaTobase64(algorithm, data, key string) string { mac := hmac.New(sha256.New, []byte(key)) mac.Write([]byte(data)) encodeData := mac.Sum(nil) return base64.StdEncoding.EncodeToString(encodeData) } func readResp(resp *http.Response) string { if resp == nil { return "" } b, err := io.ReadAll(resp.Body) if err != nil { panic(err) } return fmt.Sprintf("code=%d,body=%s", resp.StatusCode, string(b)) } type Message struct { Role string `json:"role"` Content string `json:"content"` ContentType string `json:"content_type"` }