Как обработать запрос к внешнему REST-сервису и вернуть ответ Google Assistant?

Я использую Java для создания приложения для Google Assistant, которое будет вызывать внешний REST API и возвращать определенные ответы на основе триггерных фраз. В настоящее время я могу использовать намерение приветствия по умолчанию, чтобы возвращать простые текстовые ответы через симулятор действий в Google. Однако, когда я пытаюсь вызвать внешний REST API и отправить ответ, симулятор возвращает сообщение, в котором говорится:

"MalformedResponse: Failed to parse Dialogflow response into AppResponse because of empty speech response."

Я использую org.springframework.web.client.RestTemplate из Spring-framework для обработки результата службы REST (https://fitzroi-rest-api-0525.appspot.com/rest/Фитц) со следующим вызовом: greeting = restTemplate.getForObject("https://fitzroi-rest-api-0525.appspot.com/rest/{name}", Greeting.class, givenName); (Это хорошо работает в обычном проекте Spring, но не в Actions on Google Intent)

Пример обучающей фразы для моего тестового приложения: «Тони передает привет». Отсюда я извлекаю «Тони» как @sys.given-name сущность в Dialogflow. Затем это имя передается службе REST для обработки. Служба REST — это приложение MVC, которое работает в отдельном проекте Google Cloud из приложения Google Assistant.

Пожалуйста, дайте мне знать, является ли это хорошим подходом к использованию службы REST с использованием веб-перехватчика заполнения Dialogflow.

Ниже приведен пример кода из моего веб-перехватчика, который пытается использовать службу 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();
  }

Это не похоже на ваш запрос REST API. Это может быть потому, что givenName равно нулю. Исключение говорит, что ваш речевой ответ пуст. Это может произойти только тогда, когда ваш оператор if не срабатывает (поскольку givenName имеет значение null или пуст). Дважды проверьте, что ваш параметр givenName имеет значение

Arthur Attout 30.05.2019 14:36

Спасибо, но нет, это не так. Даже если я жестко кодирую givenName и удаляю оператор if, я все равно получаю то же сообщение об ошибке. Другое дело, что я не знаю способа отладки, если приветствие когда-либо возвращает ответ в намерении. Кажется, я не могу найти, где LOGGER регистрируется в симуляторе. Единственные журналы, которые у меня есть, — это журналы симулятора сообщений между агентом и помощником.

Fitz 30.05.2019 15:41

Есть ли у greeting контент? Похоже, greeting может быть как ненулевым, так и с пустым содержимым

Nick Felker 30.05.2019 16:04

Получение значения в переменной greeting является основной причиной публикации этого вопроса. Вот где делается вызов REST, который не выполняется. Эта строка работает в простом проекте Java, но не работает в приложении Actions on Google.

Fitz 30.05.2019 22:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
4
526
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, что, поскольку actions-on-google требует вызовов потокобезопасных функций, RestTemplate из spring-framework не работает в app-engine приложении. Мне удалось найти обходной путь, используя пример кода, предоставленный командой actions-on-google на Гитхаб. Этот код требует, чтобы вы анализировали результаты URL-адреса внутри ActionsApp вместо использования библиотеки. Например:

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);

У меня также была серьезная проблема (UnKonwnHostException) при анализе результатов с удаленного URL-адреса. Этот документация был полезен.

Другие вопросы по теме