Using Sinch JS SDK to Call a Phone Number

In this tutorial, you will build an app to call a regular phone number from your browser. This is a pretty sweet feature that can, for example, enable your users to call hotels in a different country cheaply and conveniently.

Application flow: Flow A: Register user -> place a call or Flow B: Login -> place a call

Setup

  1. If you don’t have a Sinch developer account, please sign up register a new app
  2. Download the SDK here

Create an index.html file with references to jQuery and the Sinch JavaScript SDK. Also, to get some basic CSS, you will use bootstrap.

Copy
Copied
<!DOCTYPE html>
<html>
  <head>
    <title>Call sinch</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="sinch.min.js"></script>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"
    />
  </head>
  <body></body>
</html>

Adding UI for login and user registration

You don’t want anonymous users to be able to go to your site and make a call without being logged in. (The SinchClient requires a user or token.) For this tutorial, you will use a very basic backend for user management to get started. You shouldn't use this in a production environment. In production, you should use your own user authentication. You can find a .net sample project here.

Copy
Copied
<div class="container">
  <div id="auth" class="col-md-6">
    <h2>Login or register</h2>
    <form id="userForm">
      <input id="username" placeholder="username" /><br />
      <input id="password" type="password" placeholder="password" /><br />
      <button id="loginUser">Login</button>
      <button id="createUser">Create</button>
    </form>
  </div>
  <div id="call" class="col-md-6">
    <h2>Make a call</h2>
    <input type="text" id="phoneNumber" />
    <button id="callNumber">Call</button>
  </div>
  <div class="col-md-12" id="error"></div>
</div>

Next, you need to register or log in the user.

  1. Add a Sinch client variable with your application key
  2. Hook up register button to a click event
  3. Hook up the login button to a click event
Copy
Copied
<script language="javascript">
$("#call").hide(); //hide the call ui
//1. Set up sinchClient
var sinchClient = new SinchClient({
    applicationKey: '<your application key>',
    capabilities: { calling: true },
    },
});
//2. Create user and start sinch for that user
$('button#createUser').on('click', function (event) {
    event.preventDefault();
    clearError();
    $('button#loginUser').attr('disabled', true);
    $('button#createUser').attr('disabled', true);
    var signUpObj = {};
    signUpObj.username = $('input#username').val();
    signUpObj.password = $('input#password').val();
    //Use Sinch SDK to create a new user
    sinchClient.newUser(signUpObj, function (ticket) {
        //On success, start the client
        sinchClient.start(ticket, function () {
            global_username = signUpObj.username;
            //On success, show the UI
        })
    })
});
//3. Login user and and start client
$('button#loginUser').on('click', function (event) {
    event.preventDefault();
    clearError();
    $('button#loginUser').attr('disabled', true);
    $('button#createUser').attr('disabled', true);
    var signInObj = {};
    signInObj.username = $('input#username').val();
    signInObj.password = $('input#password').val();

    //Use Sinch SDK to authenticate a user
    sinchClient.start(signInObj, function () {
        global_username = signInObj.username;
        //On success, show the UI
    })
});
</script>

Handle errors

It’s a good idea to take care of errors when you try to log in to the client. To handle errors, add a small error handler:

Copy
Copied
var handleError = function (error) {
  //Enable buttons
  $("button#createUser").prop("disabled", false);
  $("button#loginUser").prop("disabled", false);
  //Show error
  $("#error").text(error.message);
  $("#error").show();
};

Next, add an error <div> to the bottom on the page: html <div class="col-md-12" id="error"></div> Add fail functionality sinchClient.newUser like below:

Copy
Copied
sinchClient.newUser(signUpObj, function (ticket) {
  //On success, start the client
  sinchClient
    .start(ticket, function () {
      global_username = signUpObj.username;
      //On success, show the UI
    })
    .fail(handleError);
});

Then, do the same for the login button:

Copy
Copied
//Use Sinch SDK to authenticate a user
sinchClient
  .start(signInObj, function () {
    global_username = signInObj.username;
    //On success, show the UI
  })
  .fail(handleError);

Tidy up a bit by creating an clearError function and call it in your onClick handlers.

