public Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken token, Action cancel, SignalDelegate signal, NextDelegate next)
        {
            request.Headers.Add("x-ms-client-request-id", processRecordId);
            request.Headers.Add("CommandName", invocationInfo?.InvocationName);
            request.Headers.Add("FullCommandName", invocationInfo?.MyCommand?.Name);
            request.Headers.Add("ParameterSetName", parameterSetName);

            // continue with pipeline.
            return(next(request, token, cancel, signal));
        }
            public Task HandleAsync(CommandContext context, NextDelegate next)
            {
                LastCommand = context.Command;

                return(Task.CompletedTask);
            }
示例#3
0
        /// <summary>
        /// Extracts information and converts the activity from a message to an event
        /// </summary>
        /// <param name="turnContext">The context object for this turn.</param>
        /// <param name="nextTurn">The delegate to call to continue the bot middleware pipeline.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        /// <seealso cref="ITurnContext"/>
        /// <seealso cref="Bot.Schema.IActivity"/>
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            // Attach to the activity
            var activity = turnContext.Activity;

            // Only try to process the data if it was sent from the emulator and was a message
            if ((activity.Type == ActivityTypes.Message) && (activity.ChannelId == "emulator"))
            {
                // Create a Typing Indicator activity and send it back to the emulator to
                // avoid a timeout while attempting to process the event
                var typingActivity = Activity.CreateTypingActivity();
                await turnContext.SendActivityAsync(typingActivity);

                // Determine if the user sent in event data in the text of the message
                if (!String.IsNullOrEmpty(activity.Text) &&
                    activity.Text.StartsWith($"/{EventToken} ", StringComparison.InvariantCultureIgnoreCase))
                {
                    // Get the length of the activity text
                    var dataLength = activity.Text.Length;

                    // Verify that the activity text has data after the command token
                    if (dataLength > EventToken.Length + 2)
                    {
                        // Retrieve the payload data from the message text
                        var payloadData = activity.Text.Substring(EventToken.Length + 2);

                        EventPayload payload = null;
                        try
                        {
                            // Deserialize the payload into and EventPayload object
                            payload = JsonConvert.DeserializeObject <EventPayload>(payloadData);
                        }
                        catch (Exception peX)
                        {
                            var ae = new ArgumentException("Invalid event data", peX);
                            // Call the Exception Processor
                            await HandleException(turnContext, ae);
                        }
                        if (payload != null)
                        {
                            // Parse the payload
                            await ParseEventPayload(turnContext, activity, payload);
                        }
                    }
                    else
                    {
                        await HandleException(turnContext, new ArgumentException("No event data received!"));
                    }
                }
                else if ((activity.Attachments?.Count == 1) &&
                         (activity.Attachments?[0].ContentType == "application/json"))
                {
                    // The user may have sent the event information in the attachment.
                    // Execute only if we have a single attachment and it is a Json file

                    // Get the attachment
                    var attachment = activity.Attachments.First();

                    string rawData = String.Empty;
                    try
                    {
                        using (HttpClient httpClient = new HttpClient()
                        {
                            Timeout = TimeSpan.FromSeconds(5)
                        })
                        {
                            /*
                             * // Skype & MS Teams attachment URLs are secured by a JwtToken, so we need to pass the token from our bot.
                             * if ((activity.ChannelId.Equals("skype", StringComparison.InvariantCultureIgnoreCase) ||
                             *  activity.ChannelId.Equals("msteams", StringComparison.InvariantCultureIgnoreCase))
                             *  && new Uri(attachment.ContentUrl).Host.EndsWith("skype.com"))
                             * {
                             *  var token = await new MicrosoftAppCredentials().GetTokenAsync();
                             *  httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                             * }
                             */

                            // Get the data from the Url
                            var responseMessage = await httpClient.GetAsync(attachment.ContentUrl);

                            var contentLenghtBytes = responseMessage.Content.Headers.ContentLength;
                            rawData = await responseMessage.Content.ReadAsStringAsync();
                        }
                        // Parse the data into a JObject
                        var bo = JObject.Parse(rawData);
                        // The actual data is in a property called "data" containing a JToken
                        JToken t = bo["data"];

                        // Pull the bytes from the JToken
                        var databytes = t.Children().Select(x => (byte)x).ToArray();

                        // Decode the byte data to a JSON string
                        var jsonWrapperString = Encoding.Default.GetString(
                            databytes,
                            0,
                            databytes.Length);

                        // Deserialize the data into an EmulatorEventWrapper object
                        EmulatorEventWrapper jsonWrapper = JsonConvert
                                                           .DeserializeObject <EmulatorEventWrapper>(jsonWrapperString);

                        // Parse the event data
                        await ParseEventWrapper(turnContext, activity, jsonWrapper);
                    }
                    catch (TaskCanceledException tce)
                    {
                        await HandleException(turnContext,
                                              new HttpRequestException("Unable to get attachment!", tce));
                    }
                    catch (Exception eewEx)
                    {
                        // Call the Exception Processor
                        await HandleException(turnContext, eewEx);
                    }
                }
            }

            await next(cancellationToken).ConfigureAwait(false);
        }
