• Nodejs Bot学习


    关于示例部分可以参考《BotFramework Nodejs示例》《BotBuilder Nodejs示例查看


    Bot Framework Nodejs SDK包括几种与用户或会话相关的数据持久化方法

    1. userData】  用户级别--》包含为指定Channel上(多个Channel应该不共享数据)的用户保存的数据(其他用户不可见)。此数据将持续多个会话(如果使用模拟器,关闭对话之后还是可以查看到数据)。
    2. conversationData】 会话级别--》包含保存在指定Channel上特定会话的上下文中的数据。此数据与参与会话的所有用户共享,并将持续存在当前会话。会话结束或 endConversation 明确调用时,该属性将被清除。
    3. privateConversationData】 会话级别--》包含在指定Channel上的特定会话的上下文中为用户保存的数据。此数据对当前用户是私有的,并且将仅持续当前对话。会话结束或 endConversation 明确调用时,该属性将被清除。
    4. dialogData】 对话级别--》保留单个对话框实例的信息,对于瀑布的步骤之前存储临时信息非常重要

    使用Bot Builder构建的Bot是无状态的,因此可以轻松扩展以跨多个计算节点运行,因为你应该避免使用全局变量或函数闭包保存状态,这样做会产生问题,当你想扩展你的机器人,相反,利用上面的数据包来保持临时和永久状态。

    官方文档地址:https://docs.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-state


    数据的操作


    会话中的对话框瀑布流

    例如以下代码中与第二段代码效果是一致的,所以上图中的意思就是可以将对话框分开成不同的文件,方便管理

    当然,这些dialog存放在同一个文件也是可以的,并不影响效果

    dialog调用的效果即,第一个dialog以beginDialog()访问跳转至第二个dialog,第二个dialog就得到了主动权,与用户进行对话,

    当第二个完成了,只需要以endDialog()或endDialogWithResult()方法返回于第一个dialog,此时主动权又回到了第一个dialog

    // This is a dinner reservation bot that uses a waterfall technique to prompt users for input.
    var bot = new builder.UniversalBot(connector, [
        function (session) {
            session.send("Welcome to the dinner reservation.");
            builder.Prompts.time(session, "Please provide a reservation date and time (e.g.: June 6th at 5pm)");
        },
        function (session, results) {
            session.dialogData.reservationDate = builder.EntityRecognizer.resolveTime([results.response]);
            builder.Prompts.text(session, "How many people are in your party?");
        },
        function (session, results) {
            session.dialogData.partySize = results.response;
            builder.Prompts.text(session, "Whose name will this reservation be under?");
        },
        function (session, results) {
            session.dialogData.reservationName = results.response;
    
            // Process request and display reservation details
            session.send("Reservation confirmed. Reservation details: <br/>Date/Time: %s <br/>Party size: %s <br/>Reservation name: %s",
                session.dialogData.reservationDate, session.dialogData.partySize, session.dialogData.reservationName);
            session.endDialog();
        }
    ]);
    View Code
    // This is a dinner reservation bot that uses multiple dialogs to prompt users for input.
    var bot = new builder.UniversalBot(connector, [
        function (session) {
            session.send("Welcome to the dinner reservation.");
            session.beginDialog('askForDateTime');//开始对话框
        },
        function (session, results) {
            session.dialogData.reservationDate = builder.EntityRecognizer.resolveTime([results.response]);//保存输入结果至dialogData
            session.beginDialog('askForPartySize');//开始对话框
        },
        function (session, results) {
            session.dialogData.partySize = results.response;//保存输入结果至dialogData
            session.beginDialog('askForReserverName');//开始对话框
        },
        function (session, results) {
            session.dialogData.reservationName = results.response;//保存输入结果至dialogData
    
            // Process request and display reservation details
            session.send("Reservation confirmed. Reservation details: <br/>Date/Time: %s <br/>Party size: %s <br/>Reservation name: %s",
                session.dialogData.reservationDate, session.dialogData.partySize, session.dialogData.reservationName);
            session.endDialog();//结束对话框
        }
    ]);
    
    // Dialog to ask for a date and time
    bot.dialog('askForDateTime', [
        function (session) {
            builder.Prompts.time(session, "Please provide a reservation date and time (e.g.: June 6th at 5pm)");
        },
        function (session, results) {
            session.endDialogWithResult(results);
        }
    ]);
    
    // Dialog to ask for number of people in the party
    bot.dialog('askForPartySize', [
        function (session) {
            builder.Prompts.text(session, "How many people are in your party?");
        },
        function (session, results) {
            session.endDialogWithResult(results);
        }
    ])
    
    // Dialog to ask for the reservation name.
    bot.dialog('askForReserverName', [
        function (session) {
            builder.Prompts.text(session, "Who's name will this reservation be under?");
        },
        function (session, results) {
            session.endDialogWithResult(results);
        }
    ]);
    View Code

    endDialog()和endDialogWithResult()及replaceDialog()方法

    endDialog()方法只是完成当前的dialog,将主动权返回调用现在的dialog的对象

    endDialogWithResult()方法是完成当前的dialog并返回参数,将主动权返回调用现在的dialog的对象

    replaceDialog()方法是将当前的主动权交互另外一个dialog


    bot framework架构


    收集输入
    Bot Builder附带了一些内置的提示,可用于从用户收集输入。
    提示类型 描述
    Prompts.text 要求用户输入文本字符串。
    提示 要求用户确认操作。
    提示 要求用户输入号码。
    提示时间 向用户询问时间或日期。
    提示 要求用户从选择列表中进行选择。
    提示 要求用户上传图片或视频。
    这些内置的提示被实现为对话所以他们会回报用户通过调用响应session.endDialogWithresult() 。任何DialogHandler都可以接收对话的结果,但是瀑布往往是处理提示结果的最简单的方法。
    提示返回给调用者的IPromptResult。用户响应将包含在results.response字段中,并且可以为null。响应为null的原因有很多。内置提示让用户通过说出像“cancel”或“nevermind”之类的操作来取消操作,这将导致null响应。或者用户可能无法输入正确格式的响应,这也可能导致空响应。确切的原因可以通过检查在result.resumed中返回的ResumeReason来确定。
    Prompts.text()
    该Prompts.text()方法要求的文本字符串用户。用户的响应将返回作为IPromptTextResult。
    builder.Prompts.text(session, "What is your name?");
    Prompts.confirm()
    该Prompts.confirm()方法将要求用户确认是/否响应的动作。用户的响应将返回作为IPromptConfirmResult。
    builder.Prompts.confirm(session, "Are you sure you wish to cancel your order?");
    Prompts.number()
    该Prompts.number()方法将要求用户用一个数字来回答。用户的响应将返回作为IPromptNumberResult。
    builder.Prompts.number(session, "How many would you like to order?");
    Prompts.time()
    该Prompts.time()方法将要求用户用时间来回答。用户的响应将返回作为IPromptTimeResult。该框架采用了一种名为库计时来分析用户的响应,都相对的“5分钟”和非亲属“6月6日下午2点”式的回应支持。
    该results.response返回的是一个实体可以使用被解析为一个JavaScript Date对象EntityRecognizer.resolveTime() 。
    bot.dialog('/createAlarm', [
    function (session) {
    session.dialogData.alarm = {};
    builder.Prompts.text(session, "What would you like to name this alarm?");
    },
    function (session, results, next) {
    if (results.response) {
    session.dialogData.name = results.response;
    builder.Prompts.time(session, "What time would you like to set an alarm for?");
    } else {
    next();
    }
    },
    function (session, results) {
    if (results.response) {
    session.dialogData.time = builder.EntityRecognizer.resolveTime([results.response]);
    }

    // Return alarm to caller
    if (session.dialogData.name && session.dialogData.time) {
    session.endDialogWithResult({
    response: { name: session.dialogData.name, time: session.dialogData.time }
    });
    } else {
    session.endDialogWithResult({
    resumed: builder.ResumeReason.notCompleted
    });
    }
    }
    ]);
    Prompts.choice()
    所述Prompts.choice()方法要求用户接从一个列表中选择一个选项。用户的响应将返回作为IPromptChoiceResult。选择列表可被呈现给用户以各种经由样式IPromptOptions.listStyle属性。用户可以通过输入选项的编号或其名称来表达他们的选择。支持选项名称的完全匹配和部分匹配。
    选择列表可以以各种方式传递到Prompts.choice()。作为管道'|' 分隔字符串。
    builder.Prompts.choice(session, "Which color?", "red|green|blue");
    作为字符串数组。
    builder.Prompts.choice(session, "Which color?", ["red","green","blue"]);
    或作为对象映射。当传递一个对象时,将使用对象键来确定选择。
    var salesData = {
    "west": {
    units: 200,
    total: "$6,000"
    },
    "central": {
    units: 100,
    total: "$3,000"
    },
    "east": {
    units: 300,
    total: "$9,000"
    }
    };
    bot.dialog('/', [
    function (session) {
    builder.Prompts.choice(session, "Which region would you like sales for?", salesData);
    },
    function (session, results) {
    if (results.response) {
    var region = salesData[results.response.entity];
    session.send("We sold %(units)d units for a total of %(total)s.", region);
    } else {
    session.send("ok");
    }
    }
    ]);
    Prompts.attachment()
    该Prompts.attachment()方法会要求用户上传像图像或视频文件附件。用户的响应将返回作为IPromptAttachmentResult。
    builder.Prompts.attachment(session, "Upload a picture for me to transform.");

  • 相关阅读:
    我的程序员之路(6)——离职
    oracle手记(二)
    关于抽象类和接口
    Oracle学习手记
    DHTML
    XmlDocument,XmlNode,XmlElement创建复杂XML文档
    一首诗
    PC端口知识(转)
    sharpPDF.NET生成PDF文件
    Socket接口原理及C#实现
  • 原文地址:https://www.cnblogs.com/weschen/p/7365512.html
Copyright © 2020-2023  润新知