172 lines
4.7 KiB
Go
172 lines
4.7 KiB
Go
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: 5 * time.Second,
|
||
}
|
||
//鎻℃墜骞跺缓绔媤ebsocket 杩炴帴
|
||
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"}, // 棣栨潯蹇呴』鏄浘鐗<E6B598>
|
||
{Role: "user", Content: "鍥剧墖鏈夊嚑涓汉", ContentType: "text"},
|
||
{Role: "assistant", Content: "鍥剧墖閲岄潰鏈変竴涓汉", ContentType: "text"},
|
||
{Role: "user", Content: "杩欎釜浜虹┛浠€涔堣。鏈<E38082>", 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{}{ // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚<EE868C>
|
||
"message": map[string]interface{}{ // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚<EE868C>
|
||
"text": messages, // 鏍规嵁瀹為檯鎯呭喌淇敼杩斿洖鐨勬暟鎹粨鏋勫拰瀛楁鍚<EE868C>
|
||
},
|
||
},
|
||
}
|
||
conn.WriteJSON(data)
|
||
|
||
var answer = ""
|
||
//鑾峰彇杩斿洖鐨勬暟鎹<E69A9F>
|
||
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("鏀跺埌鏈€缁堢粨鏋<E7B2A8>")
|
||
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"
|
||
//鍙備笌绛惧悕鐨勫瓧娈<E793A7> host ,date, request-line
|
||
signString := []string{"host: " + ul.Host, "date: " + date, "GET " + ul.Path + " HTTP/1.1"}
|
||
//鎷兼帴绛惧悕瀛楃涓<EE8381>
|
||
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"`
|
||
}
|