示例#4
0
        private async Task UploadAsync(CommandContext context, string tempFile, UploadAssetCommand command, HashSet <string>?tags, bool created, NextDelegate next)
        {
            await EnrichWithMetadataAsync(command, tags);

            var asset = await HandleCoreAsync(context, created, next);

            if (asset != null)
            {
                await assetFileStore.CopyAsync(tempFile, command.AppId.Id, command.AssetId, asset.FileVersion);
            }
        }
示例#5
0
        public override async Task HandleAsync(CommandContext context, NextDelegate next)
        {
            var tempFile = context.ContextId.ToString();

            switch (context.Command)
            {
            case CreateAsset createAsset:
            {
                try
                {
                    await EnrichWithHashAndUploadAsync(createAsset, tempFile);

                    var ctx = contextProvider.Context.Clone().WithoutAssetEnrichment();

                    if (!createAsset.Duplicate)
                    {
                        var existings = await assetQuery.QueryByHashAsync(ctx, createAsset.AppId.Id, createAsset.FileHash);

                        foreach (var existing in existings)
                        {
                            if (IsDuplicate(existing, createAsset.File))
                            {
                                var result = new AssetCreatedResult(existing, true);

                                context.Complete(result);

                                await next(context);

                                return;
                            }
                        }
                    }

                    await UploadAsync(context, tempFile, createAsset, createAsset.Tags, true, next);
                }
                finally
                {
                    await assetFileStore.DeleteAsync(tempFile);

                    createAsset.File.Dispose();
                }

                break;
            }

            case UpdateAsset updateAsset:
            {
                try
                {
                    await EnrichWithHashAndUploadAsync(updateAsset, tempFile);

                    await UploadAsync(context, tempFile, updateAsset, null, false, next);
                }
                finally
                {
                    await assetFileStore.DeleteAsync(tempFile);

                    updateAsset.File.Dispose();
                }

                break;
            }

            default:
                await HandleCoreAsync(context, false, next);

                break;
            }
        }
 /// <summary>
 /// Uses the method provided in the <see cref="AnonymousReceiveMiddleware"/> to
 /// process an incoming activity.
 /// </summary>
 /// <param name="context">The context object for this turn.</param>
 /// <param name="next">The delegate to call to continue the bot middleware pipeline.</param>
 /// <returns>A task that represents the work queued to execute.</returns>
 public Task OnTurn(ITurnContext context, NextDelegate next)
 {
     return(_toCall(context, next));
 }
 /// <summary>
 /// Middleware implementation which corrects Enity.Mention.Text to a value RemoveMentionText can work with.
 /// </summary>
 /// <param name="turnContext">turn context.</param>
 /// <param name="next">next middleware.</param>
 /// <param name="cancellationToken">cancellationToken.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
 {
     NormalizeSkypMentionText(turnContext.Activity);
     await next(cancellationToken).ConfigureAwait(false);
 }
示例#8
0
 /// <summary>
 /// Uses the method provided in the <see cref="AnonymousReceiveMiddleware"/> to
 /// process an incoming activity.
 /// </summary>
 /// <param name="turnContext">The context object for this turn.</param>
 /// <param name="next">The delegate to call to continue the bot middleware pipeline.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>A task that represents the work queued to execute.</returns>
 public Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken)
 {
     return(_toCall(turnContext, next, cancellationToken));
 }
 /// <summary>
 /// Middleware implementation which loads/savesChanges automatically.
 /// </summary>
 /// <param name="turnContext">turn context.</param>
 /// <param name="next">next middlware.</param>
 /// <param name="cancellationToken">cancellationToken.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
 {
     await next(cancellationToken).ConfigureAwait(false);
     await SaveChangesAsync(turnContext, false, cancellationToken).ConfigureAwait(false);
 }
示例#10
0
        /// <summary>
        /// Pipeline delegate to add a unique id header to an outgoing request
        /// </summary>
        /// <param name="request">The outgpoing request</param>
        /// <param name="token">The cancellation token</param>
        /// <param name="cancel">Additional cancellation action if the operation is cancelled</param>
        /// <param name="signal">Signal delegate for logging events</param>
        /// <param name="next">The next step in the pipeline</param>
        /// <returns>Amended pipeline for retrieving a response</returns>
        public Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken token, Action cancel, SignalDelegate signal, NextDelegate next)
        {
            foreach (var userAgent in _userAgents)
            {
                request.Headers.UserAgent.Add(userAgent);
            }

            // continue with pipeline.
            return(next(request, token, cancel, signal));
        }
        public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            // get feedback record from state. If we don't find anything, set to null.
            var record = await _feedbackAccessor.GetAsync(context, () => null).ConfigureAwait(false);

            // if we have requested feedback
            if (record != null)
            {
                if (_options.FeedbackActions.Any(f => context.Activity.Text == (string)f.Value || context.Activity.Text == f.Title))
                {
                    // if activity text matches a feedback action
                    // save feedback in state
                    var feedback = _options.FeedbackActions
                                   .Where(f => context.Activity.Text == (string)f.Value || context.Activity.Text == f.Title)
                                   .First();

                    // Set the feedback to the action value for consistency
                    record.Feedback = (string)feedback.Value;
                    await _feedbackAccessor.SetAsync(context, record).ConfigureAwait(false);

                    if (_options.CommentsEnabled)
                    {
                        // if comments are enabled
                        // create comment prompt with dismiss action
                        if (Channel.SupportsSuggestedActions(context.Activity.ChannelId))
                        {
                            var commentPrompt = MessageFactory.SuggestedActions(
                                text: $"{_options.FeedbackReceivedMessage} {_options.CommentPrompt}",
                                cardActions: new List <CardAction>()
                            {
                                _options.DismissAction
                            });

                            // prompt for comment
                            await context.SendActivityAsync(commentPrompt).ConfigureAwait(false);
                        }
                        else
                        {
                            // channel doesn't support suggestedActions, so use hero card.
                            var hero = new HeroCard(
                                text: _options.CommentPrompt,
                                buttons: new List <CardAction> {
                                _options.DismissAction
                            });

                            // prompt for comment
                            await context.SendActivityAsync(MessageFactory.Attachment(hero.ToAttachment())).ConfigureAwait(false);
                        }
                    }
                    else
                    {
                        // comments not enabled, respond and cleanup
                        // send feedback response
                        await context.SendActivityAsync(_options.FeedbackReceivedMessage).ConfigureAwait(false);

                        // log feedback in appInsights
                        LogFeedback(record);

                        // clear state
                        await _feedbackAccessor.DeleteAsync(context).ConfigureAwait(false);
                    }
                }
                else if (context.Activity.Text == (string)_options.DismissAction.Value || context.Activity.Text == _options.DismissAction.Title)
                {
                    // if user dismissed
                    // log existing feedback
                    if (!string.IsNullOrEmpty(record.Feedback))
                    {
                        // log feedback in appInsights
                        LogFeedback(record);
                    }

                    // clear state
                    await _feedbackAccessor.DeleteAsync(context).ConfigureAwait(false);
                }
                else if (!string.IsNullOrEmpty(record.Feedback) && _options.CommentsEnabled)
                {
                    // if we received a comment and user didn't dismiss
                    // store comment in state
                    record.Comment = context.Activity.Text;
                    await _feedbackAccessor.SetAsync(context, record).ConfigureAwait(false);

                    // Respond to comment
                    await context.SendActivityAsync(_options.CommentReceivedMessage).ConfigureAwait(false);

                    // log feedback in appInsights
                    LogFeedback(record);

                    // clear state
                    await _feedbackAccessor.DeleteAsync(context).ConfigureAwait(false);
                }
                else
                {
                    // we requested feedback, but the user responded with something else
                    // clear state and continue (so message can be handled by dialog stack)
                    await _feedbackAccessor.DeleteAsync(context).ConfigureAwait(false);
                    await next(cancellationToken).ConfigureAwait(false);
                }

                await _conversationState.SaveChangesAsync(context).ConfigureAwait(false);
            }
            else
            {
                // We are not requesting feedback. Go to next.
                await next(cancellationToken).ConfigureAwait(false);
            }
        }
示例#12
0
 /// <inheritdoc/>
 public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default)
 {
     turnContext.TurnState.Add(_httpMessageHandler);
     turnContext.TurnState.Add(_httpClient);
     await next(cancellationToken).ConfigureAwait(false);
 }
        public Task Invoke(DotNetifyHubContext context, NextDelegate next)
        {
            _eventAggregator.Context = context.CallerContext.ConnectionId;

            return(next(context));
        }
