public RootTopic(ITurnContext context) : base(context) { if (context.GetUserState <BotUserState>().Reservations == null) { context.GetUserState <BotUserState>().Reservations = new List <Reservation>(); } this.SubTopics.Add(ADD_RESERVATION_TOPIC, (object[] args) => { var addReservationTopic = new AddReservationTopic(); addReservationTopic.Set .OnSuccess((ctx, reservation) => { this.ClearActiveTopic(); if (reservation.Confirmed == "yes") { ctx.GetUserState <BotUserState>().Reservations.Add(reservation); context.SendActivity($"Reservation added!"); } else { context.SendActivity("you deleted the reservation"); } }) .OnFailure((ctx, reason) => { this.ClearActiveTopic(); context.SendActivity("It fails for some reasons"); this.ShowDefaultMessage(context); }); return(addReservationTopic); }); }
protected string GetActiveLocale(ITurnContext context) { if (context.Activity.Type == ActivityTypes.Message && !string.IsNullOrEmpty(context.GetUserState <LocaleState>().Locale)) { return(context.GetUserState <LocaleState>().Locale); } return("en-us"); }
public override Task OnTurn(ITurnContext turnContext) { if ((turnContext.Activity.Type == ActivityTypes.Message) && (turnContext.Activity.Text.Length > 0)) { var message = turnContext.Activity; // If the user wants to change the topic of conversation... if (message.Text.ToLowerInvariant() == "add alarm") { // Set the active topic and let the active topic handle this turn. return(SetActiveTopic(ADD_ALARM_TOPIC) .OnTurn(turnContext)); } if (message.Text.ToLowerInvariant() == "delete alarm") { return(SetActiveTopic(DELETE_ALARM_TOPIC, turnContext.GetUserState <BotUserState>().Alarms) .OnTurn(turnContext)); } if (message.Text.ToLowerInvariant() == "show alarms") { ClearActiveTopic(); AlarmsView.ShowAlarms(turnContext, turnContext.GetUserState <BotUserState>().Alarms); return(Task.CompletedTask); } if (message.Text.ToLowerInvariant() == "help") { ClearActiveTopic(); return(ShowHelp(turnContext)); } // If there is an active topic, let it handle this turn until it completes. if (HasActiveTopic) { return(ActiveTopic.OnTurn(turnContext)); } return(ShowDefaultMessage(turnContext)); } return(Task.CompletedTask); }
public async Task ResetState(ITurnContext ctx) { var S = ctx.GetUserState <KGBState>(); S.PavlovState = new PavlovState(); UtteranceQueueMiddleware <KGBState> .Reset(S); await ctx.SendActivity($"Ок, начинаем заново"); }
// below tasks are required to process the search text and return the results public async Task <bool> ProceedWithSearchAsync(ITurnContext context, string facet) { var userState = context.GetUserState <UserData>(); await SearchResponses.ReplyWithSearchConfirmation(context, facet); await StartAsync(context, facet); //end topic return(true); }
public static async Task ShowAlarms(ITurnContext context) { var userState = context.GetUserState <UserData>(); if (userState.Alarms == null) { userState.Alarms = new List <Alarm>(); } await ShowAlarmsTopicResponses.ReplyWithShowAlarms(context, userState.Alarms); }
private Task <bool> SetUserLanguage(ITurnContext context) { var userMessage = context.Activity.Text.ToLowerInvariant(); if (userMessage.StartsWith("set language ")) { context.GetUserState <LanguageState>().Language = userMessage.Substring(13, 5); return(Task.FromResult(true)); } return(Task.FromResult(false)); }
// Add ProcessSearchAsync below // below tasks are required to process the search text and return the results public async Task <bool> ProcessSearchAsync(ITurnContext context) { // store the users response searchText = (context.Activity.Text ?? "").Trim(); var userState = context.GetUserState <UserData>(); await SearchResponses.ReplyWithSearchConfirmation(context, searchText); await StartAsync(context); return(true); }
public override Task OnTurn(ITurnContext context) { if ((context.Activity.Type == ActivityTypes.Message) && (context.Activity.AsMessageActivity().Text.Length > 0)) { var message = context.Activity.AsMessageActivity(); //I can use LUIS here! // If the user wants to change the topic of conversation... if (message.Text.ToLowerInvariant() == "add reservation") { // Set the active topic and let the active topic handle this turn. this.SetActiveTopic(ADD_RESERVATION_TOPIC) .OnTurn(context); return(Task.CompletedTask); } //TODO: implement "delete alarm topic" //if (message.Text.ToLowerInvariant() == "delete alarm") //{ // this.SetActiveTopic(DELETE_ALARM_TOPIC) // .OnReceiveActivity(context); // return Task.CompletedTask; //} if (message.Text.ToLowerInvariant() == "show reservation") { this.ClearActiveTopic(); ReservationView.ShowReservations(context, context.GetUserState <BotUserState>().Reservations); return(Task.CompletedTask); } if (message.Text.ToLowerInvariant() == "help") { this.ClearActiveTopic(); this.ShowHelp(context); return(Task.CompletedTask); } // If there is an active topic, let it handle this turn until it completes. if (HasActiveTopic) { ActiveTopic.OnTurn(context); return(Task.CompletedTask); } ShowDefaultMessage(context); } return(Task.CompletedTask); }
private (UserInfo, DialogContext) CreateContext(ITurnContext context) { var dialogs = new DialogSet(); dialogs.AddCatalogDialog(dialogFactory); dialogs.AddCatalogFilterDialog(dialogFactory); var userState = context.GetUserState <UserInfo>(); var state = context.GetConversationState <eShopBotState>(); var dialogCtx = dialogs.CreateContext(context, state); return(userState, dialogCtx); }
public async Task OnTurn(ITurnContext context) { if (context.Activity.Type == ActivityTypes.ConversationUpdate && context.Activity.MembersAdded.FirstOrDefault()?.Id == context.Activity.Recipient.Id) { await context.SendActivity(_greetingMessage); } else if (context.Activity.Type == ActivityTypes.Message) { var userState = context.GetUserState <UserState>(); if (userState.EpisodeInquiries == null) { userState.EpisodeInquiries = new List <EpisodeInquiry>(); } var state = context.GetConversationState <Dictionary <string, object> >(); var dialogContext = dialogs.CreateContext(context, state); var utterance = context.Activity.Text.ToLowerInvariant(); if (utterance == "cancel") { if (dialogContext.ActiveDialog != null) { await context.SendActivity("Ok... Cancelled"); dialogContext.EndAll(); } else { await context.SendActivity("Nothing to cancel."); } } if (!context.Responded) { await dialogContext.Continue(); if (!context.Responded) { var luisResult = context.Services.Get <RecognizerResult>(LuisRecognizerMiddleware.LuisRecognizerResultKey); var(intent, score) = luisResult.GetTopScoringIntent(); var intentResult = score > LUIS_INTENT_THRESHOLD ? intent : "None"; await dialogContext.Begin(intent, new Dictionary <string, object> { { "LuisResult", luisResult } }); } } } }
/// <summary> /// Main bot OnTurn Implementation /// </summary> /// <param name="context">Turn scoped context containing all the data needed for processing this conversation turn. </param> public async Task OnTurn(ITurnContext context) { if (context.Activity.Type == ActivityTypes.ConversationUpdate && context.Activity.MembersAdded.FirstOrDefault()?.Id == context.Activity.Recipient.Id) { await context.SendActivity("Hi! Welcome to the Mcbeev Commerce Bot."); await context.SendActivity("How can we help you today?\n\nWould you like to **Place a new Order**, **Check your Order History** or **Find an Order Tracking Number**? Or is there something else we can help with?"); } else if (context.Activity.Type == ActivityTypes.Message) { var userState = context.GetUserState <UserState>(); var state = context.GetConversationState <Dictionary <string, object> >(); var dialogContext = dialogs.CreateContext(context, state); var utterance = context.Activity.Text.ToLowerInvariant(); if (utterance == "cancel") { if (dialogContext.ActiveDialog != null) { await context.SendActivity("Ok... Cancelled"); dialogContext.EndAll(); } else { await context.SendActivity("Nothing to cancel."); } } if (!context.Responded) { var dialogArgs = new Dictionary <string, object>(); await dialogContext.Continue(); if (!context.Responded) { var luisResult = context.Services.Get <RecognizerResult>(LuisRecognizerMiddleware.LuisRecognizerResultKey); var(intent, score) = luisResult.GetTopScoringIntent(); var intentResult = score > LUIS_INTENT_THRESHOLD ? intent : "None"; dialogArgs.Add("LuisResult", luisResult); await dialogContext.Begin(intent, dialogArgs); } } } }
public async Task UpdateCatalogFilterUserStateWithTagsAsync(ITurnContext context) { var userState = context.GetUserState <UserInfo>(); var imageFile = await attachmentService.DownloadAttachmentFromActivityAsync(context.Activity); var tags = Enumerable.Empty <string>(); if (imageFile != null) { tags = await productSearchImageService.ClassifyImageAsync(imageFile); } if (userState.CatalogFilter == null) { userState.CatalogFilter = new CatalogFilterData(); } userState.CatalogFilter.Tags = tags.ToArray(); }
public async Task OnTurn(ITurnContext context) { try { GameInfo game = context.GetUserState <GameInfo>(); switch (context.Activity.Type) { case ActivityTypes.ConversationUpdate: foreach (var newMember in context.Activity.MembersAdded) { if (newMember.Id != context.Activity.Recipient.Id) { await context.SendActivity("Hello lets play Monopoly."); } } break; case ActivityTypes.Message: var state = ConversationState <Dictionary <string, object> > .Get(context); var dc = _dialogs.CreateContext(context, state); await dc.Continue(); if (!context.Responded) { await dc.Begin("firstRun"); } if (game.Turn == 0) { await dc.Begin("roll"); game.Turn = 1; } break; } } catch (Exception e) { await context.SendActivity($"Exception: {e.Message}"); } }
private async Task OnMessageAsync(ITurnContext turnContext) { var userState = turnContext.GetUserState <UserTravelState>(); if (userState.Activities == null) { userState.Activities = new List <string>(); } var state = ConversationState <Dictionary <string, object> > .Get(turnContext); var dc = _dialogs.CreateContext(turnContext, state); await dc.Continue(); if (!turnContext.Responded || dc.ActiveDialog == null) { await dc.Begin("Travel"); } }
private async Task <bool> TryHandleInvoke(ITurnContext context, Activity activity) { if (activity.Name != ActivityStateSigninVerifystate) { return(false); } if (activity.Value == null) { return(false); } dynamic payload = activity.Value; if (!TryGetValue(payload, new Func <dynamic, string>(p => (string)p.state.accessToken), out string accessToken)) { return(false); } var userState = context.GetUserState <UserState>(); // TODO Use accessToken to fetch profile information from backend system userState.Email = "*****@*****.**"; userState.FullName = "Mr Foo"; userState.AccessToken = accessToken; // Show confirmation (check success/failure) var state = context.GetConversationState <Dictionary <string, object> >(); var dialogContext = _dialogSet.CreateContext(context, state); await dialogContext.Begin(LoginFlow.LoginConfirmation); // Send invoke response await context.SendActivity(new Activity { Type = "invokeResponse", Value = new InvokeResponse() }); return(true); }
private async Task <bool> ProcessTopicState(ITurnContext context) { string utterance = (context.Activity.Text ?? "").Trim(); var userState = context.GetUserState <UserData>(); // we are using TopicState to remember what we last asked switch (this.TopicState) { case TopicStates.AddingCard: { dynamic payload = context.Activity.Value; if (payload != null) { if (payload.Action == "Submit") { this.Alarm.Title = payload.Title; if (DateTimeOffset.TryParse((string)payload.Day, out DateTimeOffset date)) { if (DateTimeOffset.TryParse((string)payload.Time, out DateTimeOffset time)) { this.Alarm.Time = new DateTimeOffset(date.Year, date.Month, date.Day, time.Hour, time.Minute, time.Second, date.Offset); if (userState.Alarms == null) { userState.Alarms = new List <Alarm>(); } userState.Alarms.Add(this.Alarm); await AddAlarmTopicResponses.ReplyWithAddedAlarm(context, this.Alarm); // end topic return(false); } } } else if (payload.Action == "Cancel") { await AddAlarmTopicResponses.ReplyWithTopicCanceled(context, this.Alarm); // End current topic return(false); } } } return(true); case TopicStates.CancelConfirmation: { dynamic payload = context.Activity.Value; switch ((string)payload.Action) { case "Yes": { await AddAlarmTopicResponses.ReplyWithTopicCanceled(context, this.Alarm); // End current topic return(false); } case "No": { this.TopicState = TopicStates.AddingCard; return(await this.ContinueTopic(context)); } default: { await AddAlarmTopicResponses.ReplyWithCancelReprompt(context, this.Alarm); return(true); } } } default: return(true); } }
public async Task OnTurn(ITurnContext context) { //TODO: is this the right way to handle cards? string utterance = context.Activity.Text; JObject cardData = (JObject)context.Activity.Value; if (cardData != null && cardData.Property("intent") != null) { utterance = cardData["utterance"].ToString(); } var userState = context.GetUserState <CafeBotUserState>(); var conversationState = context.GetConversationState <CafeBotConvState>(); switch (context.Activity.Type) { case ActivityTypes.ConversationUpdate: var newUserName = context.Activity.MembersAdded[0].Name; if (!string.IsNullOrWhiteSpace(newUserName) && newUserName != "Bot") { await context.SendActivity($"Hello {newUserName}! I'm the Cafe bot!"); // remember the user's name userState.name = newUserName; userState.sendCards = true; await context.SendActivity("I can help you find contoso cafe locations, book a table and answer questions about Contoso cafe!"); // send a welcome card if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } } break; case ActivityTypes.Message: // create dialogContext DialogContext dc = _dialogs.CreateContext(context, conversationState); if (utterance == "start over") { //restart the conversation await context.SendActivity("Sure.. Let's start over"); dc.EndAll(); } else { // continue with any active dialogs await dc.Continue(); } if (!context.Responded) { // top level dispatch switch (utterance) { case "hi": await context.SendActivity("Hello, I'm the contoso cafe bot. How can I help you?"); if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } break; case "book table": // await context.SendActivity("I'm still learning to book a table!"); // start waterfall dialog for table booking await dc.Begin("BookTable"); break; case "who are you?": // await context.SendActivity("I'm the cafe bot!"); // start waterfall dialog for who are you? await dc.Begin("WhoAreYou"); break; default: await getQnAResult(context); break; } } break; } }
public async Task OnTurn(ITurnContext context) { //TODO: is this the right way to handle cards? string utterance = context.Activity.Text; JObject cardData = (JObject)context.Activity.Value; if (cardData != null && cardData.Property("intent") != null) { utterance = cardData["utterance"].ToString(); } System.Threading.CancellationToken ct; CafeBotUserState userState = context.GetUserState <CafeBotUserState>(); CafeBotConvState conversationState = context.GetConversationState <CafeBotConvState>(); switch (context.Activity.Type) { case ActivityTypes.ConversationUpdate: var newUserName = context.Activity.MembersAdded[0].Name; if (!string.IsNullOrWhiteSpace(newUserName) && newUserName != "Bot") { await context.SendActivity($"Hello {newUserName}! I'm the Cafe bot!"); // remember the user's name userState.name = newUserName; userState.sendCards = true; await context.SendActivity("I can help you find contoso cafe locations, book a table and answer questions about Contoso cafe!"); // send a welcome card if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } } break; case ActivityTypes.Message: // create dialogContext DialogContext dc = _dialogs.CreateContext(context, conversationState); if (utterance == "start over") { //restart the conversation await context.SendActivity("Sure.. Let's start over"); dc.EndAll(); } else { // continue with any active dialogs await dc.Continue(); } if (!context.Responded) { // call LUIS and get results LuisRecognizer lRecognizer = createLUISRecognizer(); cafeLUISModel lResult = await lRecognizer.Recognize <cafeLUISModel>(utterance, ct); Dictionary <string, object> lD = new Dictionary <string, object>(); if (lResult != null) { lD.Add("luisResult", lResult); } // top level dispatch switch (lResult.TopIntent().intent) { case cafeLUISModel.Intent.Greeting: await context.SendActivity("Hello, I'm the contoso cafe bot. How can I help you?"); if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } break; case cafeLUISModel.Intent.Book_Table: await dc.Begin("BookTable", lD); break; case cafeLUISModel.Intent.Who_are_you_intent: await dc.Begin("WhoAreYou"); break; case cafeLUISModel.Intent.None: default: await getQnAResult(context); break; } } break; } }
public async Task OnTurn(ITurnContext context) { //TODO: is this the right way to handle cards? string utterance = context.Activity.Text; JObject cardData = (JObject)context.Activity.Value; if (cardData != null && cardData.Property("intent") != null) { utterance = cardData["utterance"].ToString(); } var userState = context.GetUserState <CafeBotUserState>(); var conversationState = context.GetConversationState <CafeBotConvState>(); switch (context.Activity.Type) { case ActivityTypes.ConversationUpdate: var newUserName = context.Activity.MembersAdded[0].Name; if (!string.IsNullOrWhiteSpace(newUserName) && newUserName != "Bot" && string.IsNullOrEmpty(userState.name)) { await context.SendActivity($"Hello {newUserName}! I'm the Cafe bot!"); // remember the user's name userState.name = newUserName; userState.sendCards = true; await context.SendActivity("I can help you find contoso cafe locations, book a table and answer questions about Contoso cafe!"); // send a welcome card if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } } break; case ActivityTypes.Message: // create dialogContext var dc = _dialogs.CreateContext(context, conversationState); // continue with any active dialogs await dc.Continue(); if (!context.Responded) { // top level dispatch switch (utterance) { case "hi": await context.SendActivity("Hello, I'm the contoso cafe bot. How can I help you?"); if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } break; case "book table": await dc.Begin("BookTable"); break; case "who are you?": await dc.Begin("WhoAreYou"); break; default: await context.SendActivity("Sorry, I do not understand."); await context.SendActivity("You can say hi or book table or find locations"); // var qEndpoint = new QnAMakerEndpoint() // { // Host = "https://contosocafeqnamaker.azurewebsites.net/qnamaker", // EndpointKey = "09e2d55b-a44c-41b6-a08a-76a7df9ddffe", // KnowledgeBaseId = "b5534d70-bded-45e1-998a-5945174d4ff3" // }; // var qOptions = new QnAMakerOptions() // { // ScoreThreshold = 0.4F, // Top = 1 // }; // var qnamaker = new QnAMaker(qEndpoint, qOptions); // QueryResult[] qResult = await qnamaker.GetAnswers(context.Activity.Text); // if(qResult.Length == 0) // { // await context.SendActivity("Sorry, I do not understand."); // await context.SendActivity("You can say hi or book table or find locations"); // } else // { // await context.SendActivity(qResult[0].Answer); // } break; } } break; } }
private string GetUserLanguage(ITurnContext context) { return(context.GetUserState <LanguageState>().Language ?? "en-us"); }
public async Task <bool> FindAlarm(ITurnContext context) { var userState = context.GetUserState <UserData>(); if (userState.Alarms == null) { userState.Alarms = new List <Alarm>(); } // Ensure there are alarms to delete if (userState.Alarms.Count == 0) { await DeleteAlarmTopicResponses.ReplyWithNoAlarms(context); return(false); } // Validate title if (!String.IsNullOrWhiteSpace(this.AlarmTitle)) { if (int.TryParse(this.AlarmTitle.Split(' ').FirstOrDefault(), out int index)) { if (index > 0 && index <= userState.Alarms.Count) { index--; // Delete selected alarm and end topic var alarm = userState.Alarms.Skip(index).First(); userState.Alarms.Remove(alarm); await DeleteAlarmTopicResponses.ReplyWithDeletedAlarm(context, alarm); return(false); // cancel topic } } else { var parts = this.AlarmTitle.Split(' '); var choices = userState.Alarms.Where(alarm => parts.Any(part => alarm.Title.Contains(part))).ToList(); if (choices.Count == 0) { await DeleteAlarmTopicResponses.ReplyWithNoAlarmsFound(context, this.AlarmTitle); return(false); } else if (choices.Count == 1) { // Delete selected alarm and end topic var alarm = choices.First(); userState.Alarms.Remove(alarm); await DeleteAlarmTopicResponses.ReplyWithDeletedAlarm(context, alarm); return(false); // cancel topic } } } // Prompt for title await DeleteAlarmTopicResponses.ReplyWithTitlePrompt(context, userState.Alarms); return(true); }
private void SetLanguage(ITurnContext context, string language) => context.GetUserState <LanguageState>().Language = language;
public async Task OnTurn(ITurnContext context) { //TODO: is this the right way to handle cards? string utterance = context.Activity.Text; JObject cardData = (JObject)context.Activity.Value; if (cardData != null && cardData.Property("intent") != null) { utterance = cardData["utterance"].ToString(); } var userState = context.GetUserState <CafeBotUserState>(); var conversationState = context.GetConversationState <CafeBotConvState>(); switch (context.Activity.Type) { case ActivityTypes.ConversationUpdate: var newUserName = context.Activity.MembersAdded[0].Name; if (!string.IsNullOrWhiteSpace(newUserName) && newUserName != "Bot" && string.IsNullOrEmpty(userState.name)) { await context.SendActivity($"Hello {newUserName}! I'm the Cafe bot!"); // remember the user's name userState.name = newUserName; //userState.sendCards = true; await context.SendActivity("I can help you find contoso cafe locations, book a table and answer questions about Contoso cafe!"); // send a welcome card if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } } break; case ActivityTypes.Message: // create dialogContext var dc = _dialogs.CreateContext(context, conversationState); // continue with any active dialogs await dc.Continue(); if (!context.Responded) { // call LUIS and get results LuisRecognizerOptions lOptions = new LuisRecognizerOptions() { Verbose = true }; LuisModel lModel = new LuisModel( "edaadd9b-b632-4733-a25c-5b67271035dd", "be30825b782843dcbbe520ac5338f567", new System.Uri("https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/"), Microsoft.Cognitive.LUIS.LuisApiVersion.V2); LuisRecognizer lRecognizer = new LuisRecognizer(lModel, lOptions); System.Threading.CancellationToken ct; cafeLUISModel lResult = await lRecognizer.Recognize <cafeLUISModel>(context.Activity.Text, ct); // top level dispatch switch (lResult.TopIntent().intent) { case cafeLUISModel.Intent.Greeting: //case "hi": await context.SendActivity("Hello, I'm the contoso cafe bot. How can I help you?"); if (userState.sendCards) { await context.SendActivity(CreateCardResponse(context.Activity, createWelcomeCardAttachment())); } break; case cafeLUISModel.Intent.Book_Table: // case "book table": await dc.Begin("BookTable"); break; case cafeLUISModel.Intent.Who_are_you_intent: // case "who are you?": await dc.Begin("WhoAreYou"); break; case cafeLUISModel.Intent.None: default: var qEndpoint = new QnAMakerEndpoint() { Host = "https://contosocafeqnamaker.azurewebsites.net/qnamaker", EndpointKey = "09e2d55b-a44c-41b6-a08a-76a7df9ddffe", KnowledgeBaseId = "b5534d70-bded-45e1-998a-5945174d4ff3" }; var qOptions = new QnAMakerOptions() { ScoreThreshold = 0.4F, Top = 1 }; var qnamaker = new QnAMaker(qEndpoint, qOptions); QueryResult[] qResult = await qnamaker.GetAnswers(context.Activity.Text); if (qResult.Length == 0) { await context.SendActivity("Sorry, I do not understand."); await context.SendActivity("You can say hi or book table or find locations"); } else { await context.SendActivity(qResult[0].Answer); } //await context.SendActivity("Sorry, I do not understand."); //await context.SendActivity("You can say hi or book table or find locations"); break; } } break; } }
private void SetLocale(ITurnContext context, string locale) => context.GetUserState <LocaleState>().Locale = locale;
public RootTopic(ITurnContext turnContext) : base(turnContext) { // User state initialization should be done once in the welcome // new user feature. Placing it here until that feature is added. if (turnContext.GetUserState <BotUserState>().Alarms == null) { turnContext.GetUserState <BotUserState>().Alarms = new List <Alarm>(); } this.SubTopics.Add(ADD_ALARM_TOPIC, (object[] args) => { var addAlarmTopic = new AddAlarmTopic(); addAlarmTopic.Set .OnSuccess((turn, alarm) => { ClearActiveTopic(); turn.GetUserState <BotUserState>().Alarms.Add(alarm); turn.SendActivity($"Added alarm named '{ alarm.Title }' set for '{ alarm.Time }'."); }) .OnFailure((turn, reason) => { ClearActiveTopic(); turn.SendActivity("Let's try something else."); ShowDefaultMessage(turnContext); }); return(addAlarmTopic); }); this.SubTopics.Add(DELETE_ALARM_TOPIC, (object[] args) => { var alarms = (args.Length > 0) ? (List <Alarm>)args[0] : null; var deleteAlarmTopic = new DeleteAlarmTopic(alarms); deleteAlarmTopic.Set .OnSuccess((turn, value) => { this.ClearActiveTopic(); if (!value.DeleteConfirmed) { turn.SendActivity($"Ok, I won't delete alarm '{ value.Alarm.Title }'."); return; } turn.GetUserState <BotUserState>().Alarms.RemoveAt(value.AlarmIndex); turn.SendActivity($"Done. I've deleted alarm '{ value.Alarm.Title }'."); }) .OnFailure((turn, reason) => { ClearActiveTopic(); turn.SendActivity("Let's try something else."); ShowDefaultMessage(turn); }); return(deleteAlarmTopic); }); }