如何处理对外部 REST 服务的请求和 return 对 Google 助手的响应?
How to process a request to an external REST service and return the response to Google Assistant?
我正在使用 Java 为 Google 助手创建一个应用程序,它将根据触发短语调用外部 REST API 和 return 某些响应。
我目前可以通过 Google 模拟器上的操作使用默认欢迎意图 return 简单文本响应。但是,当我尝试调用外部 REST API 并发回响应时,模拟器 return 会显示一条消息:
"MalformedResponse: Failed to parse Dialogflow response into AppResponse because of empty speech response."
我正在使用 Spring-框架中的 org.springframework.web.client.RestTemplate
通过以下调用处理来自 REST 服务 (https://fitzroi-rest-api-0525.appspot.com/rest/Fitz) 的结果:
greeting = restTemplate.getForObject("https://fitzroi-rest-api-0525.appspot.com/rest/{name}", Greeting.class, givenName);
(这在常规 Spring 项目中运行良好,但在 Google Intent 的 Actions 中不适用)
我的测试应用程序的示例训练短语是 "Tony is sending greetings." 从这里我提取 "Tony" 作为 Dialogflow 中的 @sys.given-name
实体。然后将此名称传递给 REST 服务进行处理。 REST 服务是一个 MVC 应用程序,它 运行 在与 Google 助手应用程序分开的 Google 云项目中。
请告诉我这是否是使用 Dialogflow fullfillment webhook 使用 REST 服务的好方法。
下面是我的 webhook 中尝试使用 REST 服务的示例代码。
@ForIntent("process-greeting")
public ActionResponse greetingProcessor(ActionRequest request) {
LOGGER.info("Trying to process greeting intent");
ResponseBuilder responseBuilder = getResponseBuilder(request);
String givenName = (String) request.getParameter("given-name");
if (givenName != null && !givenName.isEmpty()) {
RestTemplate restTemplate = new RestTemplate();
Greeting greeting = null;
greeting = restTemplate.getForObject("https://fitzroi-rest-api-0525.appspot.com/rest/{name}", Greeting.class, givenName);
// LOGGER.info("Attempting to send back " + greeting.getContent() + " to Google Assistant");
if (greeting == null)
responseBuilder.add("The rest service did not return a response.");
else
responseBuilder.add(greeting.getContent());
}
LOGGER.info("Welcome intent end.");
return responseBuilder.build();
}
似乎由于 actions-on-google
需要 thread-safe 函数调用,spring-framework
中的 RestTemplate
在 app-engine
应用程序中不起作用。通过使用 actions-on-google
团队在 GitHub 上提供的示例代码,我能够找到 walk-around。此代码要求您从 ActionsApp
中解析 URL 的结果,而不是使用库。例如:
URL restURL = new URL("http://yourdomain.com/your/rest/call");
URLConnection conn = restURL.openConnection();
InputStreamReader reader = new InputStreamReader(
(InputStream) conn.getContent());
JsonParser parser = new JsonParser();
JsonElement root = parser.parse(reader);
MyObject = myParseFunction(root);
我在解析来自远程 URL 的结果时也遇到了严重的问题 (UnKonwnHostException)。这 documentation 很有帮助。
我正在使用 Java 为 Google 助手创建一个应用程序,它将根据触发短语调用外部 REST API 和 return 某些响应。 我目前可以通过 Google 模拟器上的操作使用默认欢迎意图 return 简单文本响应。但是,当我尝试调用外部 REST API 并发回响应时,模拟器 return 会显示一条消息:
"MalformedResponse: Failed to parse Dialogflow response into AppResponse because of empty speech response."
我正在使用 Spring-框架中的 org.springframework.web.client.RestTemplate
通过以下调用处理来自 REST 服务 (https://fitzroi-rest-api-0525.appspot.com/rest/Fitz) 的结果:
greeting = restTemplate.getForObject("https://fitzroi-rest-api-0525.appspot.com/rest/{name}", Greeting.class, givenName);
(这在常规 Spring 项目中运行良好,但在 Google Intent 的 Actions 中不适用)
我的测试应用程序的示例训练短语是 "Tony is sending greetings." 从这里我提取 "Tony" 作为 Dialogflow 中的 @sys.given-name
实体。然后将此名称传递给 REST 服务进行处理。 REST 服务是一个 MVC 应用程序,它 运行 在与 Google 助手应用程序分开的 Google 云项目中。
请告诉我这是否是使用 Dialogflow fullfillment webhook 使用 REST 服务的好方法。
下面是我的 webhook 中尝试使用 REST 服务的示例代码。
@ForIntent("process-greeting")
public ActionResponse greetingProcessor(ActionRequest request) {
LOGGER.info("Trying to process greeting intent");
ResponseBuilder responseBuilder = getResponseBuilder(request);
String givenName = (String) request.getParameter("given-name");
if (givenName != null && !givenName.isEmpty()) {
RestTemplate restTemplate = new RestTemplate();
Greeting greeting = null;
greeting = restTemplate.getForObject("https://fitzroi-rest-api-0525.appspot.com/rest/{name}", Greeting.class, givenName);
// LOGGER.info("Attempting to send back " + greeting.getContent() + " to Google Assistant");
if (greeting == null)
responseBuilder.add("The rest service did not return a response.");
else
responseBuilder.add(greeting.getContent());
}
LOGGER.info("Welcome intent end.");
return responseBuilder.build();
}
似乎由于 actions-on-google
需要 thread-safe 函数调用,spring-framework
中的 RestTemplate
在 app-engine
应用程序中不起作用。通过使用 actions-on-google
团队在 GitHub 上提供的示例代码,我能够找到 walk-around。此代码要求您从 ActionsApp
中解析 URL 的结果,而不是使用库。例如:
URL restURL = new URL("http://yourdomain.com/your/rest/call");
URLConnection conn = restURL.openConnection();
InputStreamReader reader = new InputStreamReader(
(InputStream) conn.getContent());
JsonParser parser = new JsonParser();
JsonElement root = parser.parse(reader);
MyObject = myParseFunction(root);
我在解析来自远程 URL 的结果时也遇到了严重的问题 (UnKonwnHostException)。这 documentation 很有帮助。