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); }
/// <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); }
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); } }
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); }
/// <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); }
/// <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); } }
/// <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)); }
/// <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); }
/// <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 } }
/// <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); } }
/// <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(); //}); }
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; } } } } }
/// <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); } }
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); }
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)); }
public void RunMiddlewares(DotNetifyHubContext hubContext, NextDelegate finalAction) { _ = RunMiddlewaresAsync(hubContext, finalAction); }
public Task HandleAsync(CommandContext context, NextDelegate next) { LastCommand = context.Command; throw new InvalidOperationException(); }
public virtual async Task PostPersonalityChatResponseToUser(ITurnContext context, NextDelegate next, string personalityChatResponse) { if (!string.IsNullOrEmpty(personalityChatResponse)) { await context.SendActivityAsync(personalityChatResponse).ConfigureAwait(false); } }