Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }