Enterprise Bot Builder SDK

Introduction

This SDK simplifies creation of production ready bots that utilize Microsoft's Next Generation Calling (NGC) protocol and distributed to select partners by invite only. The Core Signaling SDK allows for creation of Calls and provide the bot developer with the flexibility to host the media remotely on Microsoft's Media PAAS, or to plug in their own media stack. The Media Extension uses the Core Signaling protocol to allow the bot developer to host the media locally and gain access to the low level AV sockets and media streams.

The SDK Calling Service

The Enterprise SDK Calling Service is built on top on Microsoft's Platform Media Aggregation (PMA) service and is distributed as a nuget package. The Core Concepts article is designed to better explain all the constructs used by the SDK. To dive right in and deploy a locally hosted media bot the Setting Up article has further instruction.

Brief Summary

To provide a brief synopsis of the calling service, let's describe a sample incoming call, and the decisions that need to be made by the developer throughout the transaction.

Assuming a bot has been properly registered and deployed, the IEnterprisePlatform configured and built, and an incoming call request has been properly forwarded to the SDK, the first callback that will be hit is the ICallServiceHandler.CallInitializedAsync. This function will tell the SDK and the corresponding PMA service how you would like to handle this call.

/// <summary>
/// The function that is called whenever a new call is created
/// on this instance. This function is used to setup the media
/// and signaling handlers required for calls.
/// </summary>
/// <param name="call">
/// The call which we are initializing.
/// </param>
/// <param name="direction">
/// The direction of the call. 
/// Describes if the call is inbound or outbound.
/// </param>
/// <returns>
/// The <see cref="CallDescription"/> object that describes the 
/// signal and media handlers for this call.
/// </returns>
public async Task<CallDescription> CallInitializedAsync(ICall call, CallFlowDirection direction)

This function is called any time a call is created. It expects a CallDescription as a response to indicate what type of call this is. A call description object can be constructed in one of two ways; it can describe a call with remotely hosted media, or it can describe a call with locally hosted media by passing in a IMediaSession object.

Call with Remotely Hosted Media

Here is one example of creating a call with remotely hosted media:

public async Task<CallDescription> CallInitializedAsync(ICall call, CallFlowDirection direction)
{
    // We setup a signaling handler for each call.
    var callHandler = new CallHandler(call);

    // We return the CallDescription
    return new CallDescription(
        callHandler, 
        new[] { RemoteMediaCallModality.Audio }, 
        new[] { NotificationType.CallStateChange });
}
Note

In the above example, note that this bot is only subscribing to the Audio modality, and it's only listening on the CallStateChange notifications.

More details can be found in the Call with Remotely Hosted Media article.

Call with Locally Hosted Media

And here is an example of creating a call with locally hosted media:

public async Task<CallDescription> CallInitializedAsync(ICall call, CallFlowDirection direction)
{
    // We setup a signaling handler and media session for each call.
    var mediaSession = this.Platform.CreateMediaSession(
        call, 
        new AudioSocketSettings
        {
            StreamDirections = StreamDirection.Recvonly,
            SupportedAudioFormat = AudioFormat.Pcm16K
        });

    var callHandler = new CallHandler(call, mediaSession);

    // We subscribe to AV socket events.
    mediaSession.AudioSocket.DominantSpeakerChanged += callHandler.OnDominantSpeakerChanged;
    mediaSession.VideoSocket.VideoMediaReceived += callHandler.OnVideoMediaReceived;

    // We return the CallDescription
    return new CallDescription(
        callHandler,
        mediaSession,
        new List<NotificationType> { 
            NotificationType.CallStateChange, 
            NotificationType.RosterUpdate});
}
Note

In the above example, note that this bot is again only subscribing to the Audio modality, and it's only listening on the CallStateChange and the RosterUpdate notifications.

Important

In both of the above examples, the CallHandler is written by the developer, but it must implement the ISignalingHandler interface in order to be accepted by the CallDescription constructor.

More details can be found in the Call with Locally Hosted Media article.

Incoming Call

Once the ICall has been initialized and the CallHandler has been passed into the SDK via the CallDescription, the SDK triggers an additional callback with the details of the call.

/// <summary>
/// Called when an incoming call is received. Returns one of the allowed options:
/// 1. AnswerOption
/// 2. DeclineOption
/// 3. RouteCallOption
/// The execution time of this method should take no more than 20 seconds,
/// otherwise the backend server will consider this callback as timed-out.
/// </summary>
/// <param name="call">
/// The call.
/// </param>
/// <param name="conversation">
/// The conversation contained in the incoming call.
/// </param>
/// <returns>
/// The <see cref="AnswerOption"/>.
/// </returns>
Task<AnswerOption> OnIncomingCallReceivedAsync(ICall call, Conversation conversation)

This callback expects an AnswerOption as a response. At this point, depending on the response the bot can take 3 different actions:

  1. AcceptOption, which tells the SDK to answer the call.
  2. DeclineOption, which tells the SDK to decline the call.
  3. ForwardOption, which tells the SDK to route the call to another participant (user or bot).

Whether the Accept/Decline/Forward options have been completed successfully or failed is returned through a subsequent callback.

/// <summary>
/// Called when an incoming call is completed.
/// The execution time of this method should take no more than 20 seconds,
/// otherwise the backend server will consider this callback as timed-out.
/// </summary>
/// <param name="call">
/// The call.
/// </param>
/// <param name="notification">
/// The notification.
/// </param>
/// <returns>
/// The <see cref="Task"/>.
/// </returns>
Task OnIncomingCallCompletedAsync(ICall call, AnswerNotification notification)

State Management

Optionally, the SDK can be configured to store state of the lifetime of the call in memory. This has 2 implications:

  1. The instance hosting the call needs to be up throughout the lifetime of the call.
  2. Any subsequent asynchronous notifications triggered by NGC need to be directed to the instance hosting the call.

By default, any configuration that allows the bot developer to host their media locally are stateful given that the media stream has a requirement that it needs to persist in memory throughout the lifetime of the call. Remotely hosted media scenarios can be either stateful or stateless, depending on other requirements.

More details can be found in the State Management article.

  • Improve this Doc
Back to top Copyright © 2015-2017 Microsoft
Generated by DocFX