示例#14
0
 /// <summary>
 /// Processes an incoming activity.
 /// </summary>
 /// <param name="context">The context object for this turn.</param>
 /// <param name="next">The delegate to call to continue the bot middleware pipeline.</param>
 /// <param name="cancellationToken">A cancellation token that can be used by other objects
 /// or threads to receive notice of cancellation.</param>
 /// <returns>A task that represents the work queued to execute.</returns>
 public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken)
 {
     await ReceiveActivityInternalAsync(context, null, 0, cancellationToken).ConfigureAwait(false);
     await next(cancellationToken).ConfigureAwait(false);
 }
示例#15
0
        /// <summary>
        /// Records incoming and outgoing activities to the conversation store.
        /// </summary>
        /// <param name="turnContext">The context object for this turn.</param>
        /// <param name="nextTurn">The delegate to call to continue the bot middleware pipeline.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        /// <seealso cref="ITurnContext"/>
        /// <seealso cref="Bot.Schema.IActivity"/>
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate nextTurn, CancellationToken cancellationToken)
        {
            // log incoming activity at beginning of turn
            if (turnContext.Activity != null)
            {
                if (turnContext.Activity.From == null)
                {
                    turnContext.Activity.From = new ChannelAccount();
                }

                if (string.IsNullOrEmpty((string)turnContext.Activity.From.Properties["role"]))
                {
                    turnContext.Activity.From.Properties["role"] = "user";
                }

                LogActivity(CloneActivity(turnContext.Activity));
            }

            // hook up onSend pipeline
            turnContext.OnSendActivities(async(ctx, activities, nextSend) =>
            {
                // run full pipeline
                var responses = await nextSend().ConfigureAwait(false);

                foreach (var activity in activities)
                {
                    LogActivity(CloneActivity(activity));
                }

                return(responses);
            });

            // hook up update activity pipeline
            turnContext.OnUpdateActivity(async(ctx, activity, nextUpdate) =>
            {
                // run full pipeline
                var response = await nextUpdate().ConfigureAwait(false);

                // add Message Update activity
                var updateActivity  = CloneActivity(activity);
                updateActivity.Type = ActivityTypes.MessageUpdate;
                LogActivity(updateActivity);
                return(response);
            });

            // hook up delete activity pipeline
            turnContext.OnDeleteActivity(async(ctx, reference, nextDelete) =>
            {
                // run full pipeline
                await nextDelete().ConfigureAwait(false);

                // add MessageDelete activity
                // log as MessageDelete activity
                var deleteActivity = new Activity
                {
                    Type = ActivityTypes.MessageDelete,
                    Id   = reference.ActivityId,
                }
                .ApplyConversationReference(reference, isIncoming: false)
                .AsMessageDeleteActivity();

                LogActivity(deleteActivity);
            });

            // process bot logic
            await nextTurn(cancellationToken).ConfigureAwait(false);

            // flush transcript at end of turn
            while (transcript.Count > 0)
            {
                var activity = transcript.Dequeue();

                // As we are deliberately not using await, disable teh associated warning.
#pragma warning disable 4014
                logger.LogActivityAsync(activity).ContinueWith(
                    task =>
                {
                    try
                    {
                        task.Wait();
                    }
                    catch (Exception err)
                    {
                        Trace.TraceError($"Transcript logActivity failed with {err}");
                    }
                },
                    cancellationToken);
#pragma warning restore 4014
            }
        }
