From 66894a1e2bc0ead587b2e1370dd76988cfdbdf85 Mon Sep 17 00:00:00 2001 From: SebbeJohansson Date: Mon, 5 Jan 2026 00:01:57 +0100 Subject: [PATCH 1/3] First version of replacements for EMO --- README.md | 9 +++ emoProxy.conf.example | 3 +- emoProxy.go | 164 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 170 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 5664274..b7d99ce 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,12 @@ This part of the knowledge bank is a Proxy server to analyze the traffic that go ## Docker setup You can find a simplified setup using Docker Compose by SebbeJohansson here: https://github.com/SebbeJohansson/emo-proxy-docker It uses nginx, dnsmasq, and mitmproxy to be able to pass through the api requests to the EMO Proxy. + +## Experimental +### ChatGPT Speak server +One of the most common responses from EMO is to respond using ChatGPT. +An experimental feature is to use a local Speak server to generate EMO's chatgpt speak responses instead of using the living.ai servers. +You can find a proof of concept server here: https://github.com/SebbeJohansson/EmoChatGptSpeakPOC + +Connect the server by adding the following line to your emoProxy.conf file: +`"chatGptSpeakServer": "http://localhost:8085"` \ No newline at end of file diff --git a/emoProxy.conf.example b/emoProxy.conf.example index 031636d..9710c36 100644 --- a/emoProxy.conf.example +++ b/emoProxy.conf.example @@ -7,5 +7,6 @@ "postFS": "/tmp/", "logFileName": "/var/log/emoProxyss.log", "enableDatabaseAndAPI": false, # For now, default behavior is still without db and api. - "sqliteLocation": "/var/data/emo_logs.db" + "sqliteLocation": "/var/data/emo_logs.db", + "chatGptSpeakServer": "" } \ No newline at end of file diff --git a/emoProxy.go b/emoProxy.go index 633627b..e69bb25 100644 --- a/emoProxy.go +++ b/emoProxy.go @@ -9,6 +9,7 @@ import ( "io" "log" "net/http" + "net/url" "os" "strconv" "time" @@ -24,6 +25,53 @@ type emo_code struct { Errmessage string `json:"errmessage"` } +type Intent struct { + Name string `json:"name,omitempty"` + Confidence float64 `json:"confidence,omitempty"` +} + +type BehaviorParas struct { + UtilityType string `json:"utility_type,omitempty"` + Time []string `json:"time,omitempty"` + Txt string `json:"txt,omitempty"` + Url string `json:"url,omitempty"` + PreAnimation string `json:"pre_animation,omitempty"` + PostAnimation string `json:"post_animation,omitempty"` + PostBehavior string `json:"post_behavior,omitempty"` + RecBehavior string `json:"rec_behavior,omitempty"` + BehaviorParas *BehaviorParas `json:"behavior_paras,omitempty"` + Sentiment string `json:"sentiment,omitempty"` + Listen int `json:"listen,omitempty"` + AnimationName string `json:"animation_name,omitempty"` +} + +type QueryResult struct { + ResultCode string `json:"resultCode,omitempty"` + QueryText string `json:"queryText,omitempty"` + Intent *Intent `json:"intent,omitempty"` + RecBehavior string `json:"rec_behavior,omitempty"` + BehaviorParas *BehaviorParas `json:"behavior_paras,omitempty"` +} + +type QueryResponse struct { + QueryId string `json:"queryId,omitempty"` + QueryResult *QueryResult `json:"queryResult,omitempty"` + LanguageCode string `json:"languageCode,omitempty"` + Index int `json:"index,omitempty"` +} + +type TokenResponse struct { + AccessToken string `json:"access_token,omitempty"` + ExpireIn int `json:"expire_in,omitempty"` + Type string `json:"type,omitempty"` +} + +type EmoSpeechResponse struct { + Code int64 `json:"code"` + Errmessage string `json:"errmessage"` + Url string `json:"url"` +} + type Configuration struct { PidFile string `json:"pidFile"` Livingio_API_Server string `json:"livingio_api_server"` @@ -34,6 +82,7 @@ type Configuration struct { LogFileName string `json:"logFileName"` EnableDatabaseAndAPI bool `json:"enableDatabaseAndAPI"` SqliteLocation string `json:"sqliteLocation"` + ChatGptSpeakServer string `json:"chatGptSpeakServer"` } var ( @@ -105,6 +154,7 @@ func loadConfig(filename string) error { LogFileName: "/var/log/emoProxy.log", EnableDatabaseAndAPI: false, SqliteLocation: "/var/data/emo_logs.db", + ChatGptSpeakServer: "", } bytes, err := os.ReadFile(filename) @@ -315,6 +365,29 @@ func makeApiRequest(r *http.Request) string { body, _ := io.ReadAll(response.Body) log.Println("Server response: ", string(body)) + typedBody := QueryResponse{} + decoder := json.NewDecoder(bytes.NewReader([]byte(body))) + decoder.DisallowUnknownFields() + + err = decoder.Decode(&typedBody) + if err != nil { + log.Println("Error when decoding JSON (", string(body), ") will return unhandled:", err) + } else { + if typedBody.QueryId != "" { + if typedBody.QueryResult.Intent.Name == "chatgpt_speak" && conf.ChatGptSpeakServer != "" { + speakResponse := makeChatGptSpeakRequest(typedBody.QueryResult.QueryText, typedBody.LanguageCode, typedBody.QueryResult.BehaviorParas.Txt, r) + if speakResponse.Url != "" && speakResponse.Txt != "" { + log.Println("Successfully replaced chatgpt_speak response for request.") + typedBody.QueryResult.BehaviorParas.Url = speakResponse.Url + typedBody.QueryResult.BehaviorParas.Txt = speakResponse.Txt + } else { + log.Println("Failed to get valid response from ChatGptSpeakServer, keeping original response.") + } + } + body, _ = json.Marshal(typedBody) + } + } + logResponse(response) if useDatabaseAndAPI { @@ -346,10 +419,8 @@ func makeTtsRequest(r *http.Request) string { } defer response.Body.Close() - // read response body, _ := io.ReadAll(response.Body) - // write post request body to fs logBody(response.Header.Get("Content-Type"), body, "tts_") logResponse(response) @@ -382,10 +453,8 @@ func makeApiTtsRequest(r *http.Request) string { } defer response.Body.Close() - // read response body, _ := io.ReadAll(response.Body) - // write post request body to fs logBody(response.Header.Get("Content-Type"), body, "apitts_") logResponse(response) @@ -418,7 +487,6 @@ func makeResRequest(r *http.Request, w http.ResponseWriter) string { } defer response.Body.Close() - // read response body, _ := io.ReadAll(response.Body) logBody(response.Header.Get("Content-Type"), body, "res_") @@ -434,3 +502,89 @@ func makeResRequest(r *http.Request, w http.ResponseWriter) string { } return string(body) } + +func makeEmoSpeechRequest(text string, languageCode string, r *http.Request) EmoSpeechResponse { + request, _ := http.NewRequest("GET", "https://"+conf.Livingio_API_Server+"/emo/speech/tts?q="+url.QueryEscape(text)+"&l="+url.QueryEscape(languageCode), nil) + + val, exists := r.Header["Authorization"] + if exists { + request.Header.Add("Authorization", val[0]) + } + + val, exists = r.Header["Secret"] + if exists { + request.Header.Add("Secret", val[0]) + } + + request.Header.Del("User-Agent") + + httpclient := &http.Client{} + response, err := httpclient.Do(request) + + if err != nil { + log.Fatalf("An Error Occured %v", err) + } + defer response.Body.Close() + + body, _ := io.ReadAll(response.Body) + + var emoSpeechResponse EmoSpeechResponse + if err := json.Unmarshal([]byte(body), &emoSpeechResponse); err != nil { + log.Printf("Error unmarshaling ChatGptSpeakServer response: %v\n", err) + return EmoSpeechResponse{} + } + + return emoSpeechResponse +} + +func makeChatGptSpeakRequest(queryText string, languageCode string, fallbackResponse string, r *http.Request) BehaviorParas { + type ChatGptSpeakRequest struct { + QueryText string `json:"queryText"` + LanguageCode string `json:"languageCode"` + FallbackResponse string `json:"fallbackResponse,omitempty"` + } + type ChatGptSpeakResponse struct { + ResponseText string `json:"responseText"` + } + + chatGptRequestData := ChatGptSpeakRequest{ + QueryText: queryText, + LanguageCode: languageCode, + FallbackResponse: fallbackResponse, + } + chatGptRequestBody, _ := json.Marshal(chatGptRequestData) + chatGptRequest, _ := http.NewRequest("POST", conf.ChatGptSpeakServer+"/speak", bytes.NewBuffer(chatGptRequestBody)) + chatGptRequest.Header.Add("Content-Type", "application/json") + + chatGptClient := &http.Client{} + chatGptResponse, err := chatGptClient.Do(chatGptRequest) + if err != nil { + log.Fatalf("An Error Occured while calling ChatGptSpeakServer %v", err) + } + defer chatGptResponse.Body.Close() + + chatGptResponseBody, _ := io.ReadAll(chatGptResponse.Body) + + var chatGptTypedResponse ChatGptSpeakResponse + if err := json.Unmarshal([]byte(chatGptResponseBody), &chatGptTypedResponse); err != nil { + log.Printf("Error unmarshaling ChatGptSpeakServer response: %v\n", err) + return BehaviorParas{} + } + + if chatGptTypedResponse.ResponseText == "" { + log.Println("ChatGptSpeakServer returned empty response text") + return BehaviorParas{} + } + + emoSpeechResponse := makeEmoSpeechRequest(chatGptTypedResponse.ResponseText, languageCode, r) + if emoSpeechResponse.Code != 200 || emoSpeechResponse.Url == "" { + log.Printf("Error in EmoSpeechResponse: Code %d, Errmessage: %s\n", emoSpeechResponse.Code, emoSpeechResponse.Errmessage) + return BehaviorParas{} + } + behaviorParasResponse := BehaviorParas{ + Txt: chatGptTypedResponse.ResponseText, + Url: emoSpeechResponse.Url, + } + + return behaviorParasResponse +} From e24cfd8377aaf33fccf399c85d88bb7e886fd983 Mon Sep 17 00:00:00 2001 From: SebbeJohansson Date: Mon, 5 Jan 2026 00:34:49 +0100 Subject: [PATCH 2/3] Refactoring --- emoProxy.conf.example | 2 + emoProxy.go | 162 ++---------------------------------------- replacements.go | 130 +++++++++++++++++++++++++++++++++ types.go | 48 +++++++++++++ 4 files changed, 186 insertions(+), 156 deletions(-) create mode 100644 replacements.go create mode 100644 types.go diff --git a/emoProxy.conf.example b/emoProxy.conf.example index 9710c36..91de709 100644 --- a/emoProxy.conf.example +++ b/emoProxy.conf.example @@ -7,6 +7,8 @@ "postFS": "/tmp/", "logFileName": "/var/log/emoProxyss.log", "enableDatabaseAndAPI": false, # For now, default behavior is still without db and api. + "enableReplacements": false, # For now, default behavior is still without replacements. + "sqliteLocation": "/var/data/emo_logs.db", "chatGptSpeakServer": "" } \ No newline at end of file diff --git a/emoProxy.go b/emoProxy.go index e69bb25..3ecef4c 100644 --- a/emoProxy.go +++ b/emoProxy.go @@ -9,7 +9,6 @@ import ( "io" "log" "net/http" - "net/url" "os" "strconv" "time" @@ -25,53 +24,6 @@ type emo_code struct { Errmessage string `json:"errmessage"` } -type Intent struct { - Name string `json:"name,omitempty"` - Confidence float64 `json:"confidence,omitempty"` -} - -type BehaviorParas struct { - UtilityType string `json:"utility_type,omitempty"` - Time []string `json:"time,omitempty"` - Txt string `json:"txt,omitempty"` - Url string `json:"url,omitempty"` - PreAnimation string `json:"pre_animation,omitempty"` - PostAnimation string `json:"post_animation,omitempty"` - PostBehavior string `json:"post_behavior,omitempty"` - RecBehavior string `json:"rec_behavior,omitempty"` - BehaviorParas *BehaviorParas `json:"behavior_paras,omitempty"` - Sentiment string `json:"sentiment,omitempty"` - Listen int `json:"listen,omitempty"` - AnimationName string `json:"animation_name,omitempty"` -} - -type QueryResult struct { - ResultCode string `json:"resultCode,omitempty"` - QueryText string `json:"queryText,omitempty"` - Intent *Intent `json:"intent,omitempty"` - RecBehavior string `json:"rec_behavior,omitempty"` - BehaviorParas *BehaviorParas `json:"behavior_paras,omitempty"` -} - -type QueryResponse struct { - QueryId string `json:"queryId,omitempty"` - QueryResult *QueryResult `json:"queryResult,omitempty"` - LanguageCode string `json:"languageCode,omitempty"` - Index int `json:"index,omitempty"` -} - -type TokenResponse struct { - AccessToken string `json:"access_token,omitempty"` - ExpireIn int `json:"expire_in,omitempty"` - Type string `json:"type,omitempty"` -} - -type EmoSpeechResponse struct { - Code int64 `json:"code"` - Errmessage string `json:"errmessage"` - Url string `json:"url"` -} - type Configuration struct { PidFile string `json:"pidFile"` Livingio_API_Server string `json:"livingio_api_server"` @@ -81,6 +33,7 @@ type Configuration struct { PostFS string `json:"postFS"` LogFileName string `json:"logFileName"` EnableDatabaseAndAPI bool `json:"enableDatabaseAndAPI"` + EnableReplacements bool `json:"enableReplacements"` SqliteLocation string `json:"sqliteLocation"` ChatGptSpeakServer string `json:"chatGptSpeakServer"` } @@ -153,6 +106,7 @@ func loadConfig(filename string) error { PostFS: "/tmp/", LogFileName: "/var/log/emoProxy.log", EnableDatabaseAndAPI: false, + EnableReplacements: false, SqliteLocation: "/var/data/emo_logs.db", ChatGptSpeakServer: "", } @@ -365,31 +319,13 @@ func makeApiRequest(r *http.Request) string { body, _ := io.ReadAll(response.Body) log.Println("Server response: ", string(body)) - typedBody := QueryResponse{} - decoder := json.NewDecoder(bytes.NewReader([]byte(body))) - decoder.DisallowUnknownFields() + logResponse(response) - err = decoder.Decode(&typedBody) - if err != nil { - log.Println("Error when decoding JSON (", string(body), ") will return unhandled:", err) - } else { - if typedBody.QueryId != "" { - if typedBody.QueryResult.Intent.Name == "chatgpt_speak" && conf.ChatGptSpeakServer != "" { - speakResponse := makeChatGptSpeakRequest(typedBody.QueryResult.QueryText, typedBody.LanguageCode, typedBody.QueryResult.BehaviorParas.Txt, r) - if speakResponse.Url != "" && speakResponse.Txt != "" { - log.Println("Successfully replaced chatgpt_speak response for request.") - typedBody.QueryResult.BehaviorParas.Url = speakResponse.Url - typedBody.QueryResult.BehaviorParas.Txt = speakResponse.Txt - } else { - log.Println("Failed to get valid response from ChatGptSpeakServer, keeping original response.") - } - } - body, _ = json.Marshal(typedBody) - } + if conf.EnableReplacements { + log.Println("Replacements enabled, checking for replacements...") + body = runReplacementsAndReturnModifiedBody(body) } - logResponse(response) - if useDatabaseAndAPI { saveRequest(r.URL.RequestURI(), string(requestBody), string(body)) } @@ -502,89 +438,3 @@ func makeResRequest(r *http.Request, w http.ResponseWriter) string { } return string(body) } - -func makeEmoSpeechRequest(text string, languageCode string, r *http.Request) EmoSpeechResponse { - request, _ := http.NewRequest("GET", "https://"+conf.Livingio_API_Server+"/emo/speech/tts?q="+url.QueryEscape(text)+"&l="+url.QueryEscape(languageCode), nil) - - val, exists := r.Header["Authorization"] - if exists { - request.Header.Add("Authorization", val[0]) - } - - val, exists = r.Header["Secret"] - if exists { - request.Header.Add("Secret", val[0]) - } - - request.Header.Del("User-Agent") - - httpclient := &http.Client{} - response, err := httpclient.Do(request) - - if err != nil { - log.Fatalf("An Error Occured %v", err) - } - defer response.Body.Close() - - body, _ := io.ReadAll(response.Body) - - var emoSpeechResponse EmoSpeechResponse - if err := json.Unmarshal([]byte(body), &emoSpeechResponse); err != nil { - log.Printf("Error unmarshaling ChatGptSpeakServer response: %v\n", err) - return EmoSpeechResponse{} - } - - return emoSpeechResponse -} - -func makeChatGptSpeakRequest(queryText string, languageCode string, fallbackResponse string, r *http.Request) BehaviorParas { - type ChatGptSpeakRequest struct { - QueryText string `json:"queryText"` - LanguageCode string `json:"languageCode"` - FallbackResponse string `json:"fallbackResponse,omitempty"` - } - type ChatGptSpeakResponse struct { - ResponseText string `json:"responseText"` - } - - chatGptRequestData := ChatGptSpeakRequest{ - QueryText: queryText, - LanguageCode: languageCode, - FallbackResponse: fallbackResponse, - } - chatGptRequestBody, _ := json.Marshal(chatGptRequestData) - chatGptRequest, _ := http.NewRequest("POST", conf.ChatGptSpeakServer+"/speak", bytes.NewBuffer(chatGptRequestBody)) - chatGptRequest.Header.Add("Content-Type", "application/json") - - chatGptClient := &http.Client{} - chatGptResponse, err := chatGptClient.Do(chatGptRequest) - if err != nil { - log.Fatalf("An Error Occured while calling ChatGptSpeakServer %v", err) - } - defer chatGptResponse.Body.Close() - - chatGptResponseBody, _ := io.ReadAll(chatGptResponse.Body) - - var chatGptTypedResponse ChatGptSpeakResponse - if err := json.Unmarshal([]byte(chatGptResponseBody), &chatGptTypedResponse); err != nil { - log.Printf("Error unmarshaling ChatGptSpeakServer response: %v\n", err) - return BehaviorParas{} - } - - if chatGptTypedResponse.ResponseText == "" { - log.Println("ChatGptSpeakServer returned empty response text") - return BehaviorParas{} - } - - emoSpeechResponse := makeEmoSpeechRequest(chatGptTypedResponse.ResponseText, languageCode, r) - if emoSpeechResponse.Code != 200 || emoSpeechResponse.Url == "" { - log.Printf("Error in EmoSpeechResponse: Code %d, Errmessage: %s\n", emoSpeechResponse.Code, emoSpeechResponse.Errmessage) - return BehaviorParas{} - } - behaviorParasResponse := BehaviorParas{ - Txt: chatGptTypedResponse.ResponseText, - Url: emoSpeechResponse.Url, - } - - return behaviorParasResponse -} diff --git a/replacements.go b/replacements.go new file mode 100644 index 0000000..4f7a674 --- /dev/null +++ b/replacements.go @@ -0,0 +1,130 @@ +package main + +import ( + "bytes" + "encoding/json" + "io" + "log" + "net/http" + "net/url" +) + +func runReplacementsAndReturnModifiedBody(body []byte) []byte { + typedBody := QueryResponse{} + decoder := json.NewDecoder(bytes.NewReader(body)) + decoder.DisallowUnknownFields() + + err := decoder.Decode(&typedBody) + if err != nil { + log.Println("Error when decoding JSON (", string(body), ") will return unhandled:", err) + return body + } else { + if typedBody.QueryResult == nil || typedBody.QueryId == "" { + log.Println("Unexpected query response, will return unhandled.") + return body + } + + if typedBody.QueryResult.Intent.Name == "chatgpt_speak" && conf.ChatGptSpeakServer != "" { + speakResponse := makeChatGptSpeakRequest(typedBody.QueryResult.QueryText, typedBody.LanguageCode, typedBody.QueryResult.BehaviorParas.Txt, r) + if speakResponse.Url != "" && speakResponse.Txt != "" { + log.Println("Successfully replaced chatgpt_speak response for request.") + typedBody.QueryResult.BehaviorParas.Url = speakResponse.Url + typedBody.QueryResult.BehaviorParas.Txt = speakResponse.Txt + } else { + log.Println("Failed to get valid response from ChatGptSpeakServer, keeping original response.") + } + } + modifiedBody, err := json.Marshal(typedBody) + if err != nil { + log.Println("Error when marshaling modified JSON, will return unhandled:", err) + return body + } + return modifiedBody + } +} + +func makeEmoSpeechRequest(text string, languageCode string, r *http.Request) EmoSpeechResponse { + request, _ := http.NewRequest("GET", "https://"+conf.Livingio_API_Server+"/emo/speech/tts?q="+url.QueryEscape(text)+"&l="+url.QueryEscape(languageCode), nil) + + val, exists := r.Header["Authorization"] + if exists { + request.Header.Add("Authorization", val[0]) + } + + val, exists = r.Header["Secret"] + if exists { + request.Header.Add("Secret", val[0]) + } + + request.Header.Del("User-Agent") + + httpclient := &http.Client{} + response, err := httpclient.Do(request) + + if err != nil { + log.Fatalf("An Error Occured %v", err) + } + defer response.Body.Close() + + body, _ := io.ReadAll(response.Body) + + var emoSpeechResponse EmoSpeechResponse + if err := json.Unmarshal([]byte(body), &emoSpeechResponse); err != nil { + log.Printf("Error unmarshaling ChatGptSpeakServer response: %v\n", err) + return EmoSpeechResponse{} + } + + return emoSpeechResponse +} + +func makeChatGptSpeakRequest(queryText string, languageCode string, fallbackResponse string, r *http.Request) BehaviorParas { + type ChatGptSpeakRequest struct { + QueryText string `json:"queryText"` + LanguageCode string `json:"languageCode"` + FallbackResponse string `json:"fallbackResponse,omitempty"` + } + type ChatGptSpeakResponse struct { + ResponseText string `json:"responseText"` + } + + chatGptRequestData := ChatGptSpeakRequest{ + QueryText: queryText, + LanguageCode: languageCode, + FallbackResponse: fallbackResponse, + } + chatGptRequestBody, _ := json.Marshal(chatGptRequestData) + chatGptRequest, _ := http.NewRequest("POST", conf.ChatGptSpeakServer+"/speak", bytes.NewBuffer(chatGptRequestBody)) + chatGptRequest.Header.Add("Content-Type", "application/json") + + chatGptClient := &http.Client{} + chatGptResponse, err := chatGptClient.Do(chatGptRequest) + if err != nil { + log.Fatalf("An Error Occured while calling ChatGptSpeakServer %v", err) + } + defer chatGptResponse.Body.Close() + + chatGptResponseBody, _ := io.ReadAll(chatGptResponse.Body) + + var chatGptTypedResponse ChatGptSpeakResponse + if err := json.Unmarshal([]byte(chatGptResponseBody), &chatGptTypedResponse); err != nil { + log.Printf("Error unmarshaling ChatGptSpeakServer response: %v\n", err) + return BehaviorParas{} + } + + if chatGptTypedResponse.ResponseText == "" { + log.Println("ChatGptSpeakServer returned empty response text") + return BehaviorParas{} + } + + emoSpeechResponse := makeEmoSpeechRequest(chatGptTypedResponse.ResponseText, languageCode, r) + if emoSpeechResponse.Code != 200 || emoSpeechResponse.Url == "" { + log.Printf("Error in EmoSpeechResponse: Code %d, Errmessage: %s\n", emoSpeechResponse.Code, emoSpeechResponse.Errmessage) + return BehaviorParas{} + } + behaviorParasResponse := BehaviorParas{ + Txt: chatGptTypedResponse.ResponseText, + Url: emoSpeechResponse.Url, + } + + return behaviorParasResponse +} diff --git a/types.go b/types.go new file mode 100644 index 0000000..8e20399 --- /dev/null +++ b/types.go @@ -0,0 +1,48 @@ +package main + +type Intent struct { + Name string `json:"name,omitempty"` + Confidence float64 `json:"confidence,omitempty"` +} + +type BehaviorParas struct { + UtilityType string `json:"utility_type,omitempty"` + Time []string `json:"time,omitempty"` + Txt string `json:"txt,omitempty"` + Url string `json:"url,omitempty"` + PreAnimation string `json:"pre_animation,omitempty"` + PostAnimation string `json:"post_animation,omitempty"` + PostBehavior string `json:"post_behavior,omitempty"` + RecBehavior string `json:"rec_behavior,omitempty"` + BehaviorParas *BehaviorParas `json:"behavior_paras,omitempty"` + Sentiment string `json:"sentiment,omitempty"` + Listen int `json:"listen,omitempty"` + AnimationName string `json:"animation_name,omitempty"` +} + +type QueryResult struct { + ResultCode string `json:"resultCode,omitempty"` + QueryText string `json:"queryText,omitempty"` + Intent *Intent `json:"intent,omitempty"` + RecBehavior string `json:"rec_behavior,omitempty"` + BehaviorParas *BehaviorParas `json:"behavior_paras,omitempty"` +} + +type QueryResponse struct { + QueryId string `json:"queryId,omitempty"` + QueryResult *QueryResult `json:"queryResult,omitempty"` + LanguageCode string `json:"languageCode,omitempty"` + Index int `json:"index,omitempty"` +} + +type TokenResponse struct { + AccessToken string `json:"access_token,omitempty"` + ExpireIn int `json:"expire_in,omitempty"` + Type string `json:"type,omitempty"` +} + +type EmoSpeechResponse struct { + Code int64 `json:"code"` + Errmessage string `json:"errmessage"` + Url string `json:"url"` +} From 5a6bef216a6b6f1de3d35c9918136a545a438f07 Mon Sep 17 00:00:00 2001 From: SebbeJohansson Date: Mon, 5 Jan 2026 00:38:50 +0100 Subject: [PATCH 3/3] fixed so that it builds --- emoProxy.go | 2 +- replacements.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emoProxy.go b/emoProxy.go index 3ecef4c..6392d09 100644 --- a/emoProxy.go +++ b/emoProxy.go @@ -323,7 +323,7 @@ func makeApiRequest(r *http.Request) string { if conf.EnableReplacements { log.Println("Replacements enabled, checking for replacements...") - body = runReplacementsAndReturnModifiedBody(body) + body = runReplacementsAndReturnModifiedBody(body, r) } if useDatabaseAndAPI { diff --git a/replacements.go b/replacements.go index 4f7a674..a88dab3 100644 --- a/replacements.go +++ b/replacements.go @@ -9,7 +9,7 @@ import ( "net/url" ) -func runReplacementsAndReturnModifiedBody(body []byte) []byte { +func runReplacementsAndReturnModifiedBody(body []byte, r *http.Request) []byte { typedBody := QueryResponse{} decoder := json.NewDecoder(bytes.NewReader(body)) decoder.DisallowUnknownFields()