Problem Statement

This is regarding the Live Agent Handoff intermediator-bot-sample (c#) created by tompaana at https://github.com/tompaana/intermediator-bot-sample on guithub.

  • The intermediator-bot-sample works perfectly with Microsoft.Bot.Builder (4.2.2) and Microsoft.Bot.Builder.Integration.AspNet.Core(4.2.2) and dependent Version 4.2.2 packages but, It does not use Dialogs.

  • The HandoffMiddleware Code stopped getting invoked , when I added the package Microsoft.Bot.Builder.Dialogs (4.10.3) (as my existing code requires Dialogs) . This also caused upgrading to Microsoft.Bot.Builder to version 4.10.3 along with it's dependent packages i.e. Microsoft.Bot.Builder.Integration.AspNet.Core etc..

Community Support

The Original Author Handoff intermediator-bot-sample Tomi Paananen A.K.A tompaana has moved on to other projects and would no longer be able to devote time to this project and has requested to reach out MS Botframework community members for support (Refer: Author Response to Github issue raised).

  • Requesting BotFramework community to please help out to add Agent Hand Off functionality to my existing Chatbot

Observation :

  • Even After Package upgrade, the HandoffMiddleware class is getting successfully instantiated during Startup.

  • My retrofitted code contains BotController class via which all the API get invoked. This BotController class which isn't present in the original Handoff intermediator-bot-sample code.

  • On typing any utterance on the chat bot (Upgraded/new code), the control goes into the BotController class rather than invoking/triggering HandoffMiddleware.OnTurnAsync(...)

  • As the original intermediator-bot-sample code does not have any BotController/ API Controller, could this be the reason that utterances aren't getting routed via, HandoffMiddleware Middleware if so, how could I fix the issue?

// Licensed under the MIT License.
//
// Generated with Bot Builder V4 SDK Template for Visual Studio EchoBot v4.6.2

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;

namespace Neo.Controllers
{
    // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
    // implementation at runtime. Multiple different IBot implementations running at different endpoints can be
    // achieved by specifying a more specific type for the bot constructor argument.
    [Route("api/messages")]
    [ApiController]
    public class BotController : ControllerBase
    {
        private readonly IBotFrameworkHttpAdapter Adapter;
        private readonly IBot Bot;

        public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
        {
            Adapter = adapter;
            Bot = bot;
        }

        [HttpPost, HttpGet]
        public async Task PostAsync()
        {
            // Delegate the processing of the HTTP POST to the adapter.
            // The adapter will invoke the bot.
            await Adapter.ProcessAsync(Request, Response, Bot);
        }
    }
}

Referenced Packages

Original intermediator-bot-sample referenced Packages

Original intermediator-bot-sample referenced Packages

Upgraded intermediator-bot-sample referenced Packages

enter image description here

Original intermediator-bot-sample Solution Files

enter image description here

Upgraded intermediator-bot-sample Solution Files

enter image description here

Query

Could you please suggest How I can fix this issue?

  • As the HandoffMiddleware.OnTurnAsync(..) works fine when I execute the coriginal code_ but, doesn't get triggered from My Code after retrofitting IntermediateBot code with upgraded Microsoft.Bot.Builder and related packages to Version 4.10.3 .

  • Pointing to an existing working Agent HandOff sample(c#) would also help

1

There are 1 answers

0
Gaurav Anand On

The following solution makes the upgraded Tompanna Agent Handoff solution work smoothly:

  • The solution lies in the way BotFrameworkHttpAdapter needs to invoke HandoffMiddleware.

The inspection Middleware example in Github provides the methodology to invoke any middleware i.e. in those scenarios where we have the upgraded Microsoft.Bot.Builder and related packages which introduce the concept of BotController class / API Controller .

Code reference of AdapterWithInspection.cs from BotBuilder-Samples/samples

Replace InspectionMiddleware in the following code with HandoffMiddleware


namespace Microsoft.BotBuilderSamples
{
    public class AdapterWithInspection : BotFrameworkHttpAdapter
    {
        public AdapterWithInspection(IConfiguration configuration, InspectionState inspectionState, UserState userState, ConversationState conversationState, ILogger<BotFrameworkHttpAdapter> logger)
            : base(configuration, logger)
        {
            // Inspection needs credentiaols because it will be sending the Activities and User and Conversation State to the emulator
            var credentials = new MicrosoftAppCredentials(configuration["MicrosoftAppId"], configuration["MicrosoftAppPassword"]);

//***********************************************************************************//
//* InspectionMiddleware needs to be replace HandOffMddieWare in the execution pipeline *// 
//***********************************************************************************//          
              Use(new InspectionMiddleware(inspectionState, userState, conversationState, credentials));

            OnTurnError = async (turnContext, exception) =>
            {
                // Log any leaked exception from the application.
                logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

                // Send a message to the user
                await turnContext.SendActivityAsync("The bot encountered an error or bug.");
                await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");

                // Send a trace activity, which will be displayed in the Bot Framework Emulator
                await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError");
            };
        }
    }
}

New code should look like the following

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.


namespace Microsoft.BotBuilderSamples
{
    public class AdapterWithInspection : BotFrameworkHttpAdapter
    {
        public AdapterWithInspection(IConfiguration configuration, InspectionState inspectionState, UserState userState, ConversationState conversationState, ILogger<BotFrameworkHttpAdapter> logger)
            : base(configuration, logger)
        {
            // Inspection needs credentials because it will be sending the Activities and User and Conversation State to the emulator
            var credentials = new MicrosoftAppCredentials(configuration["MicrosoftAppId"], configuration["MicrosoftAppPassword"]);

//***********************************************************************************//
//*************** Adding HandOffMddieWare in the execution pipeline *****************//           
//***********************************************************************************//
            Use(new HandoffMiddleware(configuration));

            OnTurnError = async (turnContext, exception) =>
            {
                // Log any leaked exception from the application.
                logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");

                // Send a message to the user
                await turnContext.SendActivityAsync("The bot encountered an error or bug.");
                await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");

                // Send a trace activity, which will be displayed in the Bot Framework Emulator
                await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError");
            };
        }
    }
}

NOTE

  • You would need to inject dependencies in the Startup.cs accordingly

Inject Dependencies in Startup.cs

Add following code to facilitate dependency injection of AdapterWithInspection

            services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithInspection>();