示例#16
0
 /// <summary>
 /// Processess an incoming activity.
 /// </summary>
 /// <param name="context">The context object for this turn.</param>
 /// <param name="next">The delegate to call to continue the bot middleware pipeline.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>A task that represents the work queued to execute.</returns>
 /// <remarks>This middleware loads the state object on the leading edge of the middleware pipeline
 /// and persists the state object on the trailing edge.
 /// </remarks>
 public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken)
 {
     await ReadToContextServiceAsync(context, cancellationToken).ConfigureAwait(false);
     await next(cancellationToken).ConfigureAwait(false);
     await WriteFromContextServiceAsync(context, cancellationToken).ConfigureAwait(false);
 }
 public virtual async Task NoMatchHandler(ITurnContext context, string messageText, NextDelegate next, CancellationToken cancellationToken)
 {
     await next(cancellationToken);
 }
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default)
        {
            BotAssert.ContextNotNull(turnContext);

            if (next is null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            turnContext.TurnState.Add(new CardManagerTurnState());

            var options       = GetOptionsForChannel(turnContext.Activity.ChannelId);
            var shouldProceed = true;

            // Is this activity from a button?
            if (turnContext.GetIncomingActionData() is JObject data)
            {
                var incomingIds    = data.GetIdsFromActionData();
                var autoDeactivate = data.GetLibraryValueFromActionData <string>(Behaviors.AutoDeactivate);

                // Actions should not be disabled if they have no data ID's
                if (incomingIds.Count() > 0)
                {
                    if (options.IdTrackingStyle != TrackingStyle.None && autoDeactivate != BehaviorSwitch.Off)
                    {
                        // Whether we should proceed by default depends on the ID-tracking style
                        shouldProceed = options.IdTrackingStyle == TrackingStyle.TrackDisabled;

                        var state = await Manager.GetStateAsync(turnContext, cancellationToken).ConfigureAwait(false);

                        foreach (var incomingId in incomingIds)
                        {
                            state.DataIdsByScope.TryGetValue(incomingId.Key, out var trackedSet);

                            var setContainsId = trackedSet?.Contains(incomingId.Value) == true;

                            if (setContainsId)
                            {
                                // Proceed if the presence of the ID indicates that the ID is enabled (opt-in logic),
                                // short-circuit if the presence of the ID indicates that the ID is disabled (opt-out logic)
                                shouldProceed = options.IdTrackingStyle == TrackingStyle.TrackEnabled;
                            }

                            if (options.AutoDisableOnAction || autoDeactivate == BehaviorSwitch.On)
                            {
                                // This might disable an already-disabled ID but that's okay
                                await Manager.DisableIdAsync(
                                    turnContext,
                                    incomingId,
                                    options.IdTrackingStyle,
                                    cancellationToken).ConfigureAwait(false);
                            }
                        }
                    }

                    if ((options.AutoDeleteOnAction && autoDeactivate != BehaviorSwitch.Off) ||
                        (options == UpdatingOptions && autoDeactivate == BehaviorSwitch.On))
                    {
                        // If there are multiple ID scopes in use, just delete the one with the largest range
                        var scope = DataId.Scopes.ElementAtOrDefault(incomingIds.Max(id => DataId.Scopes.IndexOf(id.Key)));

                        await Manager.DeleteActionSourceAsync(turnContext, scope, cancellationToken).ConfigureAwait(false);
                    }
                }
            }

            turnContext.OnSendActivities(OnSendActivities);
            turnContext.OnUpdateActivity(OnUpdateActivity);
            turnContext.OnDeleteActivity(OnDeleteActivity);

            if (shouldProceed)
            {
                // If this is not called, the middleware chain is effectively "short-circuited"
                await next(cancellationToken).ConfigureAwait(false);
            }
        }
示例#19
0
        /// <summary>
        /// Records incoming and outgoing activities to the Application Insights store.
        /// </summary>
        /// <param name="context">The <see cref="ITurnContext"/> object for this turn.</param>
        /// <param name="nextTurn">The delegate to call to continue the bot middleware pipeline.</param>
        /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns>
        /// <seealso cref="ITurnContext"/>
        /// <seealso cref="Bot.Schema.IActivity"/>
        public async Task OnTurnAsync(ITurnContext context, NextDelegate nextTurn, CancellationToken cancellationToken)
        {
            BotAssert.ContextNotNull(context);

            if (nextTurn == null)
            {
                throw new ArgumentNullException(nameof(nextTurn));
            }

            context.TurnState.Add(MyAppInsightsLoggerMiddleware.AppInsightsServiceKey, _telemetryClient);

            // log incoming activity at beginning of turn
            if (context.Activity != null)
            {
                var activity = context.Activity;

                // Context properties for App Insights
                if (!string.IsNullOrEmpty(activity.Conversation.Id))
                {
                    _telemetryClient.Context.Session.Id = activity.Conversation.Id;
                }

                if (!string.IsNullOrEmpty(activity.From.Id))
                {
                    _telemetryClient.Context.User.Id = activity.From.Id;
                }

                // Log the Application Insights Bot Message Received
                _telemetryClient.TrackEvent(BotMsgReceiveEvent, FillReceiveEventProperties(activity));
            }

            // hook up onSend pipeline
            context.OnSendActivities(async(ctx, activities, nextSend) =>
            {
                // run full pipeline
                var responses = await nextSend().ConfigureAwait(false);

                foreach (var activity in activities)
                {
                    _telemetryClient.TrackEvent(BotMsgSendEvent, FillSendEventProperties(activity));
                }

                return(responses);
            });

            // hook up update activity pipeline
            context.OnUpdateActivity(async(ctx, activity, nextUpdate) =>
            {
                // run full pipeline
                var response = await nextUpdate().ConfigureAwait(false);

                _telemetryClient.TrackEvent(BotMsgUpdateEvent, FillUpdateEventProperties(activity));

                return(response);
            });

            // hook up delete activity pipeline
            context.OnDeleteActivity(async(ctx, reference, nextDelete) =>
            {
                // run full pipeline
                await nextDelete().ConfigureAwait(false);

                var deleteActivity = new Activity
                {
                    Type = ActivityTypes.MessageDelete,
                    Id   = reference.ActivityId,
                }
                .ApplyConversationReference(reference, isIncoming: false)
                .AsMessageDeleteActivity();

                _telemetryClient.TrackEvent(BotMsgDeleteEvent, FillDeleteEventProperties(deleteActivity));
            });

            if (nextTurn != null)
            {
                await nextTurn(cancellationToken).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Processes an incoming activity.
        /// </summary>
        /// <param name="turnContext">Context object containing information for a single turn of conversation with a user.</param>
        /// <param name="next">The delegate to call to continue the bot middleware pipeline.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (turnContext == null)
            {
                throw new ArgumentNullException(nameof(turnContext));
            }

            if (turnContext.Activity.Type == ActivityTypes.Message)
            {
                turnContext.Activity.Text = await TranslateMessageActivityAsync(turnContext.Activity.AsMessageActivity());
            }

            ////EXPERIMENT 1 -
            // IN VISUAL STUDIO > CREATE BREAK POINT ON THE LINE CONTAINING `activities,Where(a=>...)` , THEN OPEN AND PIN VARIABLES > 1) ACTIVITIES + 2) TEXT + 3) TYPE
            ///
            //turnContext.OnSendActivities(async (newContext, activities, nextSend) =>
            //{
            //    List<Task> tasks = new List<Task>();
            //    foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message))
            //    {
            //        tasks.Add(TranslateMessageActivityAsync(currentActivity.AsMessageActivity())); //, userLanguage));
            //    }
            //
            //    if (tasks.Any())
            //    {
            //        await Task.WhenAll(tasks).ConfigureAwait(false);
            //    }
            //
            //    await nextSend();
            //
            // IN VISUAL STUDIO > CREATE BREAK POINT ON THE LINE CONTAINING `activities,Where(a=>...)` , THEN OPEN AND PIN VARIABLES > 1) ACTIVITIES + 2) TEXT + 3) TYPE
            //    List<Task> tasksAfterNextSend = new List<Task>();
            //    foreach (Activity currentActivityAfterNextSend in activities.Where(a => a.Type == ActivityTypes.Message))
            //    {
            //        tasksAfterNextSend.Add(TranslateMessageActivityAsync(currentActivityAfterNextSend.AsMessageActivity())); //, userLanguage));
            //    }
            //
            //    if (tasksAfterNextSend.Any())
            //    {
            //        await Task.WhenAll(tasksAfterNextSend).ConfigureAwait(false);
            //    }
            //
            //    return await nextSend();
            //});
            //END OF EXPERIMENT 1

            //EXPERIMENT 2
            // IN VISUAL STUDIO > CREATE BREAK POINT ON THE LINE CONTAINING `activities,Where(a=>...)` , THEN OPEN AND PIN VARIABLES > 1) ACTIVITIES + 2) TEXT + 3) TYPE
            //turnContext.OnSendActivities(async (newContext, activities, nextSend) =>
            //{
            //    List<Task> tasks = new List<Task>();
            //    foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message))
            //    {
            //        tasks.Add(TranslateMessageActivityAsync(currentActivity.AsMessageActivity())); //, userLanguage));
            //    }
            //
            //    if (tasks.Any())
            //    {
            //        await Task.WhenAll(tasks).ConfigureAwait(false);
            //    }
            //
            //    return await nextSend();
            //
            //});
            //END OF EXPERIMENT 2


            //EXPERIMENT 3
            // IN VISUAL STUDIO > CREATE BREAK POINT ON THE LINE CONTAINING `activities,Where(a=>...)` , THEN OPEN AND PIN VARIABLES > 1) ACTIVITIES + 2) TEXT + 3) TYPE
            // SCROLL DOWN TO METHOD TranslateMessageActivityAsync AND OPEN/PIN VARIABLE FOR RETURN appendableString
            //turnContext.OnSendActivities(async (newContext, activities, nextSend) =>
            //{
            //    List<Task> tasks = new List<Task>();
            //    foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message))
            //    {
            //        tasks.Add(TranslateMessageActivityAsync(currentActivity.AsMessageActivity())); //, userLanguage));
            //
            //        var appendedString = await TranslateMessageActivityAsync(currentActivity.AsMessageActivity());
            //        await turnContext.SendActivityAsync(appendedString);
            //    }
            //
            //    if (tasks.Any())
            //    {
            //        await Task.WhenAll(tasks).ConfigureAwait(false);
            //    }
            //
            //    return await nextSend();
            //
            //});
            //END OF EXPERIMENT 3


            //EXPERIMENT 4
            // IN VISUAL STUDIO > CREATE BREAK POINT ON THE LINE CONTAINING `activities,Where(a=>...)` , THEN OPEN AND PIN VARIABLES > 1) ACTIVITIES + 2) TEXT + 3) TYPE
            // SCROLL DOWN TO METHOD TranslateMessageActivityAsync AND OPEN/PIN VARIABLE FOR RETURN appendableString
            turnContext.OnSendActivities(async(newContext, activities, nextSend) =>
            {
                List <Task> tasks = new List <Task>();
                foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message))
                {
                    tasks.Add(TranslateMessageActivityAsync(currentActivity.AsMessageActivity())); //, userLanguage));

                    var appendedString   = await TranslateMessageActivityAsync(currentActivity.AsMessageActivity());
                    currentActivity.Text = appendedString;
                }

                if (tasks.Any())
                {
                    await Task.WhenAll(tasks).ConfigureAwait(false);
                }

                return(await nextSend());
            });
            //END OF EXPERIMENT 4


            turnContext.OnUpdateActivity(async(newContext, activity, nextUpdate) =>
            {
                //// Translate messages sent to the user to user language
                if (activity.Type == ActivityTypes.Message)
                {
                    await TranslateMessageActivityAsync(activity.AsMessageActivity());//, userLanguage);
                }
                return(await nextUpdate());
            });

            await next(cancellationToken).ConfigureAwait(false);

            //BONUS : UNCOMMENT NOTICE THAT IT DOESN'T DO ANYTHING!
            //THIS DOES NOT ADD ANYTHING AND WONT BE CALLED
            //ALTHOUGH THIS IS WRITEN AFTER THE NEXT(CANCELLATIONTOKEN).CONFIGUREAWAIT(FALSE);
            //THE turnContext.OnSendActivities...CAN SIMPLY BE WRITTEN ABOVE IT AND THEN WITHIN THE METHOD YOU CAN SPLIT BEFORE / AFTER SEND CODE WITH AN AWAIT NEXTSEND() IN THE METHOD.
            //
            //turnContext.OnSendActivities(async (nextContext, activities, nextSend) =>
            //{
            //    List<Task> tasks = new List<Task>();
            //    foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message))
            //    {
            //        tasks.Add(TranslateMessageActivityAsync(currentActivity.AsMessageActivity())); //, userLanguage));
            //    }
            //
            //    if (tasks.Any())
            //    {
            //        await Task.WhenAll(tasks).ConfigureAwait(false);
            //    }
            //
            //    await nextSend();
            //
            //    List<Task> tasksAfterNextSend = new List<Task>();
            //    foreach (Activity currentActivityAfterNextSend in activities.Where(a => a.Type == ActivityTypes.Message))
            //    {
            //        tasks.Add(TranslateMessageActivityAsync(currentActivityAfterNextSend.AsMessageActivity())); //, userLanguage));
            //    }
            //
            //    if (tasks.Any())
            //    {
            //        await Task.WhenAll(tasks).ConfigureAwait(false);
            //    }
            //
            //    return await nextSend();
            //});
        }
