前提・実現したいこと
現在Dialogflowを勉強しています。
Dialogflowのwebhookを利用してAPIを呼び出す処理を実装していますが、構造体に値を入れられず詰まっています。
ご教授宜しくお願いいたします
Dialogflow <-> CloudFunctions <-> NewsAPI
サーバサイドはGo言語になります。
詰まっていること
fulfillmentMessages.text.textに値を追加して行きたいのですがどの様に追加すれば良いのかが分かりません。
以下試したコードです。
for i := 0; i < len(newAPIResponse.Articles); i++ { response.FulfillmentMessages.Text.Text = append(response.FulfillmentMessages.Text.Text, newAPIResponse.Articles[i].Title) }
この場合JSONにエンコードすると以下の様になりました。
response
1{{["title title title title"]}} //一つの配列に全て入ってしまう
理想は以下の様な形です。
{ "fulfillmentMessages": [ { "text": { "text": [ "Text response from webhook", "Text response from webhook", ...以下略 ] } } ] }
該当のソースコード
https://cloud.google.com/dialogflow/es/docs/fulfillment-webhook#requirements
DialogflowへのレスポンスJSON
fulfillmentMessages
1{ 2 "fulfillmentMessages": [ 3 { 4 "text": { 5 "text": [ 6 "Text response from webhook" 7 ] 8 } 9 } 10 ] 11}
ニュースAPIのレスポンスは以下の様になっています。
NewsAPI
1{ 2"status": "ok", 3"totalResults": 38, 4-"articles": [ 5-{ 6-"source": { 7"id": "cnn", 8"name": "CNN" 9}, 10"author": "Frank Pallotta, CNN Business", 11"title": "'SNL' takes on the dueling town halls between Trump and Biden - CNN", 12"description": "Instead of a presidential debate, this week had dueling town halls between President Donald Trump and former Vice President Joe Biden. \"Saturday Night Live\" covered both, like many viewers, by flipping back and forth between the two.", 13"url": "https://www.cnn.com/2020/10/18/media/snl-biden-trump-town-halls/index.html", 14"urlToImage": "https://cdn.cnn.com/cnnnext/dam/assets/201017234919-saturday-night-live-cold-open-super-tease.jpg", 15"publishedAt": "2020-10-18T04:22:00Z", 16"content": "New York (CNN Business)Instead of a presidential debate, this week had dueling town halls between President Donald Trump and former Vice President Joe Biden. \"Saturday Night Live\" covered both, like … [+2381 chars]" 17}, 18-{ 19-"source": { 20"id": null, 21"name": "NCAA.com" 22}, 23"author": "NCAA.com", 24"title": "Alabama dominates second half, beats Georgia 41-24 in huge SEC game - NCAA.com", 25"description": "No. 2 Alabama controlled the second half as the Tide defeated No. 3 Georgia 41-24 on Saturday. QB Mac Jones led a powerful offense and the defense shut down Georgia after halftime.", 26"url": "https://www.ncaa.com/live-updates/football/fbs/alabama-dominates-second-half-beats-georgia-41-24-huge-sec-game", 27"urlToImage": "https://www.ncaa.com/_flysystem/public-s3/images/2020-10/alabama-football-mac-jones_0.jpg", 28"publishedAt": "2020-10-18T03:42:12Z", 29"content": "Georgia has come about as close as you can get to beating Alabama in recent years. On Saturday, the Bulldogs get another chance.\r\nThree of the last four meetings have been classics. In 2012, Georgia … [+1495 chars]" 30}, 31.....以下略
以下Functionsにデプロイしようとしている関数になります。
CloudFunctionsは(勉強予定)無理やり使っているので関数が肥大化してますが、許してください。
// Package p contains an HTTP Cloud Function. package p import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" ) type intent struct { DisplayName string `json:"displayName"` } type parameters struct { Where []string `json:"where"` } type queryResult struct { Intent intent `json:"intent"` Parameters parameters `json:"parameters"` } type text struct { Text []string `json:"text"` } type message struct { Text text `json:"text"` } type webhookRequest struct { Session string `json:"session"` ResponseID string `json:"responseId"` QueryResult queryResult `json:"queryResult"` } type webhookResponse struct { FulfillmentMessages message `json:"fulfillmentMessages"` } type NewsAPIResponse struct { Articles []articles `json:"articles"` } type articles struct { Title string `json:"title"` Url string `json:"url"` UrlToImage string `json:"urlToImage"` } // HandleWebhookRequest handles WebhookRequest and sends the WebhookResponse. func HandleWebhookRequest(w http.ResponseWriter, r *http.Request) { var request webhookRequest var response webhookResponse var err error var newAPIResponse NewsAPIResponse // Read input JSON if err = json.NewDecoder(r.Body).Decode(&request); err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "ERROR: %v", err) return } log.Printf("Request: %+v", request) // Call intent handler intent := request.QueryResult.Intent.DisplayName if intent == "News" { where := request.QueryResult.Parameters.Where if where[0] == "日本" { where[0] = "ja" } else if where[0] == "アメリカ" { where[0] = "us" } url := "https://newsapi.org/v2/top-headlines?country=" + where[0] + "&apiKey=*****" resp, _ := http.Get(url) defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err := json.Unmarshal(body, &newAPIResponse); err != nil { log.Fatal(err) } if err != nil { return } for i := 0; i < len(newAPIResponse.Articles)-1; i++ { //ここでどう代入するかが分かりません。 response.FulfillmentMessages.Text.Text[i] = newAPIResponse.Articles[i].Title } } if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "ERROR: %v", err) return } log.Printf("newsresponse : %v", response) // Send response if err = json.NewEncoder(w).Encode(&response); err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "ERROR: %v", err) return } }
試したこと
append関数を使って代入しましたが、一つのtextに全て代入してしまったので上手く行きませんでした。
append {{["aaa aaa aaa aaa aaa"]}}
理想 {{["aaa","aaa","aaa","aaa"]}}
補足情報(FW/ツールのバージョンなど)
Go 1.13
GoogleCloudFunctions
Dialogflow