Using Siperb Provisioning and Proxy

With the 3rd option you will use all the options, and have the most secure solution. Your PBX credentials are securely stored, out of sight from your users or even the public – you use “Connections” to connect with any number of PBX services, or ISPs. The next two options cover using Siperb as a provisioning service, and as a secure proxy (no exposed passwords), but we can still offer two ways to make the actual phone client, either use your own custom code (with a few extra headers), or just use our entire solution.

Option A — Login, Provision, Use Proxy and load a custom client

With this option, you will use the Web Phone SDK to login, and provision your own custom phone client using something like SIP.js, JsSIP, SIPml or even your own SIP JavaScript.

Note: You will have to add a Connection to the proxy in order to route calls between the client and your PBX.

Step 1 — Add a connection to the proxy

To add a connection to the proxy, you must login as either yourself or as an Administrator to a Domain User.

Once logged in as an owner, go to:
Setting Window -> Admin Control Panel -> Connections -> Add Connection

Once logged in as an administrator, go to:
Setting Window -> Admin Control Panel -> Domain Users -> (select the user) -> Connections (Tab) -> Add Connections

In the Add Connection window, select either Inbound Registration, Outbound Registration, or Outbound Trunk. You can read more about each type from the links. Each offers a slightly different technique to connect the Siperb Proxy with your PBX.

Step 2 — Load the Web Phone SDK

You will need to load the Web Phone SDK. Make sure you get the latest version from the CDN, or use the release code from the Github Repo: https://github.com/Siperb/Web-Phone/releases

Add the UDM JavaScript SDK to your page in the Head or Body. The script can load at any time, and can be loaded as async :

<head>
    ... (Other Headers)
    <script src="https://cdn.siperb.com/lib/Siperb-Web-Phone/Web-Phone-<version_number>.umd.min.js"></script>
</head>

or

<body>
    ... (site content)
    <script src="https://cdn.siperb.com/lib/Siperb-Web-Phone/Web-Phone-<version_number>.umd.min.js"></script>
</body>

Note: This exposes the SDK via a browser/global window.Siperb namespace, but since the code could be loaded at any time (via async), you must wait for the page to load before you use the SDK. window.addEventListener('load', async () => { })

Step 3 — Available SDK functions

The following objects are exported to the global namespace (window.Siperb) when the script loads. (If you are using ESM library, then these will become available to import).

/**
 * Login - fetches your session token using your access token.
 * @param {string} pat - Your Personal Access Token (PAT) generated from the Admin Control Panel
 * @returns {Promise<Object>} - resolves with session object
 */
Login(pat)

/**
 * GetProvisioning - fetches provisioning data and sets window.Siperb.PROVISIONING
 * @param {Object} options - options for provisioning retrieval
 * @returns {Promise<Object>} - resolves with provisioning object
 */
GetProvisioning(options)

Note: You have to execute LoadBrowserPhone() first, and you must await for the return before you can provision the phone.

Step 4 — Configure your SIP client

Since you will be using your own phone client, you will need to perform a few additional steps to your own chosen SDK. The following example is for JsSIP, but the same principle will be applied for SIPJS or others.

// Place in Head
<script src="https://cdn.siperb.com/lib/Siperb-Web-Phone/Web-Phone-<version_number>.umd.min.js"></script>