示例#21
0
        public async Task HandleAsync(CommandContext context, NextDelegate next)
        {
            if (context.Command is CreateApp createApp)
            {
                var index = Index();

                var token = await CheckAppAsync(index, createApp);

                try
                {
                    await next(context);
                }
                finally
                {
                    if (token != null)
                    {
                        if (context.IsCompleted)
                        {
                            await index.AddAsync(token);

                            await Index(createApp.Actor.Identifier).AddAsync(createApp.AppId);
                        }
                        else
                        {
                            await index.RemoveReservationAsync(token);
                        }
                    }
                }
            }
            else
            {
                await next(context);

                if (context.IsCompleted && context.Command is AppCommand appCommand)
                {
                    var app = await GetAppCoreAsync(appCommand.AggregateId);

                    if (app != null)
                    {
                        await CacheItAsync(app, true);

                        switch (context.Command)
                        {
                        case AssignContributor assignContributor:
                            await AssignContributorAsync(assignContributor);

                            break;

                        case RemoveContributor removeContributor:
                            await RemoveContributorAsync(removeContributor);

                            break;

                        case ArchiveApp _:
                            await ArchiveAppAsync(app);

                            break;
                        }
                    }
                }
            }
        }
示例#22
0
        /// <summary>
        /// Records incoming and outgoing activities to the Application Insights store.
        /// </summary>
        /// <param name="context">The context object for this turn.</param>
        /// <param name="nextTurn">The delegate to call to continue the bot middleware pipeline.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        /// <seealso cref="ITurnContext"/>
        /// <seealso cref="Bot.Schema.IActivity"/>
        public async Task OnTurnAsync(ITurnContext context, NextDelegate nextTurn, CancellationToken cancellationToken)
        {
            BotAssert.ContextNotNull(context);

            context.TurnState.Add(TelemetryLoggerMiddleware.AppInsightsServiceKey, _telemetryClient);

            // log incoming activity at beginning of turn
            if (context.Activity != null)
            {
                var activity = context.Activity;

                // Log the Application Insights Bot Message Received
                _telemetryClient.TrackEventEx(TelemetryLoggerConstants.BotMsgReceiveEvent, activity, null, this.FillReceiveEventProperties(activity));
            }

            // hook up onSend pipeline
            context.OnSendActivities(async(ctx, activities, nextSend) =>
            {
                // run full pipeline
                var responses = await nextSend().ConfigureAwait(false);

                foreach (var activity in activities)
                {
                    _telemetryClient.TrackEventEx(TelemetryLoggerConstants.BotMsgSendEvent, activity, null, this.FillSendEventProperties(activity));
                }

                return(responses);
            });

            // hook up update activity pipeline
            context.OnUpdateActivity(async(ctx, activity, nextUpdate) =>
            {
                // run full pipeline
                var response = await nextUpdate().ConfigureAwait(false);

                _telemetryClient.TrackEventEx(TelemetryLoggerConstants.BotMsgUpdateEvent, activity, null, this.FillUpdateEventProperties(activity));

                return(response);
            });

            // hook up delete activity pipeline
            context.OnDeleteActivity(async(ctx, reference, nextDelete) =>
            {
                // run full pipeline
                await nextDelete().ConfigureAwait(false);

                var deleteActivity = new Activity
                {
                    Type = ActivityTypes.MessageDelete,
                    Id   = reference.ActivityId,
                }
                .ApplyConversationReference(reference, isIncoming: false)
                .AsMessageDeleteActivity();

                _telemetryClient.TrackEventEx(TelemetryLoggerConstants.BotMsgDeleteEvent, deleteActivity as Activity, null, this.FillDeleteEventProperties(deleteActivity));
            });

            if (nextTurn != null)
            {
                await nextTurn(cancellationToken).ConfigureAwait(false);
            }
        }