Copy
Copied
var clearError = function () {
  $("#error").text("");
  $("#error").show();
};

Add calling UI

When the user has successfully logged in, you want to show a UI to make a call. Create a function to hide the login UI and show a calling UI:

Copy
Copied
var showUI = function () {
  $("#auth").hide();
  $("#call").show();
};

Add a call to showUI() by replacing the comments //On success, show the UI

Making a call

To make a call, you will need a couple more elements in your call div. Add the following into <div id="call">.

Copy
Copied
<button id="hangupCall" style="display: none">Hangup</button>
<audio id="incoming" autoplay></audio>
<audio id="ringtone" src="ringtone.wav" loop></audio>
<div id="status"></div>

Next, add a click handler for the call button:

Copy
Copied
var callClient;
var call;
$("#callNumber").click(function (event) {
  event.preventDefault();
  callClient = sinchClient.getCallClient();
  $("#callNumber").attr("disabled", "disabled");
  $("#phoneNumber").attr("disabled", "disabled");
  $("#hangupCall").show();
  call = callClient.callPhoneNumber($("#phoneNumber").val());
  call.addEventListener(callListeners);
});

As you can see, you are missing event handlers for the call. A call can be in three states: inprogress, established and ended; they occur in that order. You’ll want to do the following:

  1. When call is in progress, play a ringtone like you hear on your regular phone
  2. When the call is established (someone has picked up or you are connected to their voicemail), stop playing the ringtone and instead play sound from the call
  3. When the call has ended, shut down the audio from the call and change the UI so the user can place a new call. In addition, your app will display some details about the call, like the duration.
Copy
Copied
var callListeners = {
  //1. start playing sound and display status
  onCallProgressing: function (call) {
    $("#ringtone").prop("currentTime", 0);
    $("#ringtone").trigger("play");
    $("#status").append('<div id="stats">Ringing...</div>');
  },
  //2. Call is pickedup (or voicemail)
  onCallEstablished: function (call) {
    $("audio#incoming").attr("src", call.incomingStreamURL);
    $("audio#ringtone").trigger("pause");
    //Report call stats
    var callDetails = call.getDetails();
    $("#status").append(
      '<div id="stats">Answered at: ' +
        new Date(callDetails.establishedTime) +
        "</div>"
    );
  },
  //3. Call ended, stop all sounds, and revert back
  onCallEnded: function (call) {
    /** you need to make sure the ringback is not
        playing incase the call ended from progress (no answer)**/
    $("audio#ringtone").trigger("pause");
    $("audio#incoming").attr("src", "");
    $("#callNumber").removeAttr("disabled");
    $("input#phoneNumber").removeAttr("disabled");
    $("#hangupCall").hide();
    //Report call stats
    var callDetails = call.getDetails();
    $("#status").append(
      '<div id="stats">Ended: ' + new Date(callDetails.endedTime) + "</div>"
    );
    $("#status").append(
      '<div id="stats">Duration (s): ' + callDetails.duration + "</div>"
    );
    $("#status").append(
      '<div id="stats">End cause: ' + callDetails.endCause + "</div>"
    );
    if (call.error) {
      $("div#callLog").append(
        '<div id="stats">Failure message: ' + call.error.message + "</div>"
      );
    }
  },
};

Hang up button

Last but not least, add a click handler for the hang up button:

Copy
Copied
$("#hangupCall").click(function (event) {
  event.preventDefault();
  call && call.hangup();
});

Run it

Either push this file to a webserver or run it locally. To give Chrome access to your microphone, launch it with with the flag –allow-file-access-from-files. On Windows, open a command prompt and type: pathtochrome%\chrome yourfilename.html --allow-file-access-from-files. On Mac: open -a Google\Chrome yourfilename.html --args --allow-file-access-from-files. For this to work, make sure to quit Chrome completely before reopening from the command line. Complete source code can be found at https://github.com/sinch/js-calling-tutorial .

Summary

Now you have a good understanding of how the Sinch client works and how to make a call with it. What’s next? Add your own authentication and make it more secure with the Sinch REST API.

Was this page helpful?