Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 3
0
        /// <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));
        }
Exemplo n.º 4
0
    public Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
    {
        turnContext.OnSendActivities(OnSendActivities);
        turnContext.OnUpdateActivity(OnUpdateActivity);

        return(next(cancellationToken));
    }
Exemplo n.º 5
0
        /// <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);
        }
Exemplo n.º 6
0
        /// <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));
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 10
0
        /// <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);
        }
Exemplo n.º 13
0
        /*
         * 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);
        }
Exemplo n.º 14
0
        /// <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);
        }
Exemplo n.º 16
0
        /// <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);
        }
Exemplo n.º 17
0
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = new CancellationToken())
        {
            // Register outgoing handler.
            turnContext.OnSendActivities(OutgoingHandler);

            // Continue processing messages.
            await next(cancellationToken);
        }
Exemplo n.º 18
0
        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);
        }
Exemplo n.º 19
0
        /// <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);
        }
Exemplo n.º 20
0
        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;
                }
            }
        }
Exemplo n.º 22
0
        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);
        }
Exemplo n.º 23
0
        // 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;
                }
            }
        }
Exemplo n.º 24
0
        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);
        }
Exemplo n.º 25
0
        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;
            //});
        }
Exemplo n.º 27
0
        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);
        }
Exemplo n.º 28
0
        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);
            }
        }
Exemplo n.º 29
0
        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);
        }
Exemplo n.º 30
0
        /// <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);
        }