DialogFlow Agent 没有 return 嵌套 axios 的结果

DialogFlow Agent does not return result of nested axios

我正在尝试将外部 API 与我的 dialogflow 代理集成。 我有随用随付计划。我正在尝试进行嵌套 API 调用(顺序),然​​后创建一个我希望我的代理人说的动态句子。

问题是我可以在 Logs Explorer 中看到 console.log(),但代理没有说出句子。

我正在为 axios 调用使用单独的函数。

这是我的代码:

function get_portfolio_status(agent) {

    agent.add("Here are your details. "); // the agent speaks only this

    var username = "uname";
    var password = "pwd";
    var product = "product";
    var to_speak = "";

// First call
    return login(username, password, product)
      .then((result) => {
        let SID = result.data.sid;

// Second nested function call using result of first one

        get_token(SID)
        .then((result) => {
            let JWT = result.data;
            console.log('Request token received:');

//Third call again using result of previous one

            get_portfolios(JWT)
            .then((result) => {
                let portfolios = result.data.data;
          
// Fourth call

                get_change([], JWT).then((result) => {
                  let changed_portfolio = result.data.data;
                  let to_speak = "Your portfolios are: " + changed_portfolio + portfolios;

                 console.log(to_speak); // I can see this in the Logs.

 // I cant seem to make this below work. Its just skipped due to js behavior I think

                 agent.add(to_speak + '\nWould you like to get your today\'s winners? '); 

                }).catch((err) => {console.error(err);}); 
            }).catch((err) => {console.error(err);}); 
          }).catch((err) => {console.error(err);});     
    }).catch((err) => {console.error(err);});
  }


应该工作的行是 agent.add(to_speak + '\nWould you like to get your today\'s winners? ');

代理人没有说出那句台词。我很确定这是 JS 的异步行为,但我正在处理承诺并返回它。

login function 和其他人只是返回 axios。其中一些是 POST 一些是 GET

例如:

function login(username, password, product){

  var data = {...};

  config = {
   method: 'post',
   url:'my_url',
   headers:{...}
  }

  return axios(config);
}

您可以 return 在所有承诺都解决后承诺。并在最后一个 API 调用结束时解决,直到它有所有响应才不解决它。我已经对拒绝的代码进行了更改,您可以在需要的地方实施。最后才解决。

function get_portfolio_status(agent) {

    agent.add("Here are your details. "); // the agent speaks only this

    var username = "uname";
    var password = "pwd";
    var product = "product";
    var to_speak = "";
    
    return new Promise((resolveAll, rejectAll)=>{
   

    // First call
    login(username, password, product)
      .then((result) => {
        let SID = result.data.sid;

// Second nested function call using result of first one

        get_token(SID)
        .then((result) => {
            let JWT = result.data;
            console.log('Request token received:');

//Third call again using result of previous one

            get_portfolios(JWT)
            .then((result) => {
                let portfolios = result.data.data;

// Fourth call

                get_change([], JWT).then((result) => {

                  let changed_portfolio = result.data.data;
                  let to_speak = "Your portfolios are: " + changed_portfolio + portfolios;

                 console.log(to_speak); // I can see this in the Logs.

 // I cant seem to make this below work. Its just skipped due to js behavior I think

                 agent.add(to_speak + '\nWould you like to get your today\'s winners? '); 
                resolveAll(); // Resolve when you finally have everything 
                }).catch((err) => {console.error(err);}); 
            }).catch((err) => {console.error(err);}); 
          }).catch((err) => {console.error(err);});     
    }).catch((err) => {console.error(err);});
  }

    })

问题已解决。有两件事需要考虑。

1- 根据 Dialogflow:对于 Google 助手应用程序,响应必须在 10 秒内发生,对于所有其他应用程序,响应必须在 5 秒内发生,否则请求将超时。 这包括 axios 调用之前的逻辑。如果您在内联编辑器中执行此操作,则函数调用从头开始,否则为您自己的 web 服务响应的时间。 在我的例子中 get_portfolio_status(agent)agent.add 部分的代码起点。

参考:https://cloud.google.com/dialogflow/es/docs/fulfillment-webhook#webhook_response

旁注:截至目前,只有美国服务器具有与 google 助手的对话流集成(用于测试)。如果外部 API 呼叫欧洲/亚洲,请在计算中考虑网络延迟。

2- 第一点现在不适用,因为此工作流的处理时间少于 2 秒。 我的代码中存在对其他函数的嵌套调用的问题。我必须将 returns 添加到所有嵌套调用中。

return login(username, password, product)
    .then((result) => {
        let SID = result.data.sid;

        // Second nested function call using result of first one

        return get_token(SID)
            .then((result) => {
                let JWT = result.data;
                console.log('Request token received:');

                //Third call again using result of previous one

                return get_portfolios(JWT)
                    .then((result) => {
                        let portfolios = result.data.data;

                        // Fourth call

                        return get_change([], JWT).then((result) => {
                            let changed_portfolio = result.data.data;
                            let to_speak = "Your portfolios are: " + changed_portfolio + portfolios;

                            console.log(to_speak); // I can see this in the Logs.

                            // WORKS

                            agent.add(to_speak + '\nWould you like to get your today\'s winners? ');

                        }).catch((err) => {
                            console.error(err);
                        });
                    }).catch((err) => {
                        console.error(err);
                    });
            }).catch((err) => {
                console.error(err);
            });
    }).catch((err) => {
        console.error(err);
    });

我希望支持对话流实现服务中的内联编辑器async/await。本来可以让我写出更简洁的代码,省去很多麻烦。

但是内联编辑器是用来测试小原型的,所以我想没关系。在生产中,我们将部署一个单独的网络服务。