/// <summary> /// Records incoming and outgoing activities to the telemetry service. /// </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> public async Task OnTurnAsync(ITurnContext context, NextDelegate nextTurn, CancellationToken cancellationToken) { BotAssert.ContextNotNull(context); // Allow other components to log telemetry context.TurnState.Add(TelemetryKey, telemetry); // Log incoming activity at beginning of turn if (context.Activity != null) { telemetry.TrackActivity(context.Activity); } // Hook up onSend pipeline and log outgoing activities context.OnSendActivities(async(ctx, activities, nextSend) => { var responses = await nextSend().ConfigureAwait(false); activities.ForEach(a => telemetry.TrackActivity(a)); return(responses); }); if (nextTurn != null) { await nextTurn(cancellationToken).ConfigureAwait(false); } }
public virtual async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default) { // Get the conversation escalation record - if null then the conversation has not been handed off var handoffRecord = await GetConversationHandoffRecordIfExists(turnContext); // If an escalation record exists then we should route the message through to LivePerson if (turnContext.Activity.Type == ActivityTypes.Message && handoffRecord != null) { await RouteActivityToExistingHandoff(turnContext, handoffRecord); return; } // Hook into the onSendActivities event. Check for outgoing HandoffEvent initiate events. If we find one // this means we should start a new connection with LivePerson and create an escalation record so that future // messages are routed correctly. turnContext.OnSendActivities(async(sendTurnContext, activities, nextSend) => { // Handle any escalation events, and let them propagate through the pipeline // This is useful for debugging with the Emulator var handoffEvents = activities.Where(activity => activity.Type == ActivityTypes.Event && (activity.Name == HandoffEventNames.InitiateHandoff || activity.Name == HandoffEventNames.HandoffStatus)); var eventActivity = handoffEvents.ToList().FirstOrDefault(); if (eventActivity != null) { switch (eventActivity.Name) { case HandoffEventNames.HandoffStatus: try { var state = (eventActivity.Value as JObject)?.Value <string>("state"); if (state == "completed") { await HandleHandoffStatusCompletedEvent(turnContext, handoffRecord); } else { await HandleHandoffStatusEvent(turnContext, handoffRecord); } } catch { } break; case HandoffEventNames.InitiateHandoff: handoffRecord = await Escalate(sendTurnContext, eventActivity).ConfigureAwait(false); await _conversationHandoffRecordMap.Add(eventActivity.Conversation.Id, handoffRecord); break; } } // run full pipeline var responses = await nextSend().ConfigureAwait(false); return(responses); }); await next(cancellationToken).ConfigureAwait(false); }
/// <summary> /// If outgoing Activities are messages and using one of the desired channels, decorate the Speak property with an SSML formatted string. /// </summary> /// <param name="context">The Bot Context object.</param> /// <param name="next">The next middleware component to run.</param> /// <param name="cancellationToken">The cancellation token for the task.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { context.OnSendActivities(async(ctx, activities, nextSend) => { foreach (var activity in activities) { switch (activity.Type) { case ActivityTypes.Message: activity.Speak = GetActivitySpeakText(activity); if (_channels.Contains(activity.ChannelId)) { activity.Speak = DecorateSSML(activity); } break; } } return(await nextSend().ConfigureAwait(false)); }); return(next(cancellationToken)); }
public Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { turnContext.OnSendActivities(OnSendActivities); turnContext.OnUpdateActivity(OnUpdateActivity); return(next(cancellationToken)); }
/// <inheritdoc /> public async Task OnTurnAsync( ITurnContext context, NextDelegate next, CancellationToken cancellationToken = new CancellationToken()) { if (context.Activity.Type == ActivityTypes.Message) { context.OnSendActivities( async(activityContext, activityList, activityNext) => { foreach (Activity activity in activityList) { if (activity.Type != ActivityTypes.Message || !activity.HasContent()) { continue; } if (activity.Id == null) { var dialogState = await feedbackBotStateRepository.ConversationDialogState.GetAsync(context); var dialogInstance = dialogState.DialogStack?.FirstOrDefault()?.State.First().Value as DialogState; activity.Id = dialogInstance?.DialogStack?.FirstOrDefault()?.Id; } } return(await activityNext()); }); } await next.Invoke(cancellationToken); }
/// <inheritdoc /> /// <summary> /// Intercepts each turn to determine whether the source of the message is from the bespoke DirectLine based NotifyConnector. /// Pushes the outgoing message on to a queue if so. /// </summary> /// <param name="context">The turn context</param> /// <param name="next">the next OnTurn operation in the pipeline</param> /// <returns>The <see cref="T:System.Threading.Tasks.Task" /></returns> public async Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) { if (context.Activity.Type == ActivityTypes.Message) { // Create a send activity handler to grab all response activities // from the activity list. context.OnSendActivities( async(activityContext, activityList, activityNext) => { dynamic channelData = context.Activity.ChannelData; if (channelData?.NotifyMessage == null) { return(await activityNext()); } foreach (Activity activity in activityList) { if (activity.Type != ActivityTypes.Message || !activity.HasContent()) { continue; } await this.RelayMessage(context, activity); } return(await activityNext()); }); } // Pass execution on to the next layer in the pipeline. await next(); }
/// <summary> /// If outgoing Activities are messages and using the Direct Line Speech channel, decorate the Speak property with an SSML formatted string. /// </summary> /// <param name="context">The Bot Context object.</param> /// <param name="next">The next middleware component to run.</param> /// <param name="cancellationToken">The cancellation token for the task.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { context.OnSendActivities(async(ctx, activities, nextSend) => { foreach (var activity in activities) { switch (activity.Type) { case ActivityTypes.Message: activity.Speak = activity.Speak ?? activity.Text; // TODO: Use Microsoft.Bot.Connector.Channels comparison when "directlinespeech" is available if (activity.ChannelId.Equals("directlinespeech")) { activity.Speak = DecorateSSML(activity); } break; } } return(await nextSend().ConfigureAwait(false)); }); return(next(cancellationToken)); }
public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { this.LogActivity(string.Empty, context.Activity); context.OnSendActivities(this.OnSendActivities); await next(cancellationToken).ConfigureAwait(false); }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken) { if (await ShouldTranslateAsync(turnContext, cancellationToken)) { if (turnContext.Activity.Type == ActivityTypes.Message) { turnContext.Activity.Text = (await translator.TranslateAsync(new TranslatorRequest[] { new TranslatorRequest(turnContext.Activity.Text) }, TranslationSettings.defaultLanguage))[0]; } } turnContext.OnSendActivities(async(newContext, activities, nextSend) => { string userLanguage = await languageStateProperty.GetAsync(turnContext, () => TranslationSettings.defaultLanguage); if (userLanguage != TranslationSettings.defaultLanguage && needToTranslateProperty.GetAsync(turnContext, () => true).Result) { 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()); }); await next(cancellationToken).ConfigureAwait(false); }
/// <summary> /// Logs events based on incoming and outgoing activities using the <see cref="IBotTelemetryClient"/> interface. /// </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 virtual async Task OnTurnAsync(ITurnContext context, NextDelegate nextTurn, CancellationToken cancellationToken) { BotAssert.ContextNotNull(context); // log incoming activity at beginning of turn if (context.Activity != null) { var activity = context.Activity; // Log Bot Message Received await OnReceiveActivityAsync(activity, cancellationToken).ConfigureAwait(false); } // hook up onSend pipeline context.OnSendActivities(async(ctx, activities, nextSend) => { // run full pipeline var responses = await nextSend().ConfigureAwait(false); foreach (var activity in activities) { await OnSendActivityAsync(activity, cancellationToken).ConfigureAwait(false); } return(responses); }); // hook up update activity pipeline context.OnUpdateActivity(async(ctx, activity, nextUpdate) => { // run full pipeline var response = await nextUpdate().ConfigureAwait(false); await OnUpdateActivityAsync(activity, cancellationToken).ConfigureAwait(false); 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(); await OnDeleteActivityAsync((Activity)deleteActivity, cancellationToken).ConfigureAwait(false); }); if (nextTurn != null) { await nextTurn(cancellationToken).ConfigureAwait(false); } }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { // log incoming activity from turnContext.Activity here // Hook the turn context's OnSendActivities turnContext.OnSendActivities(HandleSendActivities); await next(cancellationToken); }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken) { if (turnContext.Activity.Conversation.IsGroup == true) { turnContext.OnSendActivities(async(ctx, activities, nextSend) => { foreach (var activity in activities) { var text = $"<at>{activity.Recipient.Name}</at>"; var mention = new Mention(activity.Recipient, text, "mention"); activity.Text = text + activity.Text; if (activity.Entities == null) { activity.Entities = new List <Entity>(); } activity.Entities.Add(mention); } // run full pipeline var responses = await nextSend().ConfigureAwait(false); return(responses); }); turnContext.Activity.RemoveRecipientMention(); } await next(cancellationToken); }
/* * Please change OnTurnAsync logic to better suit your dialog needs. */ 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) { var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken); if (dialogContext.ActiveDialog == null) { var model = await _translator.TranslateAsync(turnContext.Activity.Text, Constants.DefaultLanguage, cancellationToken); var botState = await _accessor.FetchStateAsync(turnContext); botState.SpokenLanguage = model.DetectedLanguage; await _accessor.SaveStateAsync(turnContext, botState); turnContext.Activity.Text = model.Text; turnContext.OnSendActivities(HandleBotResponses); turnContext.OnUpdateActivity(HandleBotResponse); } else { dialogContext.Context.OnSendActivities(HandleBotResponses); dialogContext.Context.OnUpdateActivity(HandleBotResponse); } } await next(cancellationToken).ConfigureAwait(false); }
/// <inheritdoc /> public async Task OnTurnAsync( ITurnContext context, NextDelegate next, CancellationToken cancellationToken = new CancellationToken()) { if (context.Activity.Type == ActivityTypes.Message) { context.OnSendActivities( async(activityContext, activityList, activityNext) => { foreach (Activity activity in activityList) { if (activity.Type != ActivityTypes.Message || !activity.HasContent()) { continue; } var turnProperty = feedbackBotStateRepository.ConversationState.CreateProperty <long>("turnId"); var turnId = await turnProperty.GetAsync(activityContext, defaultValueFactory: () => 0, cancellationToken: cancellationToken); await turnProperty.SetAsync(activityContext, ++turnId, cancellationToken); await feedbackBotStateRepository.ConversationState.SaveChangesAsync(activityContext, cancellationToken: cancellationToken); } return(await activityNext()); }); } await next.Invoke(cancellationToken); }
/// <inheritdoc /> public async Task OnTurnAsync( ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = new CancellationToken()) { if (turnContext.Activity.Type == ActivityTypes.Message) { // Create a send activity handler to grab all response activities // from the activity list. turnContext.OnSendActivities( async(activityContext, activityList, activityNext) => { dynamic channelData = activityContext.Activity.ChannelData; if (channelData?.NotifyMessage == null) { return(await activityNext()); } foreach (Activity activity in activityList) { if (activity.Type != ActivityTypes.Message || !activity.HasContent()) { continue; } await this.EnqueueMessageAsync(turnContext, activity); } return(await activityNext()); }); } // Pass execution on to the next layer in the pipeline. await next.Invoke(cancellationToken); }
/// <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)); } var translate = await ShouldTranslateAsync(turnContext, cancellationToken); if (translate) { if (turnContext.Activity.Type == ActivityTypes.Message) { turnContext.Activity.Text = await _translator.TranslateAsync(turnContext.Activity.Text, TranslationSettings.DefaultLanguage, cancellationToken); } } turnContext.OnSendActivities(async(newContext, activities, nextSend) => { string userLanguage = await _languageStateProperty.GetAsync(turnContext, () => TranslationSettings.DefaultLanguage) ?? TranslationSettings.DefaultLanguage; bool shouldTranslate = userLanguage != TranslationSettings.DefaultLanguage; // Translate messages sent to the user to user language if (shouldTranslate) { 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()); }); turnContext.OnUpdateActivity(async(newContext, activity, nextUpdate) => { string userLanguage = await _languageStateProperty.GetAsync(turnContext, () => TranslationSettings.DefaultLanguage) ?? TranslationSettings.DefaultLanguage; bool shouldTranslate = userLanguage != TranslationSettings.DefaultLanguage; // Translate messages sent to the user to user language if (activity.Type == ActivityTypes.Message) { if (shouldTranslate) { await TranslateMessageActivityAsync(activity.AsMessageActivity(), userLanguage); } } return(await nextUpdate()); }); await next(cancellationToken).ConfigureAwait(false); }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = new CancellationToken()) { // Register outgoing handler. turnContext.OnSendActivities(OutgoingHandler); // Continue processing messages. await next(cancellationToken); }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default) { //Examine outgoing activity for SuggestedActions and convert it to card with messageBack Actions //All messageBack actions are tagged with "AddedBy" turnContext.OnSendActivities(async(newContext, activities, nextSend) => { var suggestedActionCardActivities = new List <Activity>(); foreach (var activity in activities.Where(act => (act.ChannelId == TeamsChannelId && act.SuggestedActions != null))) { var newActivity = newContext.Activity.CreateReply(); newActivity.Attachments = new List <Attachment>(); //Create a new card having suggested action buttons var suggestedActionCard = new HeroCard() { Buttons = activity.SuggestedActions.ToMessageBackActions() }; newActivity.Attachments.Add(suggestedActionCard.ToAttachment()); suggestedActionCardActivities.Add(newActivity); activity.SuggestedActions = null; } activities.AddRange(suggestedActionCardActivities); return(await nextSend()); }); //Examine incoming activity for messageBack actions if (turnContext.Activity.ChannelId == TeamsChannelId && turnContext.Activity.Value != null) { var obj = (JObject)turnContext.Activity.Value; if (obj != null && obj.ContainsKey(Constants.AddedBy) && obj[Constants.AddedBy].ToString() == Constants.SuggestedActionsMiddleware) { // In case the suggestedAction was a MessageBack switch (obj["type"].ToString()) { case ActionTypes.MessageBack: { try { turnContext.Activity.Value = JObject.Parse(obj["Value"].ToString()); } catch (JsonReaderException ex) { turnContext.Activity.Value = obj["Value"].ToString(); } } break; } //delete the original suggested actions card in which this button was clicked. _ = turnContext.DeleteActivityAsync(turnContext.Activity.ReplyToId); } } await next(cancellationToken).ConfigureAwait(false); }
/// <summary> /// Processess 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.Activity.Type == ActivityTypes.Message) { IMessageActivity message = turnContext.Activity.AsMessageActivity(); if (message != null) { if (!string.IsNullOrWhiteSpace(message.Text)) { // determine the language we are using for this conversation var sourceLanguage = string.Empty; var targetLanguage = string.Empty; sourceLanguage = await _translator.DetectAsync(message.Text).ConfigureAwait(false); // awaiting user language detection using Microsoft Translator API. targetLanguage = _nativeLanguages.Contains(sourceLanguage) ? sourceLanguage : _nativeLanguages.FirstOrDefault() ?? "en"; TranslateMessageAsync(turnContext, message, sourceLanguage, targetLanguage, _nativeLanguages.Contains(sourceLanguage)).Wait(); turnContext.OnSendActivities(async(newContext, activities, nextSend) => { // Translate messages sent to the user to user language if (_toUserLanguage) { List <Task> tasks = new List <Task>(); foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message)) { tasks.Add(TranslateMessageAsync(newContext, currentActivity.AsMessageActivity(), targetLanguage, sourceLanguage, false)); } if (tasks.Any()) { await Task.WhenAll(tasks).ConfigureAwait(false); } } return(await nextSend().ConfigureAwait(false)); }); turnContext.OnUpdateActivity(async(newContext, activity, nextUpdate) => { // Translate messages sent to the user to user language if (activity.Type == ActivityTypes.Message) { if (_toUserLanguage) { await TranslateMessageAsync(newContext, activity.AsMessageActivity(), targetLanguage, sourceLanguage, false).ConfigureAwait(false); } } return(await nextUpdate().ConfigureAwait(false)); }); } } } await next(cancellationToken).ConfigureAwait(false); }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default) { // Route the conversation based on whether it's been escalated var conversationStateAccessors = _conversationState.CreateProperty <EscalationsConversationData>(nameof(EscalationsConversationData)); var conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new EscalationsConversationData()).ConfigureAwait(false); if (turnContext.Activity.Type == ActivityTypes.Message && conversationData.EscalationRecord != null) { var account = _creds.LpAccount; var message = LivePersonConnector.MakeLivePersonMessage(0, conversationData.EscalationRecord.ConversationId, turnContext.Activity.Text); await LivePersonConnector.SendMessageToConversationAsync(account, conversationData.EscalationRecord.MessageDomain, conversationData.EscalationRecord.AppJWT, conversationData.EscalationRecord.ConsumerJWS, message).ConfigureAwait(false); return; } if (turnContext.Activity.Type == ActivityTypes.Event && turnContext.Activity.Name == HandoffEventNames.HandoffStatus) { try { var state = (turnContext.Activity.Value as JObject)?.Value <string>("state"); if (state == "completed") { conversationData.EscalationRecord = null; await _conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false); } } catch { } } turnContext.OnSendActivities(async(sendTurnContext, activities, nextSend) => { // Handle any escalation events, and let them propagate through the pipeline // This is useful for debugging with the Emulator var handoffEvents = activities.Where(activity => activity.Type == ActivityTypes.Event && activity.Name == HandoffEventNames.InitiateHandoff); if (handoffEvents.Count() == 1) { var handoffEvent = handoffEvents.First(); conversationData.EscalationRecord = await Escalate(sendTurnContext, handoffEvent).ConfigureAwait(false); await _conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false); } // run full pipeline var responses = await nextSend().ConfigureAwait(false); return(responses); }); await next(cancellationToken).ConfigureAwait(false); }
/// <inheritdoc /> public async Task OnTurnAsync( ITurnContext context, NextDelegate next, CancellationToken cancellationToken = new CancellationToken()) { string botReply = string.Empty; if (context.Activity.Type == ActivityTypes.Message) { // Create a send activity handler to grab all response activities // from the activity list. context.OnSendActivities( async(activityContext, activityList, activityNext) => { if (activityList.Any()) { botReply = string.Join("\n\n", activityList.Select(a => a.Text)); } return(await activityNext()); }); } // Pass execution on to the next layer in the pipeline. await next(cancellationToken); // Save logs for each conversational exchange only. if (context.Activity.Type == ActivityTypes.Message) { // Build a log object to write to the database. var logData = new ConversationLog { From = context.Activity.From, Recipient = context.Activity.Recipient, Conversation = context.Activity.Conversation, ChannelData = context.Activity.ChannelData, ChannelId = context.Activity.ChannelId, Time = DateTime.Now.ToString( CultureInfo.InvariantCulture), Message = context.Activity.Text, Reply = botReply }; // Write our log to the database. try { await this.conversationRepository.Save(logData); } catch (Exception ex) { // More logic for what to do on a failed write can be added here throw ex; } } }
public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { var stopwatch = new Stopwatch(); stopwatch.Start(); context.TurnState[_stopWatchStateKey] = stopwatch; await LogIncomingActivityAsync(context, context.Activity, cancellationToken).ConfigureAwait(false); context.OnSendActivities(OnSendActivitiesAsync); await next(cancellationToken).ConfigureAwait(false); }
// Define OnTurn public async Task OnTurn (ITurnContext context, MiddlewareSet.NextDelegate next) { string botReply = ""; if (context.Activity.Type == ActivityTypes.Message) { if (context.Activity.Text == "history") { // Read last 3 responses from the database, and short circuit future execution. await context.SendActivity(await ReadFromDatabase(3)); return; } } // Create a send activity handler to grab all response activities // from the activity list. context.OnSendActivities(async(activityContext, activityList, activityNext) => { foreach (Activity activity in activityList) { botReply += (activity.Text + " "); } return(await activityNext()); }); // Pass execution on to the next layer in the pipeline. await next(); // Save logs for each conversational exchange only. if (context.Activity.Type == ActivityTypes.Message) { // Build a log object to write to the database. var logData = new Log { Time = DateTime.Now.ToString(), Message = context.Activity.Text, Reply = botReply }; // Write our log to the database. try { var document = await docClient.CreateDocumentAsync(UriFactory. CreateDocumentCollectionUri(Database, Collection), logData); } catch (Exception ex) { // More logic for what to do on a failed write can be added here throw ex; } } }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(turnContext.Activity.Text)) { await next(cancellationToken); return; } var language = await _languageStateProperty.GetAsync(turnContext, () => null); if (string.IsNullOrEmpty(language)) { language = await TranslatorService.Detect(turnContext.Activity.Text); await _languageStateProperty.SetAsync(turnContext, language); } if (!language.StartsWith("en")) { // If the language in the message is not english we will translate it to english before continue var translatedText = await TranslatorService.Translate(turnContext.Activity.Text, language, "en"); turnContext.Activity.Text = translatedText; } turnContext.OnSendActivities(async(newContext, activities, nextSend) => { var userLanguage = await _languageStateProperty.GetAsync(turnContext, () => DefaultLanguage) ?? DefaultLanguage; var shouldTranslate = userLanguage != DefaultLanguage; // Translate messages sent to the user to user language if (shouldTranslate) { var tasks = new List <Task>(); foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message)) { tasks.Add(TranslateMessageActivityAsync(currentActivity, userLanguage)); } if (tasks.Any()) { await Task.WhenAll(tasks).ConfigureAwait(false); } } return(await nextSend()); }); await next(cancellationToken); }
public async Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) { string botReply = ""; if (context.Activity.Type == ActivityTypes.Message) { if (context.Activity.Text.ToLower() == "history") { // Read last 5 responses from the database, and short circuit future execution await context.SendActivity(await cdh.ReadFromDatabase(5, "BotData", "BotCollection")); return; } // Create a send activity handler to grab all response activities // from the activity list. context.OnSendActivities(async(activityContext, activityList, activityNext) => { foreach (Activity activity in activityList) { botReply += (activity.Text + " "); } return(await activityNext()); }); } await next(); // Save logs for each conversational exchange only if (context.Activity.Type == ActivityTypes.Message) { // Write log to the database var convHistory = new ConvInfo { Time = DateTime.Now.ToString(), Sender = context.Activity.From.Name, Message = context.Activity.Text, Reply = botReply }; try { var document = await cdh.docClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri("BotData", "BotCollection"), convHistory); } catch (Exception ex) { //TODO: More logic for what to do on a failed write can be added here throw ex; } } }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default) { if (turnContext.Activity.Type == ActivityTypes.Message) { await ResendUserMessage(turnContext, cancellationToken); } if (turnContext.Activity.Type == ActivityTypes.Event) { if (turnContext.Activity.Name == "webchat/join") { var reference = turnContext.Activity.GetConversationReference(); _ucs.AddConvIdReference(turnContext.Activity.From.Name, turnContext.Activity.Conversation.Id, reference); } } if (turnContext.Activity.Type != ActivityTypes.Event) { turnContext.OnSendActivities(async(ctx, activities, nextSend) => { // run full pipeline var responses = await nextSend().ConfigureAwait(false); foreach (var activity in activities) { foreach (var cr in _ucs.GetOtherUserConversations(activity.Conversation.Id)) { if (ctx.Activity.Conversation.Id != cr.Key) { await _adapter.ContinueConversationAsync(_configuration["MicrosoftAppId"], cr.Value, CreateCallback(activity), CancellationToken.None); } } } return(responses); }); } await next(cancellationToken).ConfigureAwait(false); //turnContext.OnUpdateActivity(async (ctx, activities, nextUpdate) => //{ // //Save Conversation Reference // var reference = ctx.Activity.GetConversationReference(); // _ucs.AddConvIdReference(ctx.Activity.From.Name, ctx.Activity.Conversation.Id, reference); // var responses = await nextUpdate().ConfigureAwait(false); // return responses; //}); }
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default) { // Note: skill responses will show as ContinueConversation events; we don't log those. // We only log incoming messages from users. if (turnContext.Activity.Type != ActivityTypes.Event && turnContext.Activity.Name != "ContinueConversation") { var message = $"User said: {turnContext.Activity.Text} Type: \"{turnContext.Activity.Type}\" Name: \"{turnContext.Activity.Name}\""; _logger.LogInformation(message); } // Register outgoing handler. turnContext.OnSendActivities(OutgoingHandler); // Continue processing messages. await next(cancellationToken); }
async Task IMiddleware.OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken) { var(shouldForwardToApplication, shouldIntercept) = await InvokeInboundAsync(turnContext, turnContext.Activity.TraceActivity("ReceivedActivity", "Received Activity"), cancellationToken).ConfigureAwait(false); if (shouldIntercept) { turnContext.OnSendActivities(async(ctx, activities, nextSend) => { var traceActivities = activities.Select(a => a.Type == ActivityTypes.Trace ? a.CloneTraceActivity() : a.TraceActivity("SentActivity", "Sent Activity")); await InvokeOutboundAsync(ctx, traceActivities, cancellationToken).ConfigureAwait(false); return(await nextSend().ConfigureAwait(false)); }); turnContext.OnUpdateActivity(async(ctx, activity, nextUpdate) => { var traceActivity = activity.TraceActivity("MessageUpdate", "Updated Message"); await InvokeOutboundAsync(ctx, traceActivity, cancellationToken).ConfigureAwait(false); return(await nextUpdate().ConfigureAwait(false)); }); turnContext.OnDeleteActivity(async(ctx, reference, nextDelete) => { var traceActivity = reference.TraceActivity(); await InvokeOutboundAsync(ctx, traceActivity, cancellationToken).ConfigureAwait(false); await nextDelete().ConfigureAwait(false); }); } if (shouldForwardToApplication) { try { await next(cancellationToken).ConfigureAwait(false); } catch (Exception e) { await InvokeTraceExceptionAsync(turnContext, e.TraceActivity(), cancellationToken).ConfigureAwait(false); throw; } } if (shouldIntercept) { await InvokeTraceStateAsync(turnContext, cancellationToken).ConfigureAwait(false); } }
private static string CollateBotReplies(ITurnContext context) { string allBotReplies = string.Empty; context.OnSendActivities( async(activityContext, activityList, activityNext) => { foreach (Activity activity in activityList) { allBotReplies += $"{activity.Text} "; } return(await activityNext()); }); return(allBotReplies); }
/// <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) { if (turnContext == null) { throw new ArgumentNullException(nameof(turnContext)); } if (turnContext.Activity.Type == ActivityTypes.Message) { // User says something. var text = turnContext.Activity.AsMessageActivity().Text; if (turnContext.Activity.AsMessageActivity().Locale == "nl") { turnContext.Activity.AsMessageActivity().Text = TranslateFromDutch(text); } } turnContext.OnSendActivities(async(newContext, activities, nextSend) => { // Read messages sent to the user foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message)) { if (turnContext.Activity.AsMessageActivity().Locale == "nl") { var text = currentActivity.AsMessageActivity().Speak; currentActivity.AsMessageActivity().Speak = TranslateToDutch(text); } } return(await nextSend()); }); turnContext.OnUpdateActivity(async(newContext, activity, nextUpdate) => { // Read messages sent to the user if (activity.Type == ActivityTypes.Message) { } return(await nextUpdate()); }); await next(cancellationToken).ConfigureAwait(false); }