public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { _userProfilePersistentAccessor = _userPersistentState.CreateProperty <UserProfilePersistent>(nameof(UserProfilePersistent)); var userProfilePersistent = await _userProfilePersistentAccessor.GetAsync(turnContext, () => new UserProfilePersistent()); _userProfileTemporaryAccessor = _userTemporaryState.CreateProperty <UserProfileTemporary>(nameof(UserProfileTemporary)); var userProfileTemporary = await _userProfileTemporaryAccessor.GetAsync(turnContext, () => new UserProfileTemporary()); _conversationDataAccessor = _conversationState.CreateProperty <ConversationData>(nameof(ConversationData)); var conversationData = await _conversationDataAccessor.GetAsync(turnContext, () => new ConversationData()); // Print info about image attachments //if (turnContext.Activity.Attachments != null) //{ // await turnContext.SendActivityAsync(JsonConvert.SerializeObject(turnContext.Activity.Attachments), cancellationToken: cancellationToken); //} // Save user's ID userProfilePersistent.UserId = userProfileTemporary.UserId = Helpers.Sha256Hash(turnContext.Activity.From.Id); // Add message details to the conversation data. var messageTimeOffset = (DateTimeOffset)turnContext.Activity.Timestamp; var localMessageTime = messageTimeOffset.ToLocalTime(); conversationData.Timestamp = localMessageTime.ToString(); await _conversationDataAccessor.SetAsync(turnContext, conversationData); // TODO: most of the logic/functionality in the following if statements I realised later on should probably be structured in the way the Bot Framework SDK talks about "middleware". // Maybe one day re-structure/re-factor it to following their middleware patterns... var botSrc = WebSrc.nonweb; if (InterceptWebBotSource(turnContext, out botSrc)) { userProfileTemporary.BotSrc = botSrc; await _userProfileTemporaryAccessor.SetAsync(turnContext, userProfileTemporary); } double lat = 0, lon = 0; string pushUserId = null; userProfileTemporary.PushUserId = userProfilePersistent.PushUserId; if (InterceptPushNotificationSubscription(turnContext, out pushUserId)) { if (userProfilePersistent.PushUserId != pushUserId) { userProfilePersistent.PushUserId = userProfileTemporary.PushUserId = pushUserId; await _userProfilePersistentAccessor.SetAsync(turnContext, userProfilePersistent); await _userProfileTemporaryAccessor.SetAsync(turnContext, userProfileTemporary); } } else if (Helpers.InterceptLocation(turnContext, out lat, out lon)) // Intercept any locations the user sends us, no matter where in the conversation they are { bool validCoords = true; if (lat == Consts.INVALID_COORD && lon == Consts.INVALID_COORD) { // Do a geocode query lookup against the address the user sent var result = await Helpers.GeocodeAddressAsync(turnContext.Activity.Text.ToLower().Replace("search", "")); if (result != null) { lat = result.Item1; lon = result.Item2; } else { await turnContext.SendActivityAsync(MessageFactory.Text("Place not found."), cancellationToken); validCoords = false; } } if (validCoords) { // Update user's location userProfileTemporary.Latitude = lat; userProfileTemporary.Longitude = lon; await turnContext.SendActivityAsync(MessageFactory.Text($"New location confirmed @ {lat},{lon}"), cancellationToken); var incoords = new double[] { lat, lon }; var w3wResult = await Helpers.GetWhat3WordsAddressAsync(incoords); await turnContext.SendActivitiesAsync(CardFactory.CreateLocationCardsReply(Enum.Parse <ChannelPlatform>(turnContext.Activity.ChannelId), incoords, userProfileTemporary.IsDisplayGoogleThumbnails, w3wResult), cancellationToken); await _userProfileTemporaryAccessor.SetAsync(turnContext, userProfileTemporary); await _userTemporaryState.SaveChangesAsync(turnContext, false, cancellationToken); userProfilePersistent.HasSetLocationOnce = true; await _userProfilePersistentAccessor.SetAsync(turnContext, userProfilePersistent); await _userPersistentState.SaveChangesAsync(turnContext, false, cancellationToken); await((AdapterWithErrorHandler)turnContext.Adapter).RepromptMainDialog(turnContext, _mainDialog, cancellationToken); return; } } else if (!string.IsNullOrEmpty(turnContext.Activity.Text) && turnContext.Activity.Text.EndsWith("help", StringComparison.InvariantCultureIgnoreCase)) { await Helpers.HelpAsync(turnContext, userProfileTemporary, _mainDialog, cancellationToken); } else if (!string.IsNullOrEmpty(turnContext.Activity.Text) && ( turnContext.Activity.Text.ToLower().StartsWith("/steve", StringComparison.InvariantCultureIgnoreCase) || turnContext.Activity.Text.ToLower().StartsWith("/newsteve22", StringComparison.InvariantCultureIgnoreCase) || turnContext.Activity.Text.ToLower().StartsWith("/ongshat", StringComparison.InvariantCultureIgnoreCase) )) { await new ActionHandler().ParseSlashCommands(turnContext, userProfileTemporary, cancellationToken, _mainDialog); await _userProfileTemporaryAccessor.SetAsync(turnContext, userProfileTemporary); await _userPersistentState.SaveChangesAsync(turnContext, false, cancellationToken); await _userTemporaryState.SaveChangesAsync(turnContext, false, cancellationToken); return; } else if (!string.IsNullOrEmpty(turnContext.Activity.Text) && !userProfileTemporary.IsLocationSet) { await turnContext.SendActivityAsync(MessageFactory.Text(Consts.NO_LOCATION_SET_MSG), cancellationToken); // Hack coz Facebook Messenge stopped showing "Send Location" button if (turnContext.Activity.ChannelId.Equals("facebook")) { await turnContext.SendActivityAsync(CardFactory.CreateGetLocationFromGoogleMapsReply()); } return; } else if (!string.IsNullOrEmpty(turnContext.Activity.Text) && turnContext.Activity.Text.StartsWith("/", StringComparison.InvariantCulture)) { await new ActionHandler().ParseSlashCommands(turnContext, userProfileTemporary, cancellationToken, _mainDialog); await _userProfileTemporaryAccessor.SetAsync(turnContext, userProfileTemporary); await _userPersistentState.SaveChangesAsync(turnContext, false, cancellationToken); await _userTemporaryState.SaveChangesAsync(turnContext, false, cancellationToken); return; } await base.OnTurnAsync(turnContext, cancellationToken); // Save any state changes that might have occured during the turn. await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken); await _userPersistentState.SaveChangesAsync(turnContext, false, cancellationToken); await _userTemporaryState.SaveChangesAsync(turnContext, false, cancellationToken); }
private async Task <DialogTurnResult> ChoiceActionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { if (Helpers.IsRandoLobby(stepContext.Context)) { // Don't spam Randonauts Telegram Lobby with dialog menus as they get sent to everyone return(await stepContext.EndDialogAsync(cancellationToken : cancellationToken)); } // Shortcut to trip report dialog testing //return await stepContext.ReplaceDialogAsync(nameof(TripReportDialog), new CallbackOptions(), cancellationToken); var userProfilePersistent = await _userProfilePersistentAccessor.GetAsync(stepContext.Context, () => new UserProfilePersistent()); var userProfileTemporary = await _userProfileTemporaryAccessor.GetAsync(stepContext.Context, () => new UserProfileTemporary()); // Must agree to Privacy Policy and Terms of Service before using if (!userProfilePersistent.HasAgreedToToS) { await stepContext.EndDialogAsync(cancellationToken : cancellationToken); return(await stepContext.BeginDialogAsync(nameof(PrivacyAndTermsDialog), this, cancellationToken)); } if (stepContext.Options != null) { // Callback options passed after resuming dialog after long-running background threads etc have finished // and resume dialog via the Adapter class's callback method. var callbackOptions = (CallbackOptions)stepContext.Options; if (callbackOptions.ResetFlag) { userProfileTemporary.IsScanning = false; await _userProfileTemporaryAccessor.SetAsync(stepContext.Context, userProfileTemporary, cancellationToken); await _userTemporaryState.SaveChangesAsync(stepContext.Context, false, cancellationToken); } if (callbackOptions.StartTripReportDialog) { return(await stepContext.ReplaceDialogAsync(nameof(TripReportDialog), callbackOptions, cancellationToken)); } if (callbackOptions.UpdateIntentSuggestions) { userProfileTemporary.IntentSuggestions = callbackOptions.IntentSuggestions; userProfileTemporary.TimeIntentSuggestionsSet = callbackOptions.TimeIntentSuggestionsSet; await _userProfileTemporaryAccessor.SetAsync(stepContext.Context, userProfileTemporary, cancellationToken); await _userTemporaryState.SaveChangesAsync(stepContext.Context, false, cancellationToken); } if (callbackOptions.UpdateSettings) { userProfilePersistent.IsIncludeWaterPoints = userProfileTemporary.IsIncludeWaterPoints; userProfilePersistent.IsDisplayGoogleThumbnails = userProfileTemporary.IsDisplayGoogleThumbnails; await _userProfilePersistentAccessor.SetAsync(stepContext.Context, userProfilePersistent, cancellationToken); await _userPersistentState.SaveChangesAsync(stepContext.Context, false, cancellationToken); } } // Make sure the persistent settings are in synch with the temporary ones bool doSync = false; if (userProfileTemporary.IsIncludeWaterPoints != userProfilePersistent.IsIncludeWaterPoints) { userProfileTemporary.IsIncludeWaterPoints = userProfilePersistent.IsIncludeWaterPoints; doSync = true; } if (userProfileTemporary.IsDisplayGoogleThumbnails != userProfilePersistent.IsDisplayGoogleThumbnails) { userProfileTemporary.IsDisplayGoogleThumbnails = userProfilePersistent.IsDisplayGoogleThumbnails; doSync = true; } if (doSync) { await _userTemporaryState.SaveChangesAsync(stepContext.Context, false, cancellationToken); } //_logger.LogInformation("MainDialog.ChoiceActionStepAsync"); var options = new PromptOptions() { Prompt = MessageFactory.Text("What would you like to get?"), RetryPrompt = MessageFactory.Text("That is not a valid action. What would you like to get?"), Choices = GetActionChoices(stepContext.Context), }; return(await stepContext.PromptAsync(nameof(ChoicePrompt), options, cancellationToken)); }