PBX Manager Plugin

The PBX Manager is a PBX App, which is used for configuration tasks. An App Service can provide a plugin, which shows up in the PBX Manager and can configuration tasks for the App Service. Typical task would be creating PBX objects, configuring the App Instance, establish connections to other App Instances.

This documentation describes the following procedures used for these Plugings

Publish A PBX Manager plugin
An App Service may publish a PBX Manager Plugin, so that it shows up in the PBX Manager App.
Plugin Javascript
The PBX Manager loads a Javascript Object which has to conform to some definitions
Plugin Context
When the plugin is loaded, some other Javascript libraries are already loaded and some API functions are available from the PBX Manager
Plugin Templates
Some template files, which can be used to start a new plugin

Publish a PBX Manager plugin

To publish a PBX Manager Plugin the App Service adds a class AppInstancePlugin to the AppService pluginList by overwriting the virtual function AppInstancePlugins:

void <your AppService Class>::AppInstancePlugins(istd::list<AppInstancePlugin> * pluginList)
{
    pluginList->push_back(new AppInstancePlugin(<Javascript filename>, <Icon file>, <Language file>, <multiple domains>));
}
Javascript filename
The file name of the Javascript file, which shall be loaded as plugin without the .js extension.
Icon file
File for the Icon to be displayed in the PBX Manager App. Typically a 50x50px .png file is used
Language file
This is a file containing localized texts so that the title of the plugin can be displayed in the language of the user. It should contain a Javascript object with the same name as the filename, with properties for each supported language, which should contain the property "pluginTitle" as title
multiple Domain
If argument is true, the plugin is announced to all PBX Managers, regardless of the domain. If false the Plugin is only announced if the domain of the instance matches the domain of the PBX Manager.

A plugin typically consists of three files: The Javascript code of the plugin, the texts file for the localized texts and a css. It is recommended to use the following naming conventions for these files:

Javascript code
<company id>.<App name>Manager.js
Texsts file
<company id>.<App name>ManagerTexts.js
CSS file
<company id>.<App name>Manager.css

Plugin Javascript

The PBX Manager loads the Javascript file and expects a constructor function

plugin.<filename>
to exist, which is the called to allocate a Plugin object.

"plugin" is used as a namespace to avoid a conflict with other Javascritpt objects.

It is recommended to use the company id as object name inside plugin to avoid conflicts with any other plugin from other vendors.

The PBX Manager expects that a object which uses the innovaphone.ui1.nodePrototype as prototype to be created by this constructor function. A Node "div" with a class "item-node" should be created.

The constructor function has the following arguments

start
The innovaphone.lib1 start object, which can be used to access other myApps APIs
item
An object with informatio about the plugin
{
    ap: string,
    apDn: string,
    uri: string,
    png: string
}
ap
sip name of the AP object of the AP of this instance
apDn
Display name of the AP Object of the AP
uri
URI of the instance relative to the AP
png
The icon file
app
This is the innovaphone.appwebsocket.Connection object which is connected to the PBX so it can be used to access PBX APIs like "PbxAdminApi". In addition to the standard AppWebsocket connection object, it has a property "domain" which is set to the PBX domain.

Connect to the App instance

The plugin can establish a AppWebsocket connection to the App instance. For authentication the GetInstanceLogin message from the com.innovaphone.manager API can be used.

    var managerApi = start.consumeApi("com.innovaphone.manager");
    instance = new innovaphone.appwebsocket.Connection("ws" + item.uri.slice(4), "-", null, app.domain, instanceConnected, instanceMessage, null, null, instanceLogin);


    function instanceLogin(app, challenge) {
        managerApi.sendSrc({ mt: "GetInstanceLogin", path: item.uri.slice(item.uri.indexOf("/", 8) + 1, item.uri.lastIndexOf("/")), app: app, challenge: challenge }, item.ap, function (obj) {
            instance.login(obj.msg);
        });
    }

Set the instance password

When the Manager plugin configures the first App object for an instance, it should reset the instance password with a new randowm password. Use the function innovaphone.Manager.randomPwd(16) to generate such a random password. The com.innovaphone.manager SetInstancePassword can be used for this purpose

    var pwd = innovaphone.Manager.randomPwd(16);
    managerApi.sendSrc({ mt: "SetInstancePassword", path: item.uri.slice(item.uri.indexOf("/", 8) + 1, item.uri.lastIndexOf("/")), pwd: pwd }, item.ap, function (obj) {
        ...
    });

If an additional App object shall be configured, the password stored in this App object can be copied from an existing App object, which can be referenced with copyPwd in the UpdateObject message.

src.send({ mt: "UpdateObject", api: "PbxAdminApi", copyPwd: copyPwd, cn: obj.title, guid: obj.guid, h323: obj.sip, pseudo: { type: "app", ... }, ... });

Plugin Context

The following Javascript libries are loaded when the plugin is loaded:

Plugin Templates

In the template files replace <company id> by your company in all lower case, <app name> by your App name, starting with a capital letter and <app id> with your App name with all lower case.

<company id>.Manager<app name>.js

The main plugin javascript

/// <reference path="~/web1/lib1/innovaphone.lib1.js" />
/// <reference path="~/web1/ui1.lib/innovaphone.ui1.lib.js" />

var plugin = plugin || {};
plugin.innovaphone = plugin.innovaphone || {};
plugin.<company id>.Manager<app name> = <company id>.Manager<app name> || function (start, item, app) {
    this.createNode("div", null, null, "item-node");
    innovaphone.lib1.loadCss(item.uri + ".css");

    var colorSchemes = {
        dark: {
            "--<company id>-<app id>-c1": "#efefef",
        },
        light: {
            "--<company id>-<app id>-c1": "#444444",
        }
    };

    var schemes = new innovaphone.ui1.CssVariables(colorSchemes, start.scheme);
    start.onschemechanged.attach(function () { schemes.activate(start.scheme) });

    var texts;
    var panel = this.add(new innovaphone.ui1.Div(null, "== plugin ==", "<company id>-<app id>-panel"));

    innovaphone.lib1.loadObjectScript(item.uri + "Texts", function () {
        texts = new innovaphone.lib1.Languages(<company id>.Manager<app name>Texts, start.lang);
        init();
    });

    function init() {

    }
}
plugin.innovaphone.Manager<app name>.prototype = innovaphone.ui1.nodePrototype;
<company id>.Manager<app name>Texts.js

The texts file

innovaphone.Manager<app name>Texts = {
    en: {
        pluginTitle: "<app name>",
    },
    de: {
        pluginTitle: "<app name>",
    }
}
<company id>.Manager<app name>.css

The CSS

div.<company id>-<app id>-panel {
    position:absolute;
    left:0px;
    right:0px;
    top:0px;
    bottom:0px;
    color:var(--<company id>-<app id>-c1);
    font-size:14px;
}