我在C#中使用Dialogs创建了一个表单流程机器人。这是我的机器人代码 -
这是 RootDialog.cs
[Serializable]
public class RootDialog : IDialog<object>
{
#region Fields
private const string SearchFileOption = "Search files";
private const string QueryKBOption = "Query Knowledge Base";
#endregion
public async Task StartAsync(IDialogContext context)
{
context.Wait(this.MessageReceivedAsync);
}
public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> activity)
{
this.ShowMenuOptions(context);
}
public virtual async Task ChoiceReceivedAsync(IDialogContext context, IAwaitable<string> activity)
{
try
{
string optionSelected = await activity;
switch (optionSelected)
{
case SearchFileOption:
context.Call(new SearchDialog(), ChildDialogComplete);
break;
case QueryKBOption:
context.Call(new QueryDialog(), ChildDialogComplete);
break;
}
}
catch (TooManyAttemptsException ex)
{
await context.PostAsync($"Ooops! Too many attempts :(. But don't worry, I'm handling that exception and you can try again!");
context.Wait(this.MessageReceivedAsync);
}
}
public virtual async Task ChildDialogComplete(IDialogContext context, IAwaitable<object> response)
{
this.StartOverAgain(context);
}
#region Prompts
private void ShowMenuOptions(IDialogContext context)
{
PromptDialog.Choice(context: context, resume: ChoiceReceivedAsync, options: new List<string>() { SearchFileOption, QueryKBOption }, prompt: "What would you like to do today?", retry: "Selected option not available. Please try again.", attempts: 3);
}
private void StartOverAgain(IDialogContext context)
{
PromptDialog.Choice(context: context, resume: AskConfirmation, prompt: "Would you like to start over again?", retry: "Sorry, I didn't understand that. Please try again.", options: (IEnumerable<ConfirmationChoices>)Enum.GetValues(typeof(ConfirmationChoices)));
}
public virtual async Task AskConfirmation(IDialogContext context, IAwaitable<ConfirmationChoices> Query)
{
var response = await Query;
if (response == ConfirmationChoices.Yes)
{
this.ShowMenuOptions(context);
}
else
{
await context.PostAsync("Thank you.");
context.Done(this);
}
}
#endregion
}
这是 QueryDialog.cs
[Serializable]
public class QueryDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Welcome to the QnA Service!");
this.AskQuery(context);
}
public virtual async Task GetQueryAnswer(IDialogContext context, IAwaitable<string> Query)
{
string response = await Query;
await context.PostAsync(QnAFunctions.GetAnswer(response));
this.AskConfirmQuestion(context);
}
public virtual async Task AskConfirmation(IDialogContext context, IAwaitable<ConfirmationChoices> Query)
{
var response = await Query;
if (response == ConfirmationChoices.Yes)
{
this.AskQuery(context);
}
else
{
context.Done(this);
}
}
#region Prompts
private void AskQuery(IDialogContext context)
{
PromptDialog.Text(context: context,resume: GetQueryAnswer, prompt: "Please share your query", retry: "Sorry, I didn't understand that. Please try again.");
}
private void AskConfirmQuestion(IDialogContext context)
{
PromptDialog.Choice(
context: context, resume: AskConfirmation, prompt: "Do have any other query?", retry: "Sorry, I didn't understand that. Please try again.", options: (IEnumerable<ConfirmationChoices>)Enum.GetValues(typeof(ConfirmationChoices)));
}
#endregion
}
同样,我准备了 SearchDialog.cs
这是我的 MessagesController.cs
[BotAuthentication]
public class MessagesController : ApiController
{
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new RootDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
if (message.MembersAdded.Any(o => o.Id == message.Recipient.Id))
{
ConnectorClient connector = new ConnectorClient(new System.Uri(message.ServiceUrl));
Activity reply = message.CreateReply("Hi!, I am your service provider virtual assistant. ");
connector.Conversations.ReplyToActivityAsync(reply);
}
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
}
else if (message.Type == ActivityTypes.Typing)
{
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
我正在尝试将此bot嵌入我的自定义聊天窗口,这是MVC应用程序的一部分。
以下是我试图调用bot的代码。
public string TalkToTheBot2(string paramMessage)
{
DirectLineClient client = new DirectLineClient(DirectLineSecret);
Conversation conversation = System.Web.HttpContext.Current.Session["conversation"] as Conversation;
string watermark = System.Web.HttpContext.Current.Session["watermark"] as string;
if (conversation == null)
{
conversation = client.Conversations.StartConversation();
}
Activity message = new Activity
{
Text = paramMessage,
From = new ChannelAccount(),
Type = ActivityTypes.Event
};
var result = client.Conversations.PostActivityAsync(conversation.ConversationId, message).Result;
Chat objChat = ReadBotMessagesAsync(client, conversation.ConversationId, watermark);
System.Web.HttpContext.Current.Session["conversation"] = conversation;
System.Web.HttpContext.Current.Session["watermark"] = objChat.watermark;
objChat.ChatMessage = paramMessage;
return JsonConvert.SerializeObject(objChat);
}
private Chat ReadBotMessagesAsync(DirectLineClient client, string conversationId, string watermark)
{
Chat objChat = new Chat();
bool messageReceived = false;
while (!messageReceived)
{
var activitySet = client.Conversations.GetActivitiesAsync(conversationId, watermark).Result;
watermark = activitySet?.Watermark;
var activities = from x in activitySet.Activities
where x.From.Id == botId
select x;
foreach (Activity message in activities)
{
if (message.Text != null)
{
objChat.ChatResponse
+= " "
+ message.Text.Replace("\n\n", "<br />");
}
if (message.Attachments.Count > 0)
{
objChat.ChatResponse
+= " "
+ RenderImageHTML(message.Attachments[0].ContentUrl);
}
}
messageReceived = true;
}
objChat.watermark = watermark;
return objChat;
}
此代码无效。当我第一次发布TalkToTheBot2('Hi')
时,它会返回我在'Hi!, I am your service provider virtual assistant.'
中定义的消息MessagesController
。在此之后,如果我再次致电TalkToTheBot2('Hi')
,则会返回null
。