Инициировать выполнение webhook асинхронно из намерения? - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть некоторые намерения, которые должны вызвать выполнение webhook и не заботятся об ответе.Для ответа веб-крючка требуется больше времени, чем для тайм-аута, поэтому я хотел бы, чтобы намерение было просто ответить «Спасибо за беседу», а затем закрыть разговор, фактически запуская веб-крючок.,Также я новичок в диалоге.

Я могу сделать это на любом языке, но вот пример в Javascript:

fdk.handle(function (input) {
  // Some code here that takes 20 seconds.

  return {'fulfillmentText': 'i can respond but I will never make it here.'}
});

РЕДАКТИРОВАТЬ 1 - Попытка асинхронного

Когда я использую асинхронную функцию, запрос POST никогда не происходит.Итак, в следующем коде:

fdk.handle(function (input) {
  callFlow(input);
  return { 'fulfillmentText': 'here is the response from the webhook!!' }
});

async function callFlow(input) {
  console.log("input is --> " + input)

  var url = "some_url"

  console.log("Requesting " + url)

  request(url, { json: true, headers: {'Access-Control-Allow-Origin' : '*'} }, (err, res, body) => {
    if (err) { return console.log(err); }
    console.log("body is...")
    console.log(body)
  });
}

Я вижу в журналах два вывода console.log, но ничего из запроса.И, похоже, запрос тоже не исполняется, потому что я не вижу его в своей конечной точке.

РЕШЕНИЕ

Спасибо Заключенному за подсказку.Похоже, мне нужно было вернуть выполнение JSON обратно через функции callFlow () и handle ().Теперь у Google Home нет времени ожидания, и генерируются как HTTP-вызов, так и ответ.

const fdk = require('@fnproject/fdk');
const request = require('request');

fdk.handle(function (input) {
  return callFlow(input);
});

async function callFlow(input) {
  var searchPhrase = input || "cats"
  var url = "some url"

  return new Promise((resolve, reject) => {
    request.post(url, {
      headers: { 'content-type': 'application/x-www-form-urlencoded' },
      body: searchPhrase
    },
      function (err, resp, body) {
        if (err) { return console.log(err) }
        r = { 'fulfillmentText': `OK I've triggered the flow function with search term ${searchPhrase}` }
        resolve(r)
      }
    );
  });

}

1 Ответ

0 голосов
/ 03 февраля 2019

Вы не можете запустить выполнение асинхронно.В диалоговой модели ожидается, что выполнение будет выполнять некоторую логику, которая определяет ответ.

Вы можете , однако выполнить асинхронную операцию в выполнении, которая не завершается перед вамивернуть результат.

Если вы используете достаточно современную версию узла (версия 8 и выше), вы можете сделать это, объявив функцию как async функцию, но не вызывая его с ключевым словом await.(Если вы вызовете его с помощью await, он будет ждать завершения асинхронной операции, прежде чем продолжить.)

Итак, что-то вроде этого должно работать, учитывая ваш пример:

async function doSomethingLong(){
  // This takes 20 seconds
}

fdk.handle(function (input) {
  doSomethingLong();

  return {'fulfillmentText': 'This might respond before doSomethingLong finishes.'}
});

Обновление 1 на основе вашего примера кода.

Кажется странным, что вы сообщаете, что вызов request вообще не выполняется, но есть некоторые странные вещиэто может быть причиной.

Во-первых, request само по себе не является асинхронной функцией.Он использует модель обратного вызова, и функции async не просто автоматически ожидают вызова этих обратных вызовов.Таким образом, ваша callFlow() функция вызывает console.log() пару раз, вызывает request() и возвращается до обратного вызова.

Вы, вероятно, должны заменить request чем-то вроде request-обещание пакет и ждите обещание, которое вы получите от звонка.Это делает callFlow() действительно асинхронным (и вы можете регистрировать, когда он завершает вызов).

Во-вторых, я хотел бы отметить, что код, который вы показали, не выполняет операцию POST.Это делает GET по умолчанию.Если вы или API, который вы вызываете, ожидаете POST, это может быть источником ошибки.Однако я ожидал, что параметр err будет заполнен, и ваш код выглядит так, как будто он проверяет и регистрирует это.

Единственный неизвестный во всей настройке, для меня, это то, что яЯ не знаю, как fdk обрабатывает асинхронные функции, и мое беглое чтение документации не научило меня.Я сделал это с другими фреймворками, и это не проблема, но я не знаю, истекает ли время обработки обработчика fdk или выполняет другие действия, чтобы завершить вызов после отправки ответа.

...