1

我正在使用 Bot Framework 在网络频道和直线中创建一个机器人。我有一个调用一些表单(流表单)的 luis 对话框。

我必须向每份表格索要合同编号和其他一些数据。如何只存储一次合同号并继续到其他字段以及响应用户该合同号的正确答案。

  • 我试图在乞求人的合同号和姓名时询问并检查它们是否匹配..如果是的话让用户使用机器人......但我找不到正确的逻辑代码。

您能帮我解决一下如何只询问一次合同编号并在我的所有对话和表格中使用的方法吗?下面是我的代码:

消息控制器.cs:

public class MessagesController : ApiController
{  
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        Activity isTypingReply = activity.CreateReply();
        isTypingReply.Type = ActivityTypes.Typing;
        await connector.Conversations.ReplyToActivityAsync(isTypingReply);

        if (activity.Type == ActivityTypes.Message)
        {
            activity.Locale = "en-US";
            Helpers.SaveActivityDataToDB(activity);
            await Conversation.SendAsync(activity, () => new LuisDialog());
        }
        else
        {
            HandleSystemMessage(activity);
        }
        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
    }

路易斯.cs

[LuisIntent("Greeting")]
public async Task Greeting(IDialogContext context, LuisResult result)
{
    await context.SayAsync(text: "Welcome");
}

[LuisIntent("balance")]
public async Task balance(IDialogContext context, LuisResult result)
{
    var balanca = new FormDialog<BalanceForm>(
        new BalanceForm(),
        BalanceForm.BuildForm,
        FormOptions.PromptInStart,
        result.Entities);
    context.Call<BalanceForm>(balanca, BalanceCompleted);
}

private async Task BalanceCompleted(IDialogContext context, IAwaitable<BalanceForm> result)
{
    BalanceForm form = null;
    try
    {
        form = await result;
    }
    catch (OperationCanceledException)
    {
    }

    if (form == null)
    {
        await context.PostAsync("Try again please!");
    }
    else
    {
        //call the LossForm service to complete the form fill
        var message = $"Thnx";
        await context.PostAsync(message);
    }
    context.Wait(this.MessageReceived);
}

BalanceForm.cs

[Serializable]
public class BalanceForm
{
    [Prompt("What is your contract number?")]
    public string contract;

    public static IForm<BalanceForm> BuildForm()
    {
        OnCompletionAsyncDelegate<BalanceForm> wrapUpRequest = async 
        (context, state) =>
        {
            using (BotModelDataContext BotDb = new BotModelDataContext())
            {
                //search in database 

                string wrapUpMessage = "Dear " + house.Firstname + "," + "your  balance is " + house.Balance;
                await context.PostAsync(wrapUpMessage);       
            };
            return new FormBuilder<BalanceForm>()
                .Message("We have to ask you some information")
                .Field(nameof(contract))
                .OnCompletion(wrapUpRequest)
                //.Confirm("Are you sure: Yes or No ")
                .Build();
        }
    }
}
4

1 回答 1

1

您能帮我解决一下如何只询问一次合同编号并在我的所有对话和表格中使用的方法吗?

根据您的要求,我创建了一个示例来提示用户输入合同号并将值保存在UserData中,以便我可以在子对话框中从UserData获取用户提供的合同号。以下示例代码供您参考。

在 RootDialog 中:

[Serializable]
public class RootDialog : IDialog<object>
{
    public Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);

        return Task.CompletedTask;
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var activity = await result as Activity;

        // calculate something for us to return
        int length = (activity.Text ?? string.Empty).Length;

        var contractnumber = "";

        if (!context.UserData.TryGetValue<string>("contract_number", out contractnumber))
        {
            //prompt for contract number

            PromptDialog.Text(
            context: context,
            resume: AfterGetContractNumber,
            prompt: "Please provide your contract number.",
            retry: "Please try again."
        );
        }
        else
        {
            await context.Forward(new BaiscLuisDialog(), AfterLuisDialog, context.Activity, CancellationToken.None);

        }
    }

    private async Task AfterGetContractNumber(IDialogContext context, IAwaitable<string> result)
    {
        string contractnumber = await result;

        context.UserData.SetValue<string>("contract_number", contractnumber);

        await context.PostAsync($"OK, received your contract number: {contractnumber}.");

        context.Done(this);
    }


    private async Task AfterLuisDialog(IDialogContext context, IAwaitable<object> result)
    {
        context.Wait(MessageReceivedAsync);
    }
}

在 BaiscLuisDialog 中:

[LuisIntent("balance")]
public async Task BalanceIntent(IDialogContext context, LuisResult result)
{
    //call BalanceForm
    //and pass contract number that user provided to BalanceForm contract_number
    var balanca = new Microsoft.Bot.Builder.FormFlow.FormDialog<BalanceForm>(new BalanceForm() { contract_number = context.UserData.GetValue<string>("contract_number") }, 
        BalanceForm.BuildForm, 
        Microsoft.Bot.Builder.FormFlow.FormOptions.PromptInStart, 
        result.Entities);

    context.Call<BalanceForm>(balanca, BalanceCompleted);
}

private async Task BalanceCompleted(IDialogContext context, IAwaitable<BalanceForm> result)
{
    context.Wait(MessageReceived);
}

在 BalanceForm 中:

[Serializable]
public class BalanceForm
{
    public string contract_number;

    [Prompt("What is your contract number?")]
    public string contract;

    public string your_other_field;
    public static IForm<BalanceForm> BuildForm()
    {
        OnCompletionAsyncDelegate<BalanceForm> wrapUpRequest = async
        (context, state) =>
        {
            //using (BotModelDataContext BotDb = new BotModelDataContext())
            //{
            //    //search in database 

            //    string wrapUpMessage = "Dear " + house.Firstname + "," + "your  balance is " + house.Balance;
            //    await context.PostAsync(wrapUpMessage);
            //};

            //your code logic here

            var contractnumber = "";

            context.UserData.TryGetValue<string>("contract_number", out contractnumber);

            string wrapUpMessage = " Form completed! Your contract number is " + contractnumber;
            var replymes = context.MakeMessage();
            replymes.Text = wrapUpMessage;

            await context.PostAsync(replymes);
        };

        return new FormBuilder<BalanceForm>()
            .Message("We have to ask you some information")
            .Field(new FieldReflector<BalanceForm>(nameof(contract)).SetActive(state => state.contract_number == null))
            .Field(nameof(your_other_field))
            .OnCompletion(wrapUpRequest)
            //.Confirm("Are you sure: Yes or No ")
            .Build();
    }
}

测试结果:

在此处输入图像描述

于 2018-09-05T07:30:24.670 回答