import {JSJaCJID, JSJaCWebSocketConnection, JSJaCHttpBindingConnection, JSJaCPresence, JSJaCIQ} from './jsjac';
/**
* WTAPI Library
*
* @version 1.0.0
*/
/**
* Represents a WTAPI instance
*
* @constructor
* @augments Observer
*/
function WTAPI() {
this.version = '@VERSION@';
this.applicationId = '';
this.redirectUri = '';
this.storage = sessionStorage;
this.state = 'wtapiAuth';
this.server = 'wildix';
this.resource_prefix = 'wtapi';
this.licenseType = '';
this.connected = false;
this.connecting = false;
this.handlers = {};
// Initialize supper
WTAPI.Observable.call(this);
// Initialize plugins
for(var i=0; i < this.plugins.length; i++) {
var plugin = this.plugins[i];
var instance = new plugin.cls(this);
this[plugin.name] = instance;
}
}
// ============================================================
// Shared classes
// ============================================================
/**
* @constructor
*/
WTAPI.Observable = function() {
this._listeners = {};
}
/**
* Registers a listener to receive events.
*
* @alias on
* @param event {string}
* @param callback {function}
*/
WTAPI.Observable.prototype.addListener = function(event, callback) {
var scope = arguments[2] || this;
var handler = {
callback: callback,
scope: scope
}
if (typeof(this._listeners[event]) === "undefined") {
this._listeners[event] = [handler];
} else {
this._listeners[event].push(handler);
}
};
WTAPI.Observable.prototype.on = WTAPI.Observable.prototype.addListener;
/**
* Removes a previously registered listener.
*
* @param event
* @param callback
*/
WTAPI.Observable.prototype.removeListener = function(event, callback) {
var listeners = this._listeners[event];
if (typeof(listeners) !== "undefined") {
var filtered = [];
for(var i=0; i < listeners.length; i++) {
if (listeners[i]['callback'] != callback) {
filtered.push(listeners[i]);
}
}
this._listeners[event] = filtered;
}
};
/**
* Broadcast event to listeners.
*
* @param event
* @private
*/
WTAPI.Observable.prototype._fire = function(event) {
var listeners = this._listeners[event];
var args = Array.prototype.slice.call(arguments, 1, arguments.length);
if (typeof(listeners) !== "undefined") {
for(var i=0; i < listeners.length; i++) {
var listener = listeners[i];
listener.callback.apply(listener.scope, args);
}
}
};
// ============================================================
// Public events
// ============================================================
/**
* Indicates that connection to PBX is established
*
* @event WTAPI#connected
*/
/**
* Indicates that connection with PBX is lost
*
* @event WTAPI#disconnected
*/
// ============================================================
// Static functionality
// ============================================================
WTAPI.prototype = Object.create(WTAPI.Observable.prototype);
WTAPI.prototype.plugins = [];
/**
*
*
* @private
* @param {string} name Plugin name
* @param {object} cls Plugin class (plugin prototype)
*/
WTAPI.addPlugin = function(name, cls) {
var plugin = {
name: name,
cls: cls
}
WTAPI.prototype.plugins.push(plugin);
}
// ============================================================
// Public functionality
// ============================================================
/**
* Set credentials storage
*
* @param storage
* @access public
*/
WTAPI.prototype.setStorage = function(storage) {
this.storage = (storage instanceof Storage) ? storage : sessionStorage;
}
/**
* Set options
*
* @param options
* @access public
*/
WTAPI.prototype.setOptions = function(options) {
let url = options.pbxUrl;
let extension = '';
let password = '';
let conLocation = {
host: '',
protocol: 'https:',
path: '/authorization/oauth2'
}
let newUrl = url.replace(conLocation.protocol + '//', '').split('/');
conLocation.host = newUrl[0];
this.pbxUrl = conLocation.protocol + '//' + conLocation.host;
this.applicationId = options.applicationId;
this.redirectUri = options.redirectUri;
this.responseType = (typeof options.responseType === 'string') ? options.responseType : 'token';
this.scope = (typeof options.scope === 'string') ? options.scope : '';
this.prompt = (typeof options.prompt === 'string') ? options.prompt : 'consent';
this.resource_postfix = Math.round(Math.random()*10000);
this.recon_time = 0;
this.recon_timeout = false;
this.recon_timeout_min = 2;
this.recon_timeout_max = 16;
this.recon_timeout_skip = 360;
this.recon_inactivity = 45;
this.verify_time = false;
this.verify_timeout = 1;
this.con = false;
this.con_id = 0;
this.con_rid = false;
this.con_secs = 0;
this.con_url = url;
this.host = conLocation.host;
this.protocol = conLocation.protocol;
this.authorizationUri = conLocation.path;
this.con_errors = new Array();
this.con_wait = 30;
this.con_debuger = null; // new JSJaCConsoleLogger(99);
this.con_props = {
httpbase: this.con_url,
wait: this.con_wait,
oDbg: this.con_debuger
}
WTAPI.ajax.settings.host = this.host;
WTAPI.ajax.settings.protocol = this.protocol;
// TODO: window.onbeforeunload = this.disconnect;
this.extension = extension;
this.password = password;
this.resource = this._makeResource(extension, password, this.resource_prefix, this.resource_postfix);
this.jid = extension +"@"+ this.server;
this.jid_full = this.jid +"/"+ this.resource;
this.sid = this._makeUniqueId(extension, password, 'wtapi');
}
/**
* Handle authorization response
*
* @access public
*/
WTAPI.prototype.handleAuthorizationResponse = function() {
const data = this._parseParamsFromString(location.hash.substring(1));
if (((typeof data.access_token === 'string' && data.access_token.length > 0) || typeof data.error === 'string')
&& typeof data.state === 'string'
&& data.state === this.state
) {
data.response_type = 'token';
this._sendParamsToOpener(data);
}
}
/**
* Connects to a Wildix XMPP server.
*
* Connections can be reused between connections.
* This means that an Connection may be connected, disconnected and then connected again.
* Listeners of the Connection will be retained accross connections.
*
* If a connected Connection gets disconnected abruptly then it will try to reconnect again.
* To stop the reconnection process, use disconnect(). Once stopped you can use connect() to manually connect to the server.
*
* @access public
*/
WTAPI.prototype.connect = function() {
this.con_reconnect = true;
let params = {
client_id: this.applicationId,
redirect_uri: this.redirectUri,
response_type: this.responseType,
scope: this.scope,
state: this.state,
prompt: this.prompt
};
let paramsQuery = new URLSearchParams(params).toString();
window.open(`${this.protocol}//${this.host}${this.authorizationUri}?${paramsQuery}`,
'wtapiOAuthWin',
'width=600,height=700,left=0,top=0'
)
}
/**
* Restore saved in storage authorization credentials
*
* @access public
*/
WTAPI.prototype.restoreSavedCredentials = function() {
let data = this.getCredentials();
if (data && typeof data.accessToken === 'string') {
this.setOptions(data);
WTAPI.ajax.setAuthorizationToken(data.accessToken);
this._getPersonalInfo();
}
this._fire('restoreCredentials', data);
}
WTAPI.prototype.deleteSavedCredentials = function() {
this.storage.removeItem(this.resource_prefix);
}
/**
* Get saved credentials
*
* @access public
*/
WTAPI.prototype.getCredentials = function() {
let savedData = this.storage.getItem(this.resource_prefix);
try {
savedData = JSON.parse(savedData);
} catch (e) {
savedData = null;
}
return savedData;
}
/**
* @param data
* @private
*/
WTAPI.prototype._saveCredentials = function (data) {
let save = {
accessToken: data.access_token,
expires: (new Date().getTime()) + data.expires_in * 1000,
applicationId: this.applicationId,
redirectUri: this.redirectUri,
responseType: this.responseType,
pbxUrl: this.pbxUrl,
};
this.storage.setItem(this.resource_prefix, JSON.stringify(save));
};
/**
* @param str
* @returns {{}}
* @private
*/
WTAPI.prototype._parseParamsFromString = function (str) {
const params = {};
let regex = /([^&=]+)=([^&]*)/g, m;
while (m = regex.exec(str)) {
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
return params;
};
/**
* Send OAuth data to opener window
*
* @param params {object}
* @private
*/
WTAPI.prototype._sendParamsToOpener = function(params) {
if (typeof window.opener.oauth2Callback !== 'function') {
let err = 'Not found function oauth2Callback on the opener window. Please check it.';
window.opener.console.error(err);
window.document.body.innerText = err;
return false;
}
window.opener.oauth2Callback(params);
window.close();
}
WTAPI.prototype.handleCallbackData = function(params) {
if (typeof params.error !== 'undefined') {
this.disconnect();
this._fire('oauthAuthorizationError', params);
} else if (params.response_type === 'token') {
this._saveCredentials(params);
WTAPI.ajax.setAuthorizationToken(params.access_token);
this._getPersonalInfo()
.then(() => this._sendLogs())
.catch(() => console.log('Error get personal info'));
this._fire('oauthAuthorizationSuccess', params);
}
}
/**
* @private
*/
WTAPI.prototype._sendLogs = function() {
if (localStorage.getItem('wtapi2_' + this.server)) {
return;
}
this._getPbxInfo()
.then(() => {
WTAPI.ajax({
protocol: 'https:',
host: 'feedback.wildix.com',
url: '/api/v1/Analytics/wtapi',
type: 'POST',
data: {
event: 'authorization',
data: JSON.stringify({
license: this.getLicenseType(),
userExtension: this.getExtension(),
userJid: this.getFullJid(),
pbxSerial: this.pbxSerial,
pbxVersion: this.pbxVersion,
pbxDomain: this.server,
wtapiVersion: this.getVersion()
})
},
success: () => localStorage.setItem('wtapi2_' + this.server, '1'),
error: () => console.log('Error sending logs')
});
})
.catch(() => console.log('Error get pbx info'));
}
/**
* @private
*/
WTAPI.prototype._getPbxInfo = function () {
this.pbxSerial = '';
this.pbxVersion = '';
return new Promise((resolve, reject) => {
WTAPI.ajax({
url: '/api/v1/ios/config/',
type: 'GET',
data: {
fields: 'pbxInfo'
},
success: (data) => {
if (data.type === 'result' && data.result) {
this.pbxSerial = data.result.pbxInfo.serial ? data.result.pbxInfo.serial : '';
this.pbxVersion = data.result.pbxInfo.version;
}
resolve();
},
error: () => reject()
});
});
}
/**
* @private
*/
WTAPI.prototype._getPersonalInfo = function() {
this.extension = '';
this.password = '';
this.jid = '';
this.jid_full = '';
this.sid = '';
return new Promise((resolve, reject) => {
WTAPI.ajax({
url: '/api/v1/personal/info',
type: 'GET',
data: {
fields: 'extension,name,jid,password,email,login,licenseType'
},
success: this._proxy(function(data, textStatus, jqXHR){
if(data.type == 'result' && data.result){
this.extension = data.result['extension'];
if(data.result.hasOwnProperty('password')){
this.password = data.result['password'];
}
this.resource = this._makeResource(this.extension, this.password, this.resource_prefix, this.resource_postfix);
this.jid = this.extension +"@"+ this.server;
this.jid_full = this.jid +"/"+ this.resource;
this.sid = this._makeUniqueId(this.extension, this.password, 'wtapi');
this.licenseType = data.result['licenseType'];
if(this.extension && data.result.hasOwnProperty('jid')){
var jid = new JSJaCJID(data.result.jid);
this.server = jid.getDomain();
this.jid = data.result.jid;
this.jid_full = this.jid +"/"+ this.resource;
this.con_props.httpbase = ((this.protocol == 'http:')? 'ws': 'wss') + '://'+ this.host+'/xmpp/';
this._connect(true);
} else {
this._connect();
this._verify();
}
}
resolve();
}, this),
error: this._proxy(function(jqXHR, textStatus, data){
var error = jqXHR.statusText;
if(jqXHR && jqXHR.responseText){
try {
var response = JSON.parse(jqXHR.responseText);
if(response['type'] && response['type'] == 'error'){
error = response.reason;
}
} catch (e) {
}
}
this._fire("disconnected", error);
reject();
}, this)
});
});
}
/**
* @private
*/
WTAPI.prototype._connect = function(ws) {
ws = ws || false;
this.con_id++;
if(ws){
this.con = new JSJaCWebSocketConnection(this.con_props);
}else{
this.con = new JSJaCHttpBindingConnection(this.con_props);
}
this.con.registerHandler('onconnect', this._proxy(this._handleConnected, this));
this.con.registerHandler('ondisconnect', this._proxy(this._handleDisconnected, this));
this.con.registerHandler('onerror', this._proxy(this._handleConnectionError, this));
this.con.registerHandler('presence', this._proxy(this._handlePresence, this));
this.con.registerHandler('message', this._proxy(this._handleMessage, this));
this.con.registerHandler('iq', this._proxy(this._handleIQ, this));
this.con.registerHandler('iq', 'ping', 'urn:xmpp:ping', this._proxy(this._handlePing, this));
var params = {
domain: this.server,
username: this.extension,
pass: this.password,
resource: this.resource,
register: false
}
this.connecting = true;
try {
this.con.connect(params);
} catch (e) {
console.log(e);
}
}
/**
* Closes the connection to Wildix XMPP server.
*
* @access public
*/
WTAPI.prototype.disconnect = function() {
this.con_reconnect = false;
this._disconnect();
}
/**
* @private
*/
WTAPI.prototype._disconnect = function() {
this.connected = false;
try {
this.con.disconnect();
} catch(e) {
this.con_errors.push(e);
}
}
/**
*
* @private
*/
WTAPI.prototype.isNewServer = function() {
return this.server != 'wildix';
}
/**
*
* @private
* @returns {JSJaCConnection}
*/
WTAPI.prototype.getConnection = function() {
return this.con;
}
/**
* Returns true if currently connected to the Wildix XMPP server.
*
* @access public
* @returns {boolean}
*/
WTAPI.prototype.isConnected = function() {
return this.connected;
}
/**
* Register a handler for specified event.
* Following events are supported:
* onconnect - fires when successfully connected to XMPP server (fired on reconnect also).
* ondisconnect - fires when disconnected from XMPP server (fired on reconnect also).
* onerror - fires when error returns from XMPP server.
* presence - fires when presence packet are received.
* message - fires when message packet are received.
* iq - fires when iq packet are received.
*
* @private
* @param event {string}
* @param callback {function}
* @param scope {object}
* @param priority {int}
*/
WTAPI.prototype.registerHandler = function(event, callback, scope, priority) {
var handler = {
callback: callback,
scope: scope,
priotiry: priority
}
if (typeof(this.handlers[event]) === "undefined") {
this.handlers[event] = [handler];
} else {
this.handlers[event].push(handler);
this.handlers[event].sort(this._priorityComparator);
}
};
/**
* Unregister a previously registered handler.
*
* @param event {string}
* @param callback {function}
*/
WTAPI.prototype.unregisterHandler = function(event, callback) {
var events = this.handlers[event];
if (typeof(events) !== "undefined") {
var filtered = [];
for(var i=0; i < events.length; i++) {
if (events[i]['callback'] != callback) {
filtered.push(events[i]);
}
}
this.handlers[event] = filtered;
}
};
/**
* Returns extension that are used to connect to Wildix XMPP server.
*
* @returns {string}
*/
WTAPI.prototype.getExtension = function() {
return this.extension;
}
/**
* Returns a JID that are used to connect to Wildix XMPP server.
*
* @returns {string}
*/
WTAPI.prototype.getJid = function() {
return this.jid;
}
/**
* Returns a full JID (with resource) that are used to connect to Wildix XMPP Server.
*
* @returns {string}
*/
WTAPI.prototype.getFullJid = function() {
return this.jid_full;
}
/**
* Returns a license type that are used to connect to Wildix XMPP Server.
*
* @returns {string}
*/
WTAPI.prototype.getLicenseType = function() {
return this.licenseType;
}
/**
* Return the version wtapi.js.
*
* @returns {string}
*/
WTAPI.prototype.getVersion = function() {
return this.version;
}
/**
* @private
* @param event
* @param args
*/
WTAPI.prototype._execute = function(event, args) {
var handlers = this.handlers[event];
if (typeof(handlers) !== "undefined") {
for(var i=0; i < handlers.length; i++) {
var handler = handlers[i];
var handled = handler.callback.apply(handler.scope, args);
if (handled) {
break;
}
}
}
}
// ============================================================
// JsJac callbacks
// ============================================================
/**
* @private
* @event WTAPI#connected
*/
WTAPI.prototype._handleConnected = function() {
this.connecting = false;
this.connected = true;
this._fire("connected");
// We should clear reconnection timers after good connection delay
var id = this.con_id;
setTimeout(function() {
if (id == this.con_id) {
this.recon_time = false;
this.recon_timeout = false;
}
}, this.recon_timeout_skip * 1000);
// -----
var presence = new JSJaCPresence();
this.con.send(presence);
}
/**
* Connection error handler
*
* @private
* @param error {Node}
*/
WTAPI.prototype._handleConnectionError = function(error) {
// Verify whether problem is in resource name.
if (error.getAttribute("code") == "503" && error.firstChild && error.firstChild.tagName == "remote-stream-error") {
this.resource_postfix = Math.round(Math.random()*10000);
this.resource = this._makeResource(this.extension, this.password, this.resource_prefix, this.resource_postfix);
this.jid_full = this.jid +"/"+ this.resource;
}
if (!this._connected) {
this.con_errors.push(error);
this._disconnect();
this._handleDisconnected();
}
this.con_errors.push(error);
this.connecting = false;
}
/**
* Fires when user has been disconnected (fired by jsjac connection object).
*
* @private
* @event WTAPI#connected
*/
WTAPI.prototype._handleDisconnected = function() {
var error;
if (this.con_errors.length > 0) {
error = this.con_errors[0];
if (error instanceof Node) {
var tmp = document.createElement("div");
tmp.appendChild(this.con_errors[0]);
error = tmp.innerHTML;
}
}
this.connected = false;
this.connecting = false;
this._fire("disconnected", error);
}
/**
* @private
*/
WTAPI.prototype._handlePresence = function() {
this._execute("presence", arguments);
}
/**
* @private
*/
WTAPI.prototype._handleMessage = function() {
this._execute("message", arguments);
}
/**
* @private
*/
WTAPI.prototype._handleIQ = function() {
this._execute("iq", arguments);
}
/**
* @private
*/
WTAPI.prototype._handlePing = function(iq) {
var packet = new JSJaCIQ();
packet.setTo(iq.getFrom());
packet.setType('result');
packet.setID(iq.getID());
this.con.send(packet);
}
// ============================================================
// Private functionality
// ============================================================
/**
* @private
*/
WTAPI.prototype._verify = function() {
var time = Math.round(new Date().getTime() / 1000);
if (this.con_reconnect) {
if (this.con_errors.length > 0) {
this.con_errors = new Array();
// Define reconnection timeout
this.recon_time = this.verify_timeout;
this.recon_timeout = this._random(this.recon_timeout_min, this.recon_timeout_max);
} else if (this.connected == false && this.connecting == false) {
if (this.recon_time) {
// We should connect to server when timeout has come
if (this.recon_time >= this.recon_timeout) {
this._connect();
} else {
this.recon_time += this.verify_timeout;
}
} else {
this._connect();
}
} else if (this.connected == true) {
this.con_secs += this.verify_timeout;
// Solution to detect if user hasn't internet connection.
if (this.con_rid != this.con._rid) {
this.con_rid = this.con._rid;
this.con_secs = 0;
} else if (this.con_secs > this.recon_inactivity) {
if (this.connected && !this.connecting) {
this.con_errors.push("Found this connection is not alive!");
this._disconnect();
}
}
// Solution to check if computer was in sleep mode or other problem occurs (browser doesn't execute javascript)
if (this.verify_time) {
var diff = Math.abs(time - this.verify_time);
if (diff > this.con_wait) {
if (!this.connecting) {
this.con_errors.push("Found this computer was in sleep mode");
this._disconnect();
}
}
}
}
}
this.verify_time = time;
setTimeout(this._proxy(this._verify, this), this.verify_timeout * 1000);
}
/**
* Generates a resource for connection.
* Resource generation is based on username, password, browser name and protocol.
*
* @private
* @param username
* @param password
* @param prefix
* @param postfix
*/
WTAPI.prototype._makeResource = function(username, password, prefix, postfix) {
var str = username +"-"+ password +"-"+ window.location.protocol +"-"+ navigator.userAgent;
var hash1 = (5381<<16) + 5381;
var hash2 = hash1;
var hashPos = 0;
var resource = "";
while(hashPos < str.length) {
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ str.charCodeAt(hashPos);
if( hashPos == str.length - 1) {
break;
}
hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ str.charCodeAt(hashPos + 1);
hashPos += 2;
}
hash1 = new String(hash1);
hash2 = new String(hash2 * 1566083941);
resource = prefix +"-"+ username + "-" + hash1.substr(hash1.length - 4, 4) + "-" + hash2.substr(hash1.length - 4, 4)
if (postfix) {
resource = resource +"-"+ postfix;
}
return resource;
}
/**
* Generates an unique id for current browser (used in resource)
*
* @private
* @param username
* @param password
* @param prefix
*/
WTAPI.prototype._makeUniqueId = function(username, password, prefix) {
var str = username + password + window.location.protocol + navigator.userAgent + Math.random();
var hash1 = (5381<<16) + 5381;
var hash2 = hash1;
var hashPos = 0;
while(hashPos < str.length) {
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ str.charCodeAt(hashPos);
if( hashPos == str.length - 1) {
break;
}
hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ str.charCodeAt(hashPos + 1);
hashPos += 2;
}
hash1 = new String(hash1);
hash2 = new String(hash2 * 1566083941);
return prefix +"_"+ username + "_" + hash1.substr(hash1.length - 4, 4) + "_" + hash2.substr(hash1.length - 4, 4);
}
/**
* Generates a random number in specified range.
*
* @private
* @param from int
* @param to int
*/
WTAPI.prototype._random = function(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
/**
* Wraps callback to be sure that function will be executed in proper scope
*
* @private
* @param callback function
* @param scope object
*/
WTAPI.prototype._proxy = function(callback, scope) {
return function() {
callback.apply(scope, arguments);
};
}
/**
* TODO: Description
*
* @private
*/
WTAPI.prototype._priorityComparator = function(a, b) {
if (a.priotiry < b.priotiry)
return -1;
if (a.priotiry > b.priotiry)
return 1;
return 0;
}
// ============================================================
// Public classes
// ============================================================
/**
* Represents a user that are participated in Wildix PBX.
*
* @param jid {string}
* @param name {string}
* @constructor
*/
WTAPI.User = function(jid, name) {
this._id = WTAPI.User._id++;
this._jid = jid;
this._name = name || null;
this._group = null;
// Determine extension
var s = this._jid.split("@");
if(s.length > 1 && (s[1] == '172.16.0.6' || s[1] == 'kite.wildix.com')){
this._group = 'Kite';
}
this._extension = s[0];
}
WTAPI.User._id = 1;
/**
* Returns a User <b>temporary</b> id.
* This identifier is not unique and will be changed between page refresh
*
* @returns {string}
*/
WTAPI.User.prototype.getId = function() {
return this._jid;
}
/**
* Returns a JID of User.
* JID is a unique identity of a user.
*
* @returns {string}
*/
WTAPI.User.prototype.getJid = function() {
return this._jid;
}
/**
* Returns a name of User. Can be null when name is not available at that moment.
* For example it is not possible to know a name of users that are not in roster.
* If you want to use remote user name, you should request roster before ( {@link https://www.wildix.com/webapi/doc/WTAPI.RosterPlugin.html | WTAPI.RosterPlugin().getRoster(callback)} ).
*
* @returns {string|null}
*/
WTAPI.User.prototype.getName = function() {
return this._name;
}
WTAPI.User.prototype.setName = function(name) {
this._name = name;
}
/**
* Returns an extension of User. Can be null when user doesn't have extension, for example user from MashUp service.
*
* @returns {string|null}
*/
WTAPI.User.prototype.getExtension = function() {
return this._extension;
}
WTAPI.User.prototype.isGroupExist = function() {
return this._group !== null;
}
WTAPI.User.prototype.getGroup = function() {
return this._group;
}
WTAPI.User.prototype.setGroup = function(group) {
this._group = group;
}
/**
* Represents call information of user.
* Used in user presence status and can be received from WTAPI.Presence.
*
* @param name {string}
* @param number {string}
* @constructor
*/
WTAPI.ConnectedCall = function(name, number) {
this._name = name;
this._number = number;
}
/**
* Returns the name of this connected call.
*
* @returns {*}
*/
WTAPI.ConnectedCall.prototype.getName = function() {
return this._name;
}
/**
* Returns the number of this connected call.
*
* @returns {*}
*/
WTAPI.ConnectedCall.prototype.getNumber = function() {
return this._number;
}
/**
* Represents a geographic location of User.
* Used in user presence and can be received from WTAPI.Presence.
*
* @param address {string}
* @param lat {string}
* @param lng {string}
* @constructor
*/
WTAPI.Location = function(address, lat, lng) {
this._address = address;
this._lat = lat;
this._lng = lng;
}
/**
* Returns the human-readable address of this location.
*
* @returns {*}
*/
WTAPI.Location.prototype.getAddress = function() {
return this._address;
}
/**
* Returns the latitude in degrees.
*
* @returns {*}
*/
WTAPI.Location.prototype.getLat = function() {
return this._lat;
}
/**
* Returns the longitude in degrees.
*
* @returns {*}
*/
WTAPI.Location.prototype.getLng = function() {
return this._lng;
}
/**
* Represents a profile data location of User.
* Used in user presence and can be received from WTAPI.Presence.
*
* @param mail {string}
* @param authProvider {string}
* @param url {string}
* @param gender {string}
* @param language {string}
* @param parentHostUrl {string}
* @param photo {string}
* @constructor
*/
WTAPI.ProfileData = function(mail, authProvider, url, gender, language, parentHostUrl, photo) {
this._mail = mail;
this._authProvider = authProvider;
this._url = url;
this._gender = gender;
this._language = language;
this._parentHostUrl = parentHostUrl;
this._photo = photo;
}
/**
* Returns the mail address of this profile data.
*
* @returns {*}
*/
WTAPI.ProfileData.prototype.getMail = function() {
return this._mail;
}
/**
* Returns the auth provider.
*
* @returns {*}
*/
WTAPI.ProfileData.prototype.getAuthProvider = function() {
return this._authProvider;
}
/**
* Returns the url.
*
* @returns {*}
*/
WTAPI.ProfileData.prototype.getUrl = function() {
return this._url;
}
/**
* Returns the gender.
*
* @returns {*}
*/
WTAPI.ProfileData.prototype.getGender = function() {
return this._gender;
}
/**
* Returns the language.
*
* @returns {*}
*/
WTAPI.ProfileData.prototype.getLanguage = function() {
return this._language;
}
/**
* Returns the parent host url.
*
* @returns {*}
*/
WTAPI.ProfileData.prototype.getParentHostUrl = function() {
return this._parentHostUrl;
}
/**
* Returns the photo url.
*
* @returns {*}
*/
WTAPI.ProfileData.prototype.getPhoto = function() {
return this._photo;
}
/**
* Represents a Presence of a User.
* Use WTAPI.Presence.Builder to create a new presence.
*
* @memberof WTAPI
* @alias WTAPI.Presence
* @public
* @constructor
*/
WTAPI.Presence = function() {
this._online = false;
this._show = WTAPI.Presence.NONE;
this._deviceShow = WTAPI.Presence.NONE;
this._status = null;
this._location = null;
this._profileData = null;
this._until = null;
this._connectedCall = null;
}
WTAPI.Presence.NONE = 0;
WTAPI.Presence.AWAY = 1;
WTAPI.Presence.DND = 2;
WTAPI.Presence.RINGING = 3;
WTAPI.Presence.TALKING = 4;
WTAPI.Presence.RT = 5;
WTAPI.Presence.MUR = 6;
WTAPI.Presence.REGISTERED = 7;
/**
* Returns true if user is online (available) and false if the user is offline (unavailable).
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isOnline = function() {
return this._online;
}
/**
* Returns true if user set away status.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isAway = function() {
return this._show === WTAPI.Presence.AWAY;
}
/**
* Returns true if user set DND status.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isDND = function() {
return this._show === WTAPI.Presence.DND;
}
/**
* Returns true if user set MUR status.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isMUR = function() {
return this._show === WTAPI.Presence.MUR;
}
/**
* Returns true if somebody is calling to user.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isRinging = function() {
return (this._deviceShow === WTAPI.Presence.RINGING || this._deviceShow === WTAPI.Presence.RT);
}
/**
* Returns true if user is talking with somebody.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isTalking = function() {
return (this._deviceShow === WTAPI.Presence.TALKING || this._deviceShow === WTAPI.Presence.RT);
}
/**
* Returns true if user is talking and somebody tries to call him.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isTalkingAndRinging = function() {
return this._deviceShow === WTAPI.Presence.RT;
}
/**
* Returns true if user has a registered device.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isRegisteredDevice = function() {
return this._deviceShow === WTAPI.Presence.REGISTERED;
}
/**
* Returns true if user is offline and has default values for other properties.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isEmpty = function() {
if (this._show !== WTAPI.Presence.NONE ||
this._deviceShow !== WTAPI.Presence.NONE ||
this._location !== null ||
this._profileData !== null ||
this._until !== null ||
this._status !== null) {
return false;
}
return true;
}
/**
* Returns a status icon representing a current status.
* Possible values:
* away
* away-offline
* dnd
* dnd-offline
* mur
* mur-offline
* online
* offline
*
* @returns {String}
*/
WTAPI.Presence.prototype.getStatusIcon = function() {
switch (this._show) {
case WTAPI.Presence.AWAY:
return this._online ? "away" : "away-offline"
case WTAPI.Presence.DND:
return this._online ? "dnd" : "dnd-offline"
case WTAPI.Presence.MUR:
return this._online ? "mur" : "mur-offline"
default:
return this._online ? "online" : "offline"
}
}
/**
* Returns the status message of the presence, or null if user doesn't set it.
*
* @returns {String|null}
*/
WTAPI.Presence.prototype.getStatusMessage = function() {
return this._status;
}
/**
* Returns true if user set custom status message.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isStatusMessageAvailable = function() {
return this._status !== null;
}
/**
* Returns the expire date of the presence, or null if user doesn't set it.
* Expire date - a date when this presence are valid.
*
* @returns {Date|null}
*/
WTAPI.Presence.prototype.getStatusUntil = function() {
return this._until;
}
/**
* Returns true if user set expire date for presence.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isStatusUntilAvailable = function() {
return this._until !== null;
}
/**
* Returns call information in presence status of user, or null if there is no active call.
*
* @returns {WTAPI.ConnectedCall|null}
*/
WTAPI.Presence.prototype.getConnectedCall = function() {
return this._connectedCall;
}
/**
* Returns true if user talking on the phone.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isConnectedCallAvailable = function() {
return this._connectedCall instanceof WTAPI.ConnectedCall;
}
/**
* Returns location of user, or null if user doesn't set it.
*
* @returns {WTAPI.Location|null}
*/
WTAPI.Presence.prototype.getLocation = function() {
return this._location;
}
/**
* Returns profile data of user, or null if user doesn't set it.
*
* @returns {WTAPI.ProfileData|null}
*/
WTAPI.Presence.prototype.getProfileData = function() {
return this._profileData;
}
/**
* Returns true if user set his location.
*
* @returns {boolean}
*/
WTAPI.Presence.prototype.isLocationAvailable = function() {
return this._location instanceof WTAPI.Location;
}
/**
* Constructor for Presence builder.
*
* @example
* var untilDate = new Date((new Date()).getTime() + 1*60*60*1000); //current date +1 hour
* var builder = new WTAPI.Presence.Builder();
* builder.setAway();
* builder.setStatusMessage(message);
* builder.setStatusUntil(untilDate);
* var presence = builder.build();
* wtapi.presence.changePersonalPresence(presence, onChangePresenceCallback);
*
* @returns {WTAPI.Presence.Builder}
* @constructor
*/
WTAPI.Presence.Builder = function() {
// Set status
var presence = new WTAPI.Presence();
this._getPresence = function(){
return presence;
}
}
/**
* Set online (available) status.
*
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setOnline = function() {
this._getPresence()._online = true;
return this;
}
/**
* Set away status.
*
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setAway = function() {
this._getPresence()._show = WTAPI.Presence.AWAY;
return this;
}
/**
* Set dnd status.
*
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setDND = function() {
this._getPresence()._show = WTAPI.Presence.DND;
return this;
}
/**
* Set mur status.
*
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setMUR = function() {
this._getPresence()._show = WTAPI.Presence.MUR;
return this;
}
/**
* Set ringing status.
*
* @returns {WTAPI.Presence.Builder}
* @private
*/
WTAPI.Presence.Builder.prototype.setRinging = function() {
this._getPresence()._deviceShow = WTAPI.Presence.RINGING;
return this;
}
/**
* Set talking status.
*
* @returns {WTAPI.Presence.Builder}
* @private
*/
WTAPI.Presence.Builder.prototype.setTalking = function() {
this._getPresence()._deviceShow = WTAPI.Presence.TALKING;
return this;
}
/**
* Set ringing and talking status.
*
* @returns {WTAPI.Presence.Builder}
* @private
*/
WTAPI.Presence.Builder.prototype.setRingingAndTalking = function() {
this._getPresence()._deviceShow = WTAPI.Presence.RT;
return this;
}
/**
* Set registered device.
*
* @returns {WTAPI.Presence.Builder}
* @private
*/
WTAPI.Presence.Builder.prototype.setRegisteredDevice = function() {
this._getPresence()._deviceShow = WTAPI.Presence.REGISTERED;
return this;
}
/**
* Set message.
*
* @param message {string}
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setStatusMessage = function(message) {
this._getPresence()._status = message;
return this;
}
/**
* Set until.
*
* @param date {Date}
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setStatusUntil = function(date) {
this._getPresence()._until = date;
return this;
}
/**
* Set location.
*
* @param location {WTAPI.Location}
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setLocation = function(location) {
if (!(location instanceof WTAPI.Location)) {
throw new Error("Invalid location argument, it should be a WTAPI.Location instance");
}
this._getPresence()._location = location;
return this;
}
/**
* Set connected call information.
*
* @param call {WTAPI.ConnectedCall}
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setConnectedCall = function(call) {
if (!(call instanceof WTAPI.ConnectedCall)) {
throw new Error("Invalid call argument, it should be a WTAPI.ConnectedCall instance");
}
this._getPresence()._connectedCall = call;
return this;
}
/**
* Set profile data.
*
* @param profileData {WTAPI.ProfileData}
* @returns {WTAPI.Presence.Builder}
*/
WTAPI.Presence.Builder.prototype.setProfileData = function(profileData) {
if (!(profileData instanceof WTAPI.ProfileData)) {
throw new Error("Invalid profile data argument, it should be a WTAPI.ProfileData instance");
}
this._getPresence()._profileData = profileData;
return this;
}
/**
* Build the presence object.
*
* @returns {WTAPI.Presence}
*/
WTAPI.Presence.Builder.prototype.build = function() {
return this._getPresence();
}
/**
* Represents a chat message.
* Use WTAPI.Message.Builder to create a new message.
*
* @memberof WTAPI
* @alias WTAPI.Message
* @public
* @constructor
*/
WTAPI.Message = function() {
this._id = "";
this._body = "";
}
/**
* Returns id of the message, or empty string if id has not been set.
*
* @returns {string}
*/
WTAPI.Message.prototype.getId = function() {
return this._id;
}
/**
* Returns body of the message.
*
* @returns {string}
*/
WTAPI.Message.prototype.getBody = function() {
return this._body;
}
/**
*
* @memberof WTAPI.Message
* @alias WTAPI.Message.Builder
* @public
* @constructor
*/
WTAPI.Message.Builder = function() {
var message = new WTAPI.Message();
return {
withId: function(id) {
message._id = id;
return this;
},
withAutoGeneratedId: function() {
message._id = this._rand() + this._rand() + '-' + this._rand() + '-' + this._rand() +
'-' + this._rand() + '-' + this._rand() + this._rand() + this._rand();
return this;
},
withBody: function(body) {
message._body = body;
return this;
},
build: function() {
return message;
},
_rand: function() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
}
}
export default WTAPI;