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); }
public MainDialog(UserPersistentState userPersistentState, UserTemporaryState userTemporaryState, ConversationState conversationState, ILogger <MainDialog> logger, IBotTelemetryClient telemetryClient) : base(nameof(MainDialog)) { _logger = logger; _userPersistentState = userPersistentState; _userTemporaryState = userTemporaryState; TelemetryClient = telemetryClient; if (_userPersistentState != null) { _userProfilePersistentAccessor = userPersistentState.CreateProperty <UserProfilePersistent>(nameof(UserProfilePersistent)); } if (userTemporaryState != null) { _userProfileTemporaryAccessor = userTemporaryState.CreateProperty <UserProfileTemporary>(nameof(UserProfileTemporary)); } AddDialog(new PrivacyAndTermsDialog(_userProfilePersistentAccessor, logger, telemetryClient)); AddDialog(new MoreStuffDialog(_userProfileTemporaryAccessor, this, logger, telemetryClient)); AddDialog(new TripReportDialog(_userProfileTemporaryAccessor, this, logger, telemetryClient)); AddDialog(new ScanDialog(_userProfileTemporaryAccessor, this, logger, telemetryClient)); AddDialog(new SettingsDialog(_userProfileTemporaryAccessor, logger, telemetryClient)); AddDialog(new ChoicePrompt(nameof(ChoicePrompt)) { TelemetryClient = telemetryClient, }); AddDialog(new ChoicePrompt("AskHowManyIDAsChoicePrompt", (PromptValidatorContext <FoundChoice> promptContext, CancellationToken cancellationToken) => { // override validater result to also allow free text entry for ratings int idacou; if (int.TryParse(promptContext.Context.Activity.Text, out idacou)) { if (idacou < 1 || idacou > 20) { return(Task.FromResult(false)); } return(Task.FromResult(true)); } return(Task.FromResult(false)); }) { TelemetryClient = telemetryClient, }); AddDialog(new TextPrompt("GetQRNGSourceChoicePrompt", (PromptValidatorContext <string> promptContext, CancellationToken cancellationToken) => { // verify it's a 64 char hex string (sha256 of the entropy generated) if (promptContext.Context.Activity.Text.Length != 64) { return(Task.FromResult(false)); } // regex check Regex regex = new Regex("^[a-fA-F0-9]+$"); return(Task.FromResult(regex.IsMatch(promptContext.Context.Activity.Text))); }) { TelemetryClient = telemetryClient, }); AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[] { ChoiceActionStepAsync, PerformActionStepAsync, AskHowManyIDAsStepAsync, SelectQRNGSourceStepAsync, GetQRNGSourceStepAsync, GenerateIDAsStepAsync }) { TelemetryClient = telemetryClient, }); InitialDialogId = nameof(WaterfallDialog); }