Configure hand off to any generic engagement hub

Important

Power Virtual Agents capabilities and features are now part of Microsoft Copilot Studio following significant investments in generative AI and enhanced integrations across Microsoft Copilot.

Some articles and screenshots may refer to Power Virtual Agents while we update documentation and training content.

Microsoft Copilot Studio lets you hand over bot conversations seamlessly and contextually to a human agent through an engagement hub.

With some custom development, you can configure your bot to hand off conversations to any engagement hub. This guide describes how you can do this.

Prerequisites

Important

Instructions in this section require software development from you or your developers. It is intended for experienced IT professionals, such as IT admins or developers who have a solid understanding of developer tools, utilities, and IDEs who are looking to integrate third-party engagement hubs with Microsoft Copilot Studio.

Overview

ILLUSTRATION SHOWING GENERIC ADAPTER DATAFLOW.

A full hand-off to an engagement hub follows this pattern:

  1. An end user interacts with the engagement hub's chat canvas.

  2. The engagement hub routes the incoming chat through built-in chat routing capabilities to a bot.

  3. A custom adapter relays the incoming chat messages from the engagement hub to a Microsoft Copilot Studio bot.

  4. Once the end user triggers hand-off, Microsoft Copilot Studio starts hand-off with full conversational context.

  5. The custom adapter intercepts the hand-off message, parses the full conversation context, and seamlessly routes the escalated conversation to a skilled human agent, based on availability.

  6. The end user's chat is seamlessly and contextually handed off to a human agent who can resume the conversation.

To hand off the conversation to a human agent, you need to build a custom hand-off adapter.

Build a custom hand-off adapter

An adapter bridges conversations to and from your agent engagement hub by relaying and transforming messages between end users, bots, and human agents.

Most popular agent engagement hubs provide SDKs or document their APIs publicly, enabling you to build such adapters.

While it is outside the scope of this document to cover what a custom adapter could contain, the following sample hand-off message, based on what Microsoft Copilot Studio generates as part of our standard hand-off to a live agent experience, can help get you started.

These code snippets and samples allow you to extract context from the bot conversation to seamlessly and contextually hand off bot conversations to any generic engagement hub.

Sample hand-off message payload

Hand-off is currently only supported over DirectLine - learn more about interacting with the bot over DirectLine. Upon hand-off, an event activity called handoff.initiate is raised and sent to the adapter.

You can see a full sample hand-off message activity on our GitHub site.

Extract context from hand-off message

To use conversational context, you must parse the handoff.initiate event activity. The following snippet of code parses the handoff.initiate event activity and extracts the conversational context. See the full code sample on GitHub.

        public void InitiateHandoff(string botresponseJson)
        {
            BotResponse response = JsonConvert.DeserializeObject<BotResponse>(botresponseJson);

            // Look for Handoff Initiate Activity. This indicates that conversation needs to be handed off to agent
            Activity handoffInitiateActivity = response.Activities.ToList().FirstOrDefault(
                item => string.Equals(item.Type, ActivityTypes.Event, System.StringComparison.Ordinal)
                && string.Equals(item.Name, HandoffInitiateActivityName, System.StringComparison.Ordinal));

            if (handoffInitiateActivity != null)
            {
                // Read transcript from attachment
                if (handoffInitiateActivity.Attachments?.Any() == true)
                {
                    Attachment transcriptAttachment = handoffInitiateActivity.Attachments.FirstOrDefault(a => string.Equals(a.Name.ToLowerInvariant(), TranscriptAttachmentName, System.StringComparison.Ordinal));
                    if (transcriptAttachment != null)
                    {
                        Transcript transcript = JsonConvert.DeserializeObject<Transcript>(transcriptAttachment.Content.ToString());
                    }
                }

                // Read handoff context
                HandoffContext context = JsonConvert.DeserializeObject<HandoffContext>(handoffInitiateActivity.Value.ToString());

                // Connect to Agent Hub
                // <YOUR CUSTOM ADAPTER CODE GOES HERE>
            }
        }