示例#23
0
        private async Task <IEnrichedAssetEntity?> HandleCoreAsync(CommandContext context, bool created, NextDelegate next)
        {
            await base.HandleAsync(context, next);

            if (context.PlainResult is IAssetEntity asset && !(context.PlainResult is IEnrichedAssetEntity))
            {
                var enriched = await assetEnricher.EnrichAsync(asset, contextProvider.Context);

                if (created)
                {
                    context.Complete(new AssetCreatedResult(enriched, false));
                }
                else
                {
                    context.Complete(enriched);
                }

                return(enriched);
            }

            return(null);
        }
示例#24
0
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default)
        {
            await turnContext.SendActivityAsync("Hey am Grammer Middleware");

            await next(cancellationToken);
        }
 private static NextDelegate Join(ICommandMiddleware handler, NextDelegate next)
 {
     return(context => handler.HandleAsync(context, next));
 }
示例#26
0
 public void RunMiddlewares(DotNetifyHubContext hubContext, NextDelegate finalAction)
 {
     _ = RunMiddlewaresAsync(hubContext, finalAction);
 }
            public Task HandleAsync(CommandContext context, NextDelegate next)
            {
                LastCommand = context.Command;

                throw new InvalidOperationException();
            }
示例#28
0
 public virtual async Task PostPersonalityChatResponseToUser(ITurnContext context, NextDelegate next, string personalityChatResponse)
 {
     if (!string.IsNullOrEmpty(personalityChatResponse))
     {
         await context.SendActivityAsync(personalityChatResponse).ConfigureAwait(false);
     }
 }