99 "io"
1010 "log"
1111 "net/http"
12+ "net/url"
1213 "os"
1314 "strconv"
1415 "time"
@@ -24,6 +25,53 @@ type emo_code struct {
2425 Errmessage string `json:"errmessage"`
2526}
2627
28+ type Intent struct {
29+ Name string `json:"name,omitempty"`
30+ Confidence float64 `json:"confidence,omitempty"`
31+ }
32+
33+ type BehaviorParas struct {
34+ UtilityType string `json:"utility_type,omitempty"`
35+ Time []string `json:"time,omitempty"`
36+ Txt string `json:"txt,omitempty"`
37+ Url string `json:"url,omitempty"`
38+ PreAnimation string `json:"pre_animation,omitempty"`
39+ PostAnimation string `json:"post_animation,omitempty"`
40+ PostBehavior string `json:"post_behavior,omitempty"`
41+ RecBehavior string `json:"rec_behavior,omitempty"`
42+ BehaviorParas * BehaviorParas `json:"behavior_paras,omitempty"`
43+ Sentiment string `json:"sentiment,omitempty"`
44+ Listen int `json:"listen,omitempty"`
45+ AnimationName string `json:"animation_name,omitempty"`
46+ }
47+
48+ type QueryResult struct {
49+ ResultCode string `json:"resultCode,omitempty"`
50+ QueryText string `json:"queryText,omitempty"`
51+ Intent * Intent `json:"intent,omitempty"`
52+ RecBehavior string `json:"rec_behavior,omitempty"`
53+ BehaviorParas * BehaviorParas `json:"behavior_paras,omitempty"`
54+ }
55+
56+ type QueryResponse struct {
57+ QueryId string `json:"queryId,omitempty"`
58+ QueryResult * QueryResult `json:"queryResult,omitempty"`
59+ LanguageCode string `json:"languageCode,omitempty"`
60+ Index int `json:"index,omitempty"`
61+ }
62+
63+ type TokenResponse struct {
64+ AccessToken string `json:"access_token,omitempty"`
65+ ExpireIn int `json:"expire_in,omitempty"`
66+ Type string `json:"type,omitempty"`
67+ }
68+
69+ type EmoSpeechResponse struct {
70+ Code int64 `json:"code"`
71+ Errmessage string `json:"errmessage"`
72+ Url string `json:"url"`
73+ }
74+
2775type Configuration struct {
2876 PidFile string `json:"pidFile"`
2977 Livingio_API_Server string `json:"livingio_api_server"`
@@ -34,6 +82,7 @@ type Configuration struct {
3482 LogFileName string `json:"logFileName"`
3583 EnableDatabaseAndAPI bool `json:"enableDatabaseAndAPI"`
3684 SqliteLocation string `json:"sqliteLocation"`
85+ ChatGptSpeakServer string `json:"chatGptSpeakServer"`
3786}
3887
3988var (
@@ -105,6 +154,7 @@ func loadConfig(filename string) error {
105154 LogFileName : "/var/log/emoProxy.log" ,
106155 EnableDatabaseAndAPI : false ,
107156 SqliteLocation : "/var/data/emo_logs.db" ,
157+ ChatGptSpeakServer : "" ,
108158 }
109159
110160 bytes , err := os .ReadFile (filename )
@@ -315,6 +365,29 @@ func makeApiRequest(r *http.Request) string {
315365 body , _ := io .ReadAll (response .Body )
316366 log .Println ("Server response: " , string (body ))
317367
368+ typedBody := QueryResponse {}
369+ decoder := json .NewDecoder (bytes .NewReader ([]byte (body )))
370+ decoder .DisallowUnknownFields ()
371+
372+ err = decoder .Decode (& typedBody )
373+ if err != nil {
374+ log .Println ("Error when decoding JSON (" , string (body ), ") will return unhandled:" , err )
375+ } else {
376+ if typedBody .QueryId != "" {
377+ if typedBody .QueryResult .Intent .Name == "chatgpt_speak" && conf .ChatGptSpeakServer != "" {
378+ speakResponse := makeChatGptSpeakRequest (typedBody .QueryResult .QueryText , typedBody .LanguageCode , typedBody .QueryResult .BehaviorParas .Txt , r )
379+ if speakResponse .Url != "" && speakResponse .Txt != "" {
380+ log .Println ("Successfully replaced chatgpt_speak response for request." )
381+ typedBody .QueryResult .BehaviorParas .Url = speakResponse .Url
382+ typedBody .QueryResult .BehaviorParas .Txt = speakResponse .Txt
383+ } else {
384+ log .Println ("Failed to get valid response from ChatGptSpeakServer, keeping original response." )
385+ }
386+ }
387+ body , _ = json .Marshal (typedBody )
388+ }
389+ }
390+
318391 logResponse (response )
319392
320393 if useDatabaseAndAPI {
@@ -346,10 +419,8 @@ func makeTtsRequest(r *http.Request) string {
346419 }
347420 defer response .Body .Close ()
348421
349- // read response
350422 body , _ := io .ReadAll (response .Body )
351423
352- // write post request body to fs
353424 logBody (response .Header .Get ("Content-Type" ), body , "tts_" )
354425 logResponse (response )
355426
@@ -382,10 +453,8 @@ func makeApiTtsRequest(r *http.Request) string {
382453 }
383454 defer response .Body .Close ()
384455
385- // read response
386456 body , _ := io .ReadAll (response .Body )
387457
388- // write post request body to fs
389458 logBody (response .Header .Get ("Content-Type" ), body , "apitts_" )
390459 logResponse (response )
391460
@@ -418,7 +487,6 @@ func makeResRequest(r *http.Request, w http.ResponseWriter) string {
418487 }
419488 defer response .Body .Close ()
420489
421- // read response
422490 body , _ := io .ReadAll (response .Body )
423491
424492 logBody (response .Header .Get ("Content-Type" ), body , "res_" )
@@ -434,3 +502,89 @@ func makeResRequest(r *http.Request, w http.ResponseWriter) string {
434502 }
435503 return string (body )
436504}
505+
506+ func makeEmoSpeechRequest (text string , languageCode string , r * http.Request ) EmoSpeechResponse {
507+ request , _ := http .NewRequest ("GET" , "https://" + conf .Livingio_API_Server + "/emo/speech/tts?q=" + url .QueryEscape (text )+ "&l=" + url .QueryEscape (languageCode ), nil )
508+
509+ val , exists := r .Header ["Authorization" ]
510+ if exists {
511+ request .Header .Add ("Authorization" , val [0 ])
512+ }
513+
514+ val , exists = r .Header ["Secret" ]
515+ if exists {
516+ request .Header .Add ("Secret" , val [0 ])
517+ }
518+
519+ request .Header .Del ("User-Agent" )
520+
521+ httpclient := & http.Client {}
522+ response , err := httpclient .Do (request )
523+
524+ if err != nil {
525+ log .Fatalf ("An Error Occured %v" , err )
526+ }
527+ defer response .Body .Close ()
528+
529+ body , _ := io .ReadAll (response .Body )
530+
531+ var emoSpeechResponse EmoSpeechResponse
532+ if err := json .Unmarshal ([]byte (body ), & emoSpeechResponse ); err != nil {
533+ log .Printf ("Error unmarshaling ChatGptSpeakServer response: %v\n " , err )
534+ return EmoSpeechResponse {}
535+ }
536+
537+ return emoSpeechResponse
538+ }
539+
540+ func makeChatGptSpeakRequest (queryText string , languageCode string , fallbackResponse string , r * http.Request ) BehaviorParas {
541+ type ChatGptSpeakRequest struct {
542+ QueryText string `json:"queryText"`
543+ LanguageCode string `json:"languageCode"`
544+ FallbackResponse string `json:"fallbackResponse,omitempty"`
545+ }
546+ type ChatGptSpeakResponse struct {
547+ ResponseText string `json:"responseText"`
548+ }
549+
550+ chatGptRequestData := ChatGptSpeakRequest {
551+ QueryText : queryText ,
552+ LanguageCode : languageCode ,
553+ FallbackResponse : fallbackResponse ,
554+ }
555+ chatGptRequestBody , _ := json .Marshal (chatGptRequestData )
556+ chatGptRequest , _ := http .NewRequest ("POST" , conf .ChatGptSpeakServer + "/speak" , bytes .NewBuffer (chatGptRequestBody ))
557+ chatGptRequest .Header .Add ("Content-Type" , "application/json" )
558+
559+ chatGptClient := & http.Client {}
560+ chatGptResponse , err := chatGptClient .Do (chatGptRequest )
561+ if err != nil {
562+ log .Fatalf ("An Error Occured while calling ChatGptSpeakServer %v" , err )
563+ }
564+ defer chatGptResponse .Body .Close ()
565+
566+ chatGptResponseBody , _ := io .ReadAll (chatGptResponse .Body )
567+
568+ var chatGptTypedResponse ChatGptSpeakResponse
569+ if err := json .Unmarshal ([]byte (chatGptResponseBody ), & chatGptTypedResponse ); err != nil {
570+ log .Printf ("Error unmarshaling ChatGptSpeakServer response: %v\n " , err )
571+ return BehaviorParas {}
572+ }
573+
574+ if chatGptTypedResponse .ResponseText == "" {
575+ log .Println ("ChatGptSpeakServer returned empty response text" )
576+ return BehaviorParas {}
577+ }
578+
579+ emoSpeechResponse := makeEmoSpeechRequest (chatGptTypedResponse .ResponseText , languageCode , r )
580+ if emoSpeechResponse .Code != 200 || emoSpeechResponse .Url == "" {
581+ log .Printf ("Error in EmoSpeechResponse: Code %d, Errmessage: %s\n " , emoSpeechResponse .Code , emoSpeechResponse .Errmessage )
582+ return BehaviorParas {}
583+ }
584+ behaviorParasResponse := BehaviorParas {
585+ Txt : chatGptTypedResponse .ResponseText ,
586+ Url : emoSpeechResponse .Url ,
587+ }
588+
589+ return behaviorParasResponse
590+ }
0 commit comments