BotFramework发布请求正文未保存在session.userData中

时间:2019-02-27 09:21:47

标签: node.js azure request botframework

使用POST请求,我将用户提交的信息发送到API,该API将提供用户特定的信息。

现在,我想将POST请求反击的信息另存为变量,以便在其他功能/对话中使用。

我尝试了以下操作:

  1. 将POST请求正文保存在session.userData.xxx变量中
  2. 声明了一个全局变量并将其用于存储正文。
  3. 在发布请求中声明了一个变量,我在其中存储了正文

我所做的代码版本如下:

    var body2;

    bot.dialog('FunctionA', [
        function (session) {
            session.sendTyping();
            builder.Prompts.text(session, "Please key-in your App ID:");
    },
    function (session, results) {
        session.userData.AppID= results.response;
         var options = {
      url: 'APIXYZ.COM',
      headers: {
          'Content-Type' : 'application/json'               
            },
         body: JSON.stringify({"appID": session.userData.AppID})

        };

        request.post(options, function(error, response, body) {
          if (!error && response.statusCode == 200) {
            console.log(body); //logs okay
            session.userData.infoA = body;
        console.log(session.userData.infoA) //logs okay
        body2 = body;
            console.log (body2) // logs ok
        var bodyvar = body;
            console.log (bodyvar) //logs ok

          } else {
              console.log("Error: " + error);
              console.log("Status Code: " + response.statusCode);
          }
        });

        var msg = new builder.Message(session)

        .text("The body is:" + session.userData.infoA) //outputs "The body is undefined", if body2,bodyvar -> empty
        .suggestedActions(
            builder.SuggestedActions.create(
                session, [

                    builder.CardAction.imBack(session, "Ok", "Ok")
                    builder.CardAction.imBack(session, "No", "No")

                ]
            ));
    session.send(msg).endDialog();

    }]).triggerAction({ matches: /^ABC/i });

似乎它仅在请求块内起作用,而我不能在其之外使用它。在外部使用时记录为未定义。我希望能够将POST请求正文存储为变量,以便可以在此对话框之外使用它们,并将其保存在数据库中。

谢谢!

编辑:

我已将body2声明为对话框和请求块外部的变量,并在同一对话框中紧随request.post

使用了该变量。
var msg = new builder.Message(session)

.text("The body contains: " + body2 + " .") 
        .suggestedActions(
            builder.SuggestedActions.create(
                session, [

                    builder.CardAction.imBack(session, "Ok", "Ok")
                    builder.CardAction.imBack(session, "No", "No")

                ]
            ));

这将输出The body contains: undefined .

我也试图在另一个对话框中使用它:

bot.dialog('Validation', function (session) {
    console.log(body2);
   session.send("The content is : " + body2 +" xx");
    if (body2== "ABC")
    {
        session.sendTyping();
        var msg = new builder.Message(session);
[.......]

这将导致"Oops. Something went wrong and we need to start over"提示

1 个答案:

答案 0 :(得分:0)

问题在于您的post请求在执行其他功能之前没有完成。换句话说,这就是您的代码正在做的事情:

  1. 创建post请求
  2. 执行代码,其中body2仍未定义
  3. post请求完成,然后然后body2定义为body

您可以通过两种方式解决此问题:

使用异步/等待

这基本上会迫使您的所有代码等待request.post返回数据后再继续。如果您不熟悉,async/await是使用Promises.then()的较新方法。它非常有用,特别是在发出HTTP请求时。您可以read more here

添加async

async function (session, results) {
    session.userData.AppID= results.response;
    var options = {
        url: 'APIXYZ.COM',
...

添加await

await request.post(options, function(error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body); //logs okay
    session.userData.infoA = body;

将代码封装在您的请求函数中

由于request.post一旦具有errorresponsebody就将执行代码,因此您可以包括任何需要使用这样返回的数据的代码:

request.post(options, function(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body); //logs okay
        body2 = body;
        console.log (body2) // logs ok
        var msg = new builder.Message(session)
            .text("The body is:" + body2)
            .suggestedActions(
                builder.SuggestedActions.create(
                    session, [

                        builder.CardAction.imBack(session, "Ok", "Ok"),
                        builder.CardAction.imBack(session, "No", "No")

                    ]
                ));
        session.send(msg).endDialog();
    } else {
        console.log("Error: " + error);
        console.log("Status Code: " + response.statusCode);
    }
});

出于两个原因,我建议走async/await路线:

  1. 它在许多JavaScript场景中超级有用,并且非常了解
  2. 如果在其他对话框中使用body2,则仍然需要使用它。使用上面的“封装”方法,您可能仍在等待响应,而另一个对话框需要body2

所有这些,看起来您正在使用Bot Framework的V3。如果这是一个新机器人,我建议您在V4中进行构建-它具有更新的功能,我们会提供更好的支持。