// Place in Head
<script>
const main = async function() {
    const accessToken = "<YOUR_PERSONAL_ACCESS_TOKEN>";   // Personal Access Token from ACP
    let session;
    try {
        session = await window.Siperb.Login(accessToken);
    } catch (error) {
        console.error('Failed to get session:', error); return;
    }

    const prov = await window.Siperb.GetProvisioning({
        UserId: session.UserId,                      // Your user id returned from Login
        DeviceToken: "<YOUR_KNOWN_DEVICE_TOKEN>";    // Device Token from ACP
        SessionToken: session.SessionToken,          // Your session token returned from Login
        EnableCache: true,                           // Turn caching on or off
        ProvisioningKey: "SIPERB_PROVISIONING".      // Key used in localstorage
    });
    
    // Build WebSocket server URL
    const wsServer = `wss://${prov.SipWssServer}:${prov.SipWebsocketPort}/${prov.SipServerPath}`;

    // Example JsSIP configuration using provisioning details
    const socket = new window.JsSIP.WebSocketInterface(wsServer);
    const configuration = {
        sockets: [socket],
        uri: `sip:${prov.SipUsername}@${prov.SipDomain}`,
        password: provisioning.SipPassword,
        contact_uri: `sip:${prov.ContactUserName}@${provisioning.SipDomain}`,
        extra_headers: [
            `X-Siperb-Sid: ${session.SessionToken}`,       // Your Siperb Session token
            `X-Siperb-Uid: ${session.UserId}`,             // Your Siperb User ID
            `Authorization: Bearer ${provisioning.SipJwt}` // Your Siperb JSON Web Token
        ]
    };

    // Start JsSIP UserAgent
    const ua = new window.JsSIP.UA(configuration);
    ua.start();
    console.log('JsSIP UA started.');

    // Example: Make an outbound call with custom headers
    const target = 'sip:*65@${prov.SipWssServer}';
    const eventHandlers = Array;
    const options = {
        extraHeaders: [
            `X-Siperb-Sid: ${session.SessionToken}`,       // Your Siperb Session token
            `X-Siperb-Uid: ${session.UserId}`,             // Your Siperb User ID
            `Authorization: Bearer ${provisioning.SipJwt}` // Your Siperb JSON Web Token
        ]
        // ...other call options as needed
    };
    ua.call(target, options);
    console.log('Outbound call initiated with custom headers.');
    // End of demonstration
}
window.addEventListener('load', async function(){ await main() });
</script>

Option B — Login, Provision, Use Proxy and load Browser Phone SDK

With this option, you will use the Web Phone SDK to login, and provision the Browser Phone SDK, and have a complete secure operational SIP based phone embedded into your web page.

Note: You will have to add a Connection to the proxy in order to route call between the client and your PBX.

Step 1 — Add a connection to the proxy

To add a connection to the proxy, you must login as either yourself or as an Administrator to a Domain User.

Once logged in as an owner, go to:
Setting Window -> Admin Control Panel -> Connections -> Add Connection

Once logged in as an administrator, go to:
Setting Window -> Admin Control Panel -> Domain Users -> (select the user) -> Connections (Tab) -> Add Connections

In the Add Connection window, select either Inbound Registration, Outbound Registration, or Outbound Trunk. You can read more about each type from the links. Each offers a slightly different technique to connect the Siperb Proxy with your PBX.

You will need to load the Web Phone SDK. Make sure you get the latest version from the CDN, or use the release code from the Github Repo: https://github.com/Siperb/Web-Phone/releases

Add the UDM JavaScript SDK to your page in the Head or Body. The script can load at any time, and can be loaded as async :

<head>
    ... (Other Headers)
    <script src="https://cdn.siperb.com/lib/Siperb-Web-Phone/Web-Phone-<version_number>.umd.min.js"></script>
</head>

or

<body>
    ... (site content)
    <script src="https://cdn.siperb.com/lib/Siperb-Web-Phone/Web-Phone-<version_number>.umd.min.js"></script>
</body>

Note: This exposes the SDK via a browser/global window.Siperb namespace, but since the code could be loaded at any time (via async), you must wait for the page to load before you use the SDK. window.addEventListener('load', async () => { })

The following objects are exported to the global namespace (window.Siperb) when the script loads. (If you are using ESM library, then these will become available to import).

/**
 * Login - fetches your session token using your access token.
 * @param {string} pat - Your Personal Access Token (PAT) generated from the Admin Control Panel
 * @returns {Promise<Object>} - resolves with session object
 */
Login(pat)

/**
 * GetProvisioning - fetches provisioning data and sets window.Siperb.PROVISIONING
 * @param {Object} options - options for provisioning retrieval
 * @returns {Promise<Object>} - resolves with provisioning object
 */
GetProvisioning(options)


/**
 * Load the Browser Phone into the IFRAME
 * @param {HTMLIFrameElement} The iframe element to load the phone into 
 * @returns {Promise<Object>} - resolves when done, or rejects with error
 */
LoadBrowserPhone(iframeElement)

/**
 * 
 * @param {Object} options object with the following properties:
 * @param {Object} options.Provisioning - The provisioning object
 * @param {HTMLIFrameElement} options.PhoneFrame - The iframe element containing the phone
 * @param {string} options.ProfileUserId - The Profile User ID (Device ID)
 * @param {string} options.SessionId - The current session ID
 * @param {string} options.UserId - The current user ID
 * @param {function} [options.OnLoad] - Optional OnLoad callback function
 * @returns {Promise} - Resolves when the phone is provisioned, or rejects with an error
 */
ProvisionPhone(options)

Note: You have to execute LoadBrowserPhone() first, and you must await for the return before you can provision the phone.

Step 3 — Complete example

The complete code of this solution is as follows:

// Place in Head
<script src="https://cdn.siperb.com/lib/Siperb-Web-Phone/Web-Phone-<version_number>.umd.min.js"></script>

// Sample IFRAME in DOM
<iframe
  id="phoneFrame"
  style="width:400px; height:640px; border:1px solid #000000; border-radius:5px; overflow:hidden;"
  allow="microphone; autoplay"
></iframe>

// Place in Head
<script>
const main = async function() {
    const accessToken = "<YOUR_PERSONAL_ACCESS_TOKEN>";   // Personal Access Token from ACP
    let session;
    try {
        session = await window.Siperb.Login(accessToken);
    } catch (error) {
        console.error('Failed to get session:', error); return;
    }

    const provisioning = await window.Siperb.GetProvisioning({
        UserId: session.UserId,                      // Your user id returned from Login
        DeviceToken: "<YOUR_KNOWN_DEVICE_TOKEN>";    // Device Token from ACP
        SessionToken: session.SessionToken,          // Your session token returned from Login
        EnableCache: true,                           // Turn caching on or off
        ProvisioningKey: "SIPERB_PROVISIONING".      // Key used in localstorage
    });
    
    const thePhoneFrame = document.getElementById("phoneFrame");
    await window.Siperb.LoadBrowserPhone(thePhoneFrame);
    const phoneAPI = await window.Siperb.ProvisionPhone({
        Provisioning : provisioning,            // The returned provisioning object
        PhoneFrame : thePhoneFrame,             // The HTMLIFrameElement object
        ProfileUserId : "<instance_id>",        // Any string to identify this instance
        SessionId : "<session_id>",             // Any string to identify this session
        UserId : "<user_id>",                   // Any string to identify this user
        // Optional Settings
        EnableAvatar : true,                    // Show user avatar/profile picture
        EnabledSettings : false,                // Show settings button
        EnableDialPad : true,                   // Show dial pad button
        EnableDisplayCallDetailRecords : true,  // Show call detail records button
        EnableCallTransfer : true,              // Enable call transfer feature 
        EnableCallHold : true,                  // Enable call hold feature
        EnableCallMute : true,                  // Enable call mute feature
        EnableCallRecording : true,             // Enable call recording feature
        EnableDeviceSelector : true,            // Enable media device selection
        // Settings normally in settings window
        EnableAutoAnswer : false,               // Auto answer incoming calls
        EnableDoNotDisturb : false,             // Do not disturb mode
        EnableCallWaiting : false,              // Call waiting feature
        Language : 'auto',                      // e.g. 'en-US' etc.
        DisplayDateFormat : 'MMM DD, YYYY',     // Moment JS date format
        DisplayTimeFormat : 'hh:mm A',          // Moment JS date time format
        UiThemeStyle : 'light',                 // 'light', 'dark', or 'system'
        // Optional: Callback when the phone UI has loaded and is ready
        OnLoad : function(){
            phoneAPI.Toast("Browser Phone UI has loaded and is ready.");
        }
        // Additional option go here...
    });
    // Add/Edit callbacks on phoneAPI here.  
    phoneAPI.InitTooltips(); // Apply the tool tips
    // Done
    console.log('✅ Browser Phone provisioned and running.');
}
window.addEventListener('load', async function(){ await main() });
</script>