用户从聊天机器人中的快速回复中选择一个选项后如何调用表单流

How to call formflow after user choose an option from quickreply in chatbot

我正在创建一个用于停车的聊天机器人。

当聊天启动带有 3 个按钮的应用程序附件菜单时。 当您单击第一个按钮时,将显示带有一些选项的快速回复。当用户选择第一个选项时,我想为选项 1 启动表单流,然后当用户选择选项 2 时,再次启动此表单流。

我附上了我的代码,你能帮帮我吗?

这是 messagecontroller.cs 的代码:

namespace Project1
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Autofac;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Connector;
using Properties;
using Dialogs;
using Microsoft.Bot.Builder.FormFlow;
using Microsoft.Bot.Builder.Dialogs;
using FormFlow;
using Models;

[BotAuthentication]
public class MessagesController : ApiController {
    private IMessageActivity activity;

    public string cityRange{
        get;
        private set;
    }

    private static IForm<Enquiry> buildEnquiryForm() {
        var builder = new FormBuilder<Enquiry>();

        public async Task<HttpResponseMessage> Post([FromBody]Activity activity){
            if (activity.Type == ActivityTypes.Message){

                // The Configured IISExpressSSLPort property in this project file

                const int ConfiguredHttpsPort = 44371;

                var link = Url.Link("CheckOut", new{ controller = "CheckOut", action = "Index" });
                var uriBuilder = new UriBuilder(link){
                    Scheme = Uri.UriSchemeHttps,
                    Port = ConfiguredHttpsPort
                };
                var checkOutRouteUri = uriBuilder.Uri.ToString();

                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity)){
                    var dialog = scope.Resolve<IDialog<object>>(TypedParameter.From(checkOutRouteUri));
                    await Conversation.SendAsync(activity, () = > dialog);
                }
            }
            else{
                await this.HandleSystemMessage(activity);
            }

            var response = Request.CreateResponse(HttpStatusCode.OK);
            return response;
        }

        internal static IDialog<ContactMessage> dialog(){
            return Chain.From(() = > FormDialog.FromForm(ContactMessage.BuildForm));
        }


        private async Task HandleSystemMessage(Activity message){
            if (message.Type == ActivityTypes.DeleteUserData){
                // Implement user deletion here
                // If we handle user deletion, return a real message
            }
            else if (message.Type == ActivityTypes.ConversationUpdate){
                if (message.MembersAdded.Any(o = > o.Id == message.Recipient.Id)){
                    var reply = message.CreateReply(Resources.RootDialog_Welcome_Message);

                    ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl));

                    await connector.Conversations.ReplyToActivityAsync(reply);
                }
            }
            else if (message.Type == ActivityTypes.ContactRelationUpdate){}

            else if (message.Type == cityRange && cityRange == "A"){
                await Conversation.SendAsync(activity, () = > new FormFlow.Enquiry());
            }

            else if (message.Type == ActivityTypes.Typing){
                // Handle knowing tha the user is typing
            }
            else if (message.Type == ActivityTypes.Ping) {}
        }
    }
}

联系信息是:

using Microsoft.Bot.Builder.FormFlow;
using System;
using Microsoft.Bot.Builder.Dialogs;
using System.Threading.Tasks;

namespace Project1.Models{
    [Serializable]
    public class ContactMessage{
        public string Name{
            get;
            set;
        }
        public string Address{
            get;
            set;
        }
        public string ContactNumber{
            get;
            set;
        }
        public string Email{
            get;
            set; 
        }
        public ContactMethod PreferredContactMethod{
            get;
            set;
        }
        public string Message{
            get;
            set;
        }

        public static IForm<ContactMessage> BuildForm(){
            return new FormBuilder<ContactMessage>()
            .Message("I just need a few details to submit your message")
            .Build();
        }
    }

    public enum ContactMethod{
        IGNORE,
        Telephone,
        SMS,
        Email
    }
}

我想在 Rootdialog.cs 的这部分代码中调用表单:

private async Task WelcomeMessageAsync(IDialogContext context){
    var reply = context.MakeMessage();

    var options = new[] {
        Resources.RootDialog_Welcome_Start,
        Resources.RootDialog_Welcome_Stop,
    };
    reply.AddHeroCard(
        Resources.RootDialog_Welcome_Title,
        Resources.RootDialog_Welcome_Subtitle,
        options,
        new[] { "" }
    );

    await context.PostAsync(reply);

    context.Wait(this.OnOptionSelected);
}

private async Task OnOptionSelected(IDialogContext context, IAwaitable<IMessageActivity> result){
    var message = await result;

    //if you choose start parking
    if (message.Text == Resources.RootDialog_Welcome_Start) {
        this.order = new Models.Order();

        var promptOptions = new PromptOptions<string>(
            "Please select the city where you want to park:",
            options: new[] { "A", "B", "C" },
            promptStyler : new FacebookQuickRepliesPromptStyler()
        );

        PromptDialog.Choice(context, this.ResumeAfterSelection, promptOptions);

    }

    else if (message.Text == Resources.RootDialog_Welcome_Stop){}
}

private async Task ResumeAfterSelection(IDialogContext context, IAwaitable<string> result){
    try {
        var cityRange = await result;
        if (cityRange == "A"){

            //  **I WANT TO CALL HERE MY FORMFLOW**  


            //  context.Call(FormDialog.FromForm<Enquiry>(Enquiry.BuildEnquiryForm, FormOptions.PromptInStart), async (ctx, formResult) => ctx.Wait(this.MessageReceivedAsync));

            //  var myform = new FormDialog<Enquiry>(new Enquiry(), Enquiry.BuildEnquiryForm, FormOptions.PromptInStart, null);

            //  context.Call(myform, ResumeAfterCallback);
            //// Chain.From(() => new Enquiry(buildEnquiryForm));

            //var orderForm = new FormDialog<Models.Order>(this.order, Models.Order.BuildOrderForm, FormOptions.PromptInStart);
            //context.Call(orderForm, this.AfterOrderForm);
            // }

            //   await Conversation.SendAsync(activity, Enquiry);

            Chain.From(() = > FormDialog.FromForm(ContactMessage.BuildForm));

当我尝试以这种模式呼叫时:

我将我的代码打印如下

controller.cs enquiry.cs

我在用户选择快速回复后调用表单流:

 await Conversation.SendAsync(activity, () => new Enquiry());

我接受这个错误:异常:在激活特定注册期间发生错误。有关详细信息,请参阅内部异常。 Registration: Activator = IMessageActivity (DelegateActivator), Services = [Microsoft.Bot.Connector.IMessageActivity, Microsoft.Bot.Connector.IActivity], Lifetime = Autofac.Core.Lifetime.MatchingScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope —> 一个委托注册创建实例' Microsoft.Bot.Connector.IMessageActivity' 返回空值。 (有关详细信息,请参阅内部异常。) [文件类型 'text/plain']