Skip to content

Getting started with .NET on Enfonica

This tutorial shows how to get started with Enfonica's communication API with .NET. Follow this tutorial by creating an outgoing phone call with the Enfonica .NET Client Library.

Objectives

  • Create an outgoing phone call with the API.
  • Control the call using code and synthesize speech.
  • Log the state changes that the call goes through to the console.

Costs

This tutorial uses the following billable components of Enfonica:

You will be charged for outgoing phone calls and speech synthesis.

Before you begin

  1. In the Enfonica Console, select the project that you want to use > click > Settings, and take note of your project name.

    Project Name

    Your project name will be of the form projects/*.

    Open Enfonica Console

  2. Create and download a service account key to use to authenticate the client library with Enfonica.

  3. Make sure you have Visual Studio 2019 (or later) or VS Code installed.

  4. Make sure you have .NET Core 3.1 SDK or later installed.

  5. Make sure you have ngrok installed and set up. This is used to allow Enfonica to send webhooks to the app running locally without setting up port forwarding.

Running the demo app locally

  1. Clone the getting-started-dotnet repository.

    git clone https://github.com/enfonica/getting-started-dotnet
    
  2. Copy your service account key to the root of the repository and rename the file service-account-key.json.

  3. Open the ApiDialler project, located in /src/ApiDialler/ApiDialler.csproj, with Visual Studio or VS Code.

  4. Run ngrok to forward HTTP traffic to the app on port 12964.

    ngrok http localhost:12964
    

    The ngrok interface will provide a forwarding URL such as https://randomletters.ngrok.io. Take note of this URL.

  5. Open Program.cs and take note of the constants CALL_TO, CALL_FROM, PROJECT and PUBLIC_BASE_URL.

    CALL_TO: The number that you want to make a call to.

    CALL_FROM: The caller ID that you want to use for the call.

    PROJECT: The project name you noted earlier.

    PUBLIC_BASE_URL: The ngrok forwarding URL you noted earlier.

  6. Run the application. A call should be created using the API. When it's answered, speech should be synthesized. As the call state changes, it should be logged to the console.

Understand how it works

Creating the outgoing call

In Program.cs, the app creates the calls client. This allows the app to interact with the Calls service. In your application, it's best to register this client for dependency injection.

// create Enfonica client
var client = new CallsClientBuilder().Build();

Next, the app builds the request to create a call.

// start outgoing call
logger.LogInformation("Creating outgoing API call");
var request = new CreateCallRequest()
{
    Parent = PROJECT,
    Call = new Call()
    {
        To = CALL_TO,
        From = CALL_FROM,
        Options = new Call.Types.ApiCallOptions()
        {
            StateUpdateUri = new Uri(new Uri(PUBLIC_BASE_URL),
                "/state-update").ToString()
        }
    }
};
request.Call.Options.HandlerUris.Add(
    new Uri(new Uri(PUBLIC_BASE_URL), "/handle-call").ToString());

This request object defines the recipient and caller ID of the call (To and From), and also two URIs that Enfonica will use to control the call (HandlerUris) and post state update webhooks (StateUpdateUri).

Next, Enfonica calls the CreateCall API. The Enfonica API is a resource based API. Using the CreateCall API will create a call with in the QUEUED state, after which Enfonica will place an actual outgoing call.

var call = await client.CreateCallAsync(request);

Controlling the call once it's connected

In Controllers/CallController.cs, the method HandleCall is called by Enfonica when the call has connected.

The app first parses the request, which will contain a JSON serialized CallRequest object.

// parse the request
string json;
using (var streamReader = new StreamReader(Request.Body, Encoding.UTF8))
{
    json = await streamReader.ReadToEndAsync();
}
var callRequest = _jsonParser.Parse<CallRequest>(json);

In a more in-depth application, other properties of this object are useful for controlling the call.

Next, the application returns an XML response. This instructs Enfonica to synthesize speech and implicitly hang up the call.

return Content(
@"<Response>
  <Say>Hi! This is a test of the API dialler! Good day.</Say>
</Response>", "application/xml");

Logging state updates

In Controllers/CallController.cs, the method StateUpdate is called by Enfonica when the state of the call changes.

The app first parses the request, which will contain a JSON serialized Call object.

// parse the request
string json;
using (var streamReader = new StreamReader(Request.Body, Encoding.UTF8))
{
    json = await streamReader.ReadToEndAsync();
}
var call = _jsonParser.Parse<Call>(json);

The app then logs the new state and returns a 204 No Content response.

_logger.LogInformation($"{call.Name} has changed state to {call.State}");
return NoContent();