\n";
graphicDiv.innerHTML = html;
var img = document.createElement('img');
img.setAttribute('src', urlprefix + result.avatar);
div.appendChild(graphicDiv);
}
});
}
}
GraphicsUploader.map = {};
GraphicsUploader.tags = [];
GraphicsUploader.categories = [];
/**
* Open a media uploader dialog initialized with a form.
* The dialog will use the form's action to upload media as 'file' for a file, or 'upload-url' for a URL.
* The form should define an ID if to be used on multiple forms in the same document.
* This can be used on the onclick on an input element to open the dialog i.e.
* This will create a hidden input of type file ('file'), and a hidden input of type text ('upload-url'), these will be passed to your server when the dialog submits the form.
*/
GraphicsUploader.openUploadDialog = function(form, title, showFile, showURL, showBrowse) {
var id = form.getAttribute('id');
var prefix = "uploader-";
var dialogId = "graphics-uploader";
var browserId = "graphics-browser";
if (id == null) {
id = "uploader";
} else {
prefix = id + '-' + prefix;
dialogId = id + '-' + dialogId;
browserId = id + '-' + browserId;
}
var uploader = GraphicsUploader.map[id];
if (uploader == null) {
uploader = new GraphicsUploader();
GraphicsUploader.map[id] = uploader;
var div = document.createElement('div');
var html =
"\n"
+ "";
div.innerHTML = html;
form.appendChild(div);
if (title != null) {
uploader.dialogTitle = title;
}
if (showFile != null) {
uploader.showFile = showFile;
}
if (showURL != null) {
uploader.showURL = showURL;
}
if (showBrowse != null) {
uploader.showBrowse = showBrowse;
}
uploader.prefix = prefix;
uploader.dialogId = dialogId;
uploader.id= browserId;
uploader.fileInput = document.getElementById(id + 'file-input');
uploader.urlInput = document.getElementById(id + 'url-input');
uploader.uploadURL = form.action;
}
uploader.openUploadDialog();
return false;
}
/**
* Credentials used to establish a connection.
* Defines the url, host, app, rest, which are all defaulted and should not need to be changed,
* Requires an application id.
* You can obtain your application id from your user details page on the hosting website.
* @class
*/
function Credentials() {
this.host = SDK.host;
this.app = SDK.app;
this.url = SDK.url;
this.rest = SDK.rest;
this.applicationId = SDK.applicationId;
}
/**
* Credentials for use with hosted services on the BOT libre website, a free bot hosting service.
* http://www.botlibre.com
* @class
*/
function BOTlibreCredentials() {
this.DOMAIN = "www.botlibre.com";
this.APP = "";
this.PATH = "/rest/botlibre";
this.host = this.DOMAIN;
this.app = this.APP;
this.url = "http://" + this.DOMAIN + this.APP;
this.rest = this.url + this.PATH;
this.applicationId = SDK.applicationId;
}
/**
* Credentials for use with hosted services on the Paphus Live Chat website,
* a commercial live chat, chatroom, forum, and chat bot, hosting service.
* http://www.paphuslivechat.com
* @class
*/
function PaphusCredentials() {
this.DOMAIN = "www.paphuslivechat.com";
this.APP = "";
this.PATH = "/rest/livechat";
this.host = this.DOMAIN;
this.app = this.APP;
this.url = "http://" + this.DOMAIN + this.APP;
this.rest = this.url + this.PATH;
this.applicationId = SDK.applicationId;
}
/**
* Credentials for use with hosted services on the LIVE CHAT libre website, a free live chat, chatrooms, forum, and chat bots that learn.
* http://www.livechatlibre.com
* @class
*/
function LIVECHATlibreCredentials() {
this.DOMAIN = "www.livechatlibre.com";
this.APP = "";
this.PATH = "/rest/livechatlibre";
this.host = this.DOMAIN;
this.app = this.APP;
this.url = "http://" + this.DOMAIN + this.APP;
this.rest = this.url + this.PATH;
this.applicationId = SDK.applicationId;
}
/**
* Credentials for use with hosted services on the FORUMS libre website, a free embeddable forum hosting service.
* http://www.forumslibre.com
* @class
*/
function FORUMSlibreCredentials() {
this.DOMAIN = "www.forumslibre.com";
this.APP = "";
this.PATH = "/rest/forumslibre";
this.host = this.DOMAIN;
this.app = this.APP;
this.url = "http://" + this.DOMAIN + this.APP;
this.rest = this.url + this.PATH;
this.applicationId = SDK.applicationId;
}
/**
* Listener interface for a LiveChatConnection.
* This gives asynchronous notification when a channel receives a message, or notice.
* @class
*/
function LiveChatListener() {
/**
* A user message was received from the channel.
*/
this.message = function(message) {};
/**
* An informational message was received from the channel.
* Such as a new user joined, private request, etc.
*/
this.info = function(message) {};
/**
* An error message was received from the channel.
* This could be an access error, or message failure.
*/
this.error = function(message) {};
/**
* Notification that the connection was closed.
*/
this.closed = function() {};
/**
* The channels users changed (user joined, left, etc.)
* This contains a comma separated values (CSV) list of the current channel users.
* It can be passed to the SDKConnection.getUsers() API to obtain the UserConfig info for the users.
*/
this.updateUsers = function(usersCSV) {};
/**
* The channels users changed (user joined, left, etc.)
* This contains a HTML list of the current channel users.
* It can be inserted into an HTML document to display the users.
*/
this.updateUsersXML = function(usersXML) {};
}
/**
* The WebLiveChatListener provides an integration between a LiveChatConnection and an HTML document.
* It updates the document to message received from the connection, and sends messages from the document's form.
* The HTML document requires the following elements:
* - chat - chat text input for sending messages
* - send - button for sending chat input
* - response -
paragraph for last chat message
* - console -
table for chat log, and user log
* - scroller -
div for chat log scroll pane
* - online -
table for chat user list
* @class
*/
function WebLiveChatListener() {
/** Set the caption for the button bar button. */
this.caption = null;
this.switchText = true;
this.playChime = true;
this.speak = false;
this.voice = null;
this.nativeVoice = null;
this.nativeVoiceName = null;
this.lang = null;
this.nick = "";
this.connection = null;
this.sdk = null;
/** Configure if chat should be given focus after message. */
this.focus = true;
/** Element id and class prefix. Can be used to have multiple avatars in the same page, or avoid naming collisions. */
this.prefix = "";
/** Allow the chat box button color to be set. */
this.color = "#009900";
/** Allow the chat box hover button color to be set. */
this.hoverColor = "grey";
/** Allow the chat box background color to be set. */
this.background = null;
/** Chat box width. */
this.width = 300;
/** Chat box height. */
this.height = 320;
/** Chat box offest from side. */
this.offset = 30;
/** Print response in chat bubble. */
this.bubble = false;
/** Set the location of the button and box, one of "bottom-right", "bottom-left", "top-right", "top-left". */
this.boxLocation = "bottom-right";
/** Set styles explictly to avoid inheriting page styles. Disable this to be able to override styles. */
this.forceStyles = true;
/** Override the URL used in the chat box popup. */
this.popupURL = null;
/** Set if the box chat log should be shown. */
this.chatLog = true;
/** Box chat loading message to display. */
this.loading = "loading...";
/** Box chat chatroom option. */
this.chatroom = false;
/** Box chat show online users option. */
this.online = false;
/** Link to online user list users to their profile page. */
this.linkUsers = true;
/** Configure message log format (table or log). */
this.chatLogType = "log";
/** Prompt for name/email before connecting. */
this.promptContactInfo = false;
this.hasContactInfo = false;
this.contactName = null;
this.contactEmail = null;
this.contactPhone = null;
this.contactInfo = "";
this.windowTitle = document.title;
this.isActive = true;
self = this;
/**
* Create an embedding bar and div in the current webpage.
*/
this.createBox = function() {
if (this.prefix == "" && this.elementPrefix != null) {
this.prefix = this.elementPrefix;
}
if (this.caption == null) {
this.caption = this.instanceName;
}
var backgroundstyle = "";
var buttonstyle = "";
var buttonHoverStyle = "";
var hidden = "hidden";
var border = "";
if (this.backgroundIfNotChrome && SDK.isChrome()) {
this.background = null;
}
if (this.background != null) {
backgroundstyle = " style='background-color:" + this.background + "'";
hidden = "visible";
border = "border:1px;border-style:solid;border-color:black;";
}
if (this.color != null) {
buttonstyle = "background-color:" + this.color + ";";
}
if (this.hoverColor != null) {
buttonHoverStyle = "background-color:" + this.hoverColor + ";";
}
var minWidth = "";
var divWidth = "";
var background = "";
var minHeight = "";
var divHeight = "";
if (this.width != null) {
minWidth = "width:" + this.width + "px;";
background = "background-size:" + this.width + "px auto;";
divWidth = minWidth;
divHeight = "min-height:" + this.width + "px;";
responseWidth = "width:" + (this.width - 16) + "px;";
}
if (this.height != null) {
minHeight = "height:" + this.height + "px;";
divHeight = minHeight;
if (this.width != null) {
background = "background-size:" + this.width + "px " + this.height + "px;";
} else {
background = "background-size: auto " + this.height + "px;";
divWidth = "min-width:" + this.height + "px;";
}
}
var boxloc = "bottom:10px;right:10px";
if (this.boxLocation == "top-left") {
boxloc = "top:10px;left:10px";
} else if (this.boxLocation == "top-right") {
boxloc = "top:10px;right:10px";
} else if (this.boxLocation == "bottom-left") {
boxloc = "bottom:10px;left:10px";
} else if (this.boxLocation == "bottom-right") {
boxloc = "bottom:10px;right:10px";
}
var boxbarloc = "bottom:2px;right:" + this.offset + "px";
if (this.boxLocation == "top-left") {
boxbarloc = "top:2px;left:" + this.offset + "px";
} else if (this.boxLocation == "top-right") {
boxbarloc = "top:2px;right:" + this.offset + "px";
} else if (this.boxLocation == "bottom-left") {
boxbarloc = "bottom:2px;left:" + this.offset + "px";
} else if (this.boxLocation == "bottom-right") {
boxbarloc = "bottom:2px;right:" + this.offset + "px";
}
var box = document.createElement('div');
var html =
"\n"
+ "
"
+ "
"
+ " "
+ "
";
if (this.online) {
html = html
+ "
"
+ "
"
+ "
"
+ "
"
+ "
";
}
if (this.chatLog) {
html = html
+ "
"
+ "
"
+ "
"
}
var urlprefix = this.sdk.credentials.url + "/";
html = html
+ "
";
box.innerHTML = html;
document.body.appendChild(box);
document.getElementById(this.prefix + "livechatboxmax").addEventListener("click", function() {
SDK.popupwindow(SDK.url + '/livechat?id=' + channel + '&embedded&chat','child', 700, 520);
return false;
});
}
/**
* Minimize the embedding div in the current webpage.
*/
this.minimizeBox = function() {
if (this.promptContactInfo) {
document.getElementById(this.prefix + "contactinfo").style.display = 'none';
}
document.getElementById(this.prefix + "box").style.display = 'none';
document.getElementById(this.prefix + "boxbar").style.display = 'inline';
var livechatbot = document.getElementById(this.prefix + "livechatboxbar");
if (livechatbot != null) {
livechatbot.style.display = 'inline';
}
this.exit();
return false;
}
/**
* Check contact info and connect.
*/
this.contactConnect = function() {
this.hasContactInfo = true;
this.contactName = document.getElementById(this.prefix + "contactname").value;
var ok = true;
if (this.contactName != null && this.contactName == "") {
ok = false;
document.getElementById(this.prefix + "contactname").style.borderColor = "red";
document.getElementById(this.prefix + "contactname").placeholder = "Enter name";
}
this.contactEmail = document.getElementById(this.prefix + "contactemail").value;
if (this.contactEmail != null && this.contactEmail.indexOf("@") == -1) {
ok = false;
document.getElementById(this.prefix + "contactemail").style.borderColor = "red";
document.getElementById(this.prefix + "contactemail").placeholder = "Enter valid email";
}
this.contactPhone = document.getElementById(this.prefix + "contactphone").value;
this.contactInfo = this.contactName + " " + this.contactEmail + " " + this.contactPhone;
if (ok) {
this.maximizeBox();
}
}
/**
* Maximize the embedding div in the current webpage.
*/
this.maximizeBox = function() {
if (this.promptContactInfo && !this.hasContactInfo) {
document.getElementById(this.prefix + "contactinfo").style.display = 'inline';
document.getElementById(this.prefix + "boxbar").style.display = 'none';
document.getElementById(this.prefix + "box").style.display = 'none';
var livechatbot = document.getElementById(this.prefix + "livechatboxbar");
if (livechatbot != null) {
livechatbot.style.display = 'none';
}
} else {
if (this.promptContactInfo) {
document.getElementById(this.prefix + "contactinfo").style.display = 'none';
}
document.getElementById(this.prefix + "boxbar").style.display = 'none';
document.getElementById(this.prefix + "box").style.display = 'inline';
var livechatbot = document.getElementById(this.prefix + "livechatboxbar");
if (livechatbot != null) {
livechatbot.style.display = 'none';
}
this.greet();
}
return false;
}
/**
* Close the embedding div in the current webpage.
*/
this.closeBox = function() {
if (this.promptContactInfo) {
document.getElementById(this.prefix + "contactinfo").style.display = 'none';
}
document.getElementById(this.prefix + "boxbar").style.display = 'none';
document.getElementById(this.prefix + "box").style.display = 'none';
var livechatbot = document.getElementById(this.prefix + "livechatboxbar");
if (livechatbot != null) {
livechatbot.style.display = 'none';
}
this.exit();
return false;
}
/**
* Create a popup window chat session with the bot.
*/
this.popup = function() {
var box = document.getElementById(this.prefix + "box");
if (box != null) {
box.style.display = 'none';
}
var speech = this.speak;
if (!this.allowSpeech) {
speech = "disable";
}
var height = 520;
if (!this.avatar) {
height = 220;
}
if (this.popupURL != null) {
var popupURL = this.popupURL;
if (popupURL.indexOf("chat?") != -1 && this.contactInfo != null && this.contactInfo != "") {
popupURL = popupURL + "&info=" + encodeURI(this.contactInfo);
}
SDK.popupwindow(popupURL, 'child', 700, height);
} else {
var form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", SDK.url + "/chat");
form.setAttribute("target", 'child');
var input = document.createElement('input');
input.type = 'hidden';
input.name = "id";
input.value = this.instance;
form.appendChild(input);
input = document.createElement('input');
input.type = 'hidden';
input.name = "embedded";
input.value = "embedded";
form.appendChild(input);
input = document.createElement('input');
input.type = 'hidden';
input.name = "speak";
input.value = speech;
form.appendChild(input);
input = document.createElement('input');
input.type = 'hidden';
input.name = "avatar";
input.value = this.avatar;
form.appendChild(input);
input = document.createElement('input');
input.type = 'hidden';
input.name = "info";
input.value = this.contactInfo;
form.appendChild(input);
input = document.createElement('input');
input.type = 'hidden';
input.name = "application";
input.value = this.connection.credentials.applicationId;
form.appendChild(input);
document.body.appendChild(form);
SDK.popupwindow('','child', 700, height);
form.submit();
document.body.removeChild(form);
}
this.minimizeBox();
return false;
}
/**
* A chat message was received from the bot.
*/
this.response = function(user, message) {
document.getElementById(this.prefix + 'response').innerHTML = SDK.linkURLs(message);
this.message(user, message);
if (this.focus) {
document.getElementById(this.prefix + 'chat').focus();
}
if (this.onresponse != null) {
this.onresponse(message);
}
}
/**
* A chat message was received from the bot.
*/
this.message = function(user, message) {
var speaker = user;
var scroller = document.getElementById(this.prefix + 'scroller');
var chatconsole = document.getElementById(this.prefix + 'console');
if (scroller == null || chatconsole == null) {
return;
}
var tr = document.createElement('tr');
var td = document.createElement('td');
var td2 = document.createElement('td');
var span2 = document.createElement('span');
var chatClass = 'chat-1';
if (this.switchText) {
chatClass = 'chat-2';
}
if (this.botThumb == null || this.userThumb == null) {
var span = document.createElement('span');
span.className = chatClass;
span.innerHTML = speaker;
td.appendChild(span);
} else {
var img = document.createElement('img');
img.className = 'chat-user';
img.setAttribute('alt', speaker);
if (user == this.userName) {
img.setAttribute('src', this.userThumb);
} else {
img.setAttribute('src', this.botThumb);
}
td.appendChild(img);
}
span2.className = chatClass;
span2.innerHTML = SDK.linkURLs(message);
td.className = 'chat-user';
td.setAttribute('nowrap', 'nowrap');
td2.className = chatClass;
td2.setAttribute('align', 'left');
td2.setAttribute('width', '100%');
chatconsole.appendChild(tr);
tr.appendChild(td);
tr.appendChild(td2);
td2.appendChild(span2);
this.switchText = !this.switchText;
while (chatconsole.childNodes.length > 500) {
chatconsole.removeChild(chatconsole.firstChild);
}
scroller.scrollTop = scroller.scrollHeight;
};
/**
* Update the bot's avatar's image/video/audio from the chat response.
*/
this.updateAvatar = function(responseMessage) {
var urlprefix = this.connection.credentials.url + "/";
SDK.updateAvatar(responseMessage, this.speak, urlprefix, this.prefix, null, null, this.nativeVoice, this.lang, this.nativeVoiceName);
};
this.toggleSpeak = function() {
this.speak = !this.speak;
}
/**
* Initialize the bot listener.
*/
this.start = function() {
if (this.prefix == "" && this.elementPrefix != null) {
this.prefix = this.elementPrefix;
}
var self = this;
this.connection.error = function(message) {
self.response("Error", message);
}
if (this.avatar) {
var config = new ChatConfig();
config.instance = this.instance;
if (this.translate) {
config.language = this.lang;
}
if (this.format != null) {
config.avatarFormat = this.format;
}
if (this.hd != null) {
config.avatarHD = this.hd;
}
this.connection.initChat(config, function(responseMessage) {
if (this.conversation == null) {
self.updateAvatar(responseMessage);
}
});
}
}
/**
* Send the bot an empty message to let it greet the user.
* This will have the bot respond with any defined greeting it has.
*/
this.greet = function() {
this.start();
var chat = new ChatConfig();
chat.info = this.contactInfo;
chat.instance = this.instance;
if (this.translate) {
chat.language = this.lang;
}
if (this.avatarId != null) {
chat.avatar = this.avatarId;
}
if (this.hd != null) {
chat.avatarHD = this.hd;
} else if ((this.width != null && this.width > 400) || (this.height != null && this.height > 400)) {
chat.avatarHD = true;
}
if (this.format != null) {
chat.avatarFormat = this.format;
}
if (this.nativeVoice && SDK.speechSynthesis) {
chat.speak = false;
} else {
chat.speak = this.speak;
}
var self = this;
if (this.external) {
this.externalChat(chat);
} else {
this.connection.chat(chat, function(responseMessage) {
self.conversation = responseMessage.conversation;
self.updateAvatar(responseMessage);
if (responseMessage.message != null && responseMessage.message != "") {
self.response(self.instanceName, responseMessage.message);
} else if (self.greeting == null) {
document.getElementById(self.prefix + 'response').innerHTML = "Hi";
}
});
}
return false;
};
/**
* Send the current text from the chat input as a message to the bot, and process the response.
*/
this.sendMessage = function() {
var message = document.getElementById(this.prefix + 'chat').value;
if (message != '') {
this.message(this.userName, message);
var chat = new ChatConfig();
chat.message = message;
chat.instance = this.instance;
if (this.translate) {
chat.language = this.lang;
}
if (this.avatarId != null) {
chat.avatar = this.avatarId;
}
if (this.hd != null) {
chat.avatarHD = this.hd;
} else if ((this.width != null && this.width > 400) || (this.height != null && this.height > 400)) {
chat.avatarHD = true;
}
if (this.format != null) {
chat.avatarFormat = this.format;
}
if (this.nativeVoice && SDK.speechSynthesis) {
chat.speak = false;
} else {
chat.speak = this.speak;
}
chat.conversation = this.conversation;
var correction = document.getElementById(this.prefix + 'correction');
if (correction != null && correction.checked) {
chat.correction = true;
correction.checked = false;
}
var learning = document.getElementById(this.prefix + 'learning');
if (learning != null && learning.style.display != "none") {
chat.learn = learning.checked;
}
var debug = document.getElementById(this.prefix + 'debug');
if (debug != null && debug.checked) {
chat.debug = true;
var debugLevel = document.getElementById(this.prefix + 'debugLevel');
if (debugLevel != null) {
chat.debugLevel = debugLevel.value;
}
}
var offensive = document.getElementById(this.prefix + 'offensive');
if (offensive != null && offensive.checked) {
chat.offensive = true;
offensive.checked = false;
}
var emote = document.getElementById(this.prefix + 'emote');
if (emote != null && emote.value != null && emote.value != "" && emote.value != "NONE") {
chat.emote = emote.value.toUpperCase();
emote.value = "NONE";
}
var action = document.getElementById(this.prefix + 'action');
if (action != null && action.value != null && action.value != "") {
chat.action = action.value;
action.value = "";
}
var self = this;
document.getElementById(this.prefix + 'response').innerHTML = 'thinking';
document.getElementById(this.prefix + 'chat').value = '';
if (this.external) {
this.externalChat(chat);
} else {
this.connection.chat(chat, function(responseMessage) {
self.conversation = responseMessage.conversation;
self.response(self.instanceName, responseMessage.message);
self.updateAvatar(responseMessage);
var log = document.getElementById(self.prefix + 'log');
var logText = responseMessage.log;
if (log != null) {
if (logText != null) {
log.style.display = "inline";
log.innerHTML = logText;
} else {
log.innerHTML = "";
}
}
});
}
}
return false;
};
/**
* Send an external API chat request.
*/
this.externalChat = function(chat) {
var url = this.apiURL;
if (chat.message == null) {
url = url.replace(":message", "");
} else {
url = url.replace(":message", encodeURIComponent(chat.message));
}
if (chat.conversation == null) {
url = url.replace(":conversation", "");
} else {
url = url.replace(":conversation", encodeURIComponent(chat.conversation));
}
if (chat.speak) {
url = url.replace(":speak", "true");
} else {
url = url.replace(":speak", "");
}
var self = this;
this.connection.GET(url, function(xml) {
if (xml == null) {
return null;
}
var responseMessage = new ChatResponse();
responseMessage.parseXML(xml);
self.conversation = responseMessage.conversation;
self.response(self.instanceName, responseMessage.message);
var urlprefix = self.apiURL.substring(0, self.apiURL.indexOf("/rest/api/form-chat")) + "/";
SDK.updateAvatar(responseMessage, self.speak, urlprefix, self.prefix, null, null, self.nativeVoice, self.lang, self.nativeVoiceName);
var log = document.getElementById(self.prefix + 'log');
var logText = responseMessage.log;
if (log != null) {
if (logText != null) {
log.innerHTML = logText;
} else {
log.innerHTML = "";
}
}
});
}
/**
* Exit the conversation.
*/
this.exit = function() {
if (this.conversation == null || this.external) {
return false;
}
var chat = new ChatConfig();
chat.disconnect = true;
chat.instance = this.instance;
chat.conversation = this.conversation;
var self = this;
this.connection.chat(chat, function(responseMessage) {
self.conversation = null;
});
return false;
};
/**
* Clear the chat console.
*/
this.clear = function() {
document.getElementById(this.prefix + 'response').innerHTML = '';
var console = document.getElementById(this.prefix + 'console');
if (console != null) {
console.innerHTML = '';
}
return false;
};
this.resizeAvatar = function () {
var avatar = document.getElementById(this.prefix + "avatar");
var avatarDiv = document.getElementById(this.prefix + "avatar-image-div");
var avatarVideo = document.getElementById(this.prefix + "avatar-video");
var avatarVideoDiv = document.getElementById(this.prefix + "avatar-video-div");
var avatarCanvas = document.getElementById(this.prefix + "avatar-canvas");
var avatarCanvasDiv = document.getElementById(this.prefix + "avatar-canvas-div");
var scroller = document.getElementById(this.prefix + "scroller");
if (!this.big) {
this.hd = true;
if (avatar != null) {
avatar.className = "avatar-big";
}
if (avatarVideo != null) {
avatarVideo.className = "avatar-video-big";
}
if (avatarVideoDiv != null) {
avatarVideoDiv.className = "avatar-video-div-big";
}
if (avatarCanvas != null) {
avatarCanvas.className = "avatar-canvas-big";
}
if (avatarCanvasDiv != null) {
avatarCanvasDiv.className = "avatar-canvas-div-big";
}
if (scroller != null) {
scroller.style.display = "none";
}
this.big = true;
} else {
this.hd = false;
if (avatar != null) {
avatar.className = "avatar";
}
if (avatarVideo != null) {
avatarVideo.className = "avatar-video";
}
if (avatarVideoDiv != null) {
avatarVideoDiv.className = "avatar-video-div";
}
if (avatarCanvas != null) {
avatarCanvas.className = "avatar-canvas";
}
if (avatarCanvasDiv != null) {
avatarCanvasDiv.className = "avatar-canvas-div";
}
if (scroller != null) {
scroller.style.display = "inline-block";
}
this.big = false;
}
if (window.onresize != null) {
setTimeout(window.onresize(), 100);
}
return false;
}
}
/**
* The WebAvatar provides access to an avatar and binds it to elements in an HTML document.
* It lets you use a bot avatar without having a bot. You can tell the avatar what to say, and what actions and poses to display.
* The HTML document requires the following elements:
*
*
avatar - img element for the avatar
*
avatar-image-div - div element for the avatar's image
*
avatar-video - video element for the avatar's video
*
avatar-video-div - div element for the avatar's video
*
* If a prefix is set, these id will be prefixed by the prefix.
* Or you can call createBox() to have the WebAvatar create its own components in the current page.
* @class
*/
function WebAvatar() {
/** Enable or disable speech. */
this.speak = true;
/** Configure if the browser's native voice TTS should be used. */
this.nativeVoice = false;
/** Set the language for the native voice. */
this.lang = null;
/** Set the voice for the native voice. */
this.nativeVoiceName = null;
/** An SDK connection object must be set. */
this.connection = null;
/** The id or name of the avatar object to use. */
this.avatar = null;
/** The name of the voice to use. */
this.voice = null;
/** Allow the background color to be set. */
this.background = null;
/** Avatar image/video width. */
this.width = 300;
/** Avatar image/video height. */
this.height = null;
/** Only apply the background color if not Chrome. */
this.backgroundIfNotChrome = false;
/** An optional close event. */
this.onclose = null;
/** Return if the avatar box is in a closed state. */
this.closed = true;
/** Element id and class prefix. Can be used to have multiple avatars in the same page, or avoid naming collisions. */
this.prefix = "avatar-";
/** Store list of messages to output. */
this.messages = null;
/** Function to invoke when processing all messages is complete. */
this.ended = null;
/** Set if the avatar should request HD (high def) video/images. */
this.hd = null;
/** Set if the avatar should request a specific video or image format. */
this.format = null;
/**
* Create an embedding bar and div in the current webpage.
*/
this.createBox = function() {
if (this.prefix == "" && this.elementPrefix != null) {
this.prefix = this.elementPrefix;
}
var backgroundstyle = "";
var hidden = "hidden";
var border = "";
if ((this.background != null) && (!this.backgroundIfNotChrome || !SDK.isChrome())) {
backgroundstyle = " style='background-color:" + this.background + "'";
hidden = "visible";
border = "border:1px;border-style:solid;border-color:black;";
}
var box = document.createElement('div');
var minWidth = "";
var minHeight = "";
var divWidth = "";
var divHeight = "";
var background = "";
if (this.width != null) {
minWidth = "width:" + this.width + "px;";
background = "background-size:" + this.width + "px;";
divWidth = minWidth;
divHeight = "min-height:" + this.width + "px;";
}
if (this.height != null) {
minHeight = "height:" + this.height + "px;";
divHeight = minHeight;
if (this.width != null) {
background = "background-size:" + this.width + "px " + this.height + "px;";
} else {
background = "background-size: auto " + this.height + "px;";
divWidth = "min-width:" + this.height + "px;";
}
}
var html =
"\n"
+ "
"
+ "
"
+ " "
+ "
"
+ "
"
+ ""
+ "
"
+ "
"
+ ""
+ "
"
+ "
"
+ ""
+ "
"
+ "
";
box.innerHTML = html;
document.body.appendChild(box);
var self = this;
document.getElementById(this.prefix + "avatarboxclose").addEventListener("click", function() {
self.closeBox();
return false;
});
this.closed = false;
}
/**
* Open the embedding div in the current webpage.
*/
this.openBox = function() {
document.getElementById(this.prefix + "avatarbox").style.display = 'inline';
this.speak = true;
this.closed = false;
return false;
}
/**
* Close the embedding div in the current webpage.
*/
this.closeBox = function() {
document.getElementById(this.prefix + "avatarbox").style.display = 'none';
this.speak = false;
if (this.onclose != null) {
this.onclose();
}
this.closed = true;
return false;
}
/**
* Update the avatar's image/video/audio from the message response.
*/
this.updateAvatar = function(responseMessage, afterFunction) {
var urlprefix = this.connection.credentials.url + "/";
SDK.updateAvatar(responseMessage, this.speak, urlprefix, this.prefix, false, afterFunction, this.nativeVoice, this.lang, this.nativeVoiceName);
};
/**
* Add the message to the avatars message queue.
* The messages will be spoken when processMessages() is called.
*/
this.addMessage = function(message, emote, action, pose) {
var config = new AvatarMessage();
config.message = message;
config.avatar = this.avatar;
if (this.hd != null) {
config.hd = this.hd;
} else if ((this.width != null && this.width > 400) || (this.height != null && this.height > 400)) {
config.hd = true;
}
if (this.format != null) {
config.format = this.format;
}
if (this.nativeVoice && SDK.speechSynthesis) {
config.speak = false;
} else {
config.speak = this.speak;
config.voice = this.voice;
}
config.emote = emote;
config.action = action;
config.pose = pose;
if (this.messages == null) {
this.messages = [];
}
this.messages[this.messages.length] = config;
return false;
};
/**
* Add the message to the avatars message queue.
* The messages will be spoken when runMessages() is called.
*/
this.processMessages = function(pause) {
if (this.messages == null || this.messages.length == 0) {
if (this.ended != null) {
this.ended();
}
return false;
}
if (pause == null) {
pause = 500;
}
var self = this;
var message = this.messages[0];
this.messages = this.messages.splice(1, this.messages.length);
this.connection.avatarMessage(message, function(responseMessage) {
self.updateAvatar(responseMessage, function() {
setTimeout(function() {
self.processMessages(pause);
}, pause);
});
});
return false;
}
/**
* Have the avatar speak the message with voice and animation.
* The function will be called at the end of the speech.
*/
this.message = function(message, emote, action, pose, afterFunction) {
var config = new AvatarMessage();
config.message = message;
config.avatar = this.avatar;
if (this.nativeVoice && SDK.speechSynthesis) {
config.speak = false;
} else {
config.speak = this.speak;
config.voice = this.voice;
}
config.emote = emote;
config.action = action;
config.pose = pose;
var self = this;
this.connection.avatarMessage(config, function(responseMessage) {
self.updateAvatar(responseMessage, afterFunction);
});
return false;
};
}
/**
* Connection class for a Live Chat, or chatroom connection.
* A live chat connection is different than an SDKConnection as it is asynchronous,
* and uses web sockets for communication.
* @class
* @property channel
* @property user
* @property credentials
* @property listener
* @property keepAlive
* @property onMediaStream
* @property onMediaStreamEnded
* @property nick
* @property channelToken
* @property onNewChannel
* @property nick
*/
function LiveChatConnection() {
this.channel = null;
this.user = null;
this.contactInfo = null;
this.credentials = new Credentials();
this.socket = null;
this.listener = null;
this.keepAlive = false;
this.keepAliveInterval = null;
this.mediaConnection = null;
this.onMediaStream = null;
this.onMediaStreamEnded = null;
this.nick = null;
this.channelToken = null;
this.onNewChannel = null;
this.onMessageCallbacks = {};
/**
* Connect to the live chat server channel.
* Validate the user credentials.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
*/
this.connect = function(channel, user) {
if (this.credentials == null) {
throw "Mising credentials";
}
this.channel = channel;
this.user = user;
if (this.nick == null && this.user != null) {
this.nick = this.user.user;
}
var host = null;
if (SDK.scheme == "https") {
host = "wss://" + this.credentials.host + this.credentials.app + "/live/chat";
} else {
host = "ws://" + this.credentials.host + this.credentials.app + "/live/chat";
}
if ('WebSocket' in window) {
this.socket = new WebSocket(host);
} else if ('MozWebSocket' in window) {
this.socket = new MozWebSocket(host);
} else {
throw 'Error: WebSocket is not supported by this browser.';
}
this.listener.connection = this;
var self = this;
this.socket.onopen = function () {
if (self.channel != null) {
var appId = self.credentials.applicationId;
if (appId == null) {
appId = '';
}
var connectString = "connect " + self.channel.id;
if (self.user == null) {
connectString = connectString + " " + appId;
} else if (user.token == null) {
connectString = connectString + " " + self.user.user + " " + self.user.password + " " + appId;
} else {
connectString = connectString + " " + self.user.user + " " + self.user.token + " " + appId;
}
if (self.contactInfo != null) {
connectString = connectString + " @info " + self.contactInfo;
}
self.socket.send(connectString);
}
self.setKeepAlive(this.keepAlive);
};
this.socket.onclose = function () {
self.listener.message("Info: Closed");
self.listener.closed();
self.disconnectMedia();
};
this.socket.onmessage = function (message) {
user = "";
data = message.data;
text = data;
index = text.indexOf(':');
if (index != -1) {
user = text.substring(0, index);
data = text.substring(index + 2, text.length);
}
if (user == "Media") {
data = JSON.parse(data);
if (data.sender == self.nick) {
return;
}
if (data.channel != self.channelToken) {
return;
}
if (self.onMessageCallbacks[data.channel]) {
self.onMessageCallbacks[data.channel](data.message);
};
return;
}
if (user == "Online-xml") {
self.listener.updateUsersXML(data);
return;
}
if (user == "Online") {
self.listener.updateUsers(data);
return;
}
if (user == "Channel") {
self.channelToken = data;
if (self.onNewChannel != null) {
self.onNewChannel(data);
}
return;
}
if (user == "Nick") {
if (self.nick == null) {
self.nick = data;
}
return;
}
if (self.keepAlive && user == "Info" && text.contains("pong")) {
return;
}
if (user == "Info") {
self.listener.info(text);
return;
}
if (user == "Error") {
self.listener.error(text);
return;
}
self.listener.message(text);
};
};
/**
* Connect to the active channels media feed (video, audio).
*/
this.connectMedia = function(mediaChannel, shareAudio, shareVideo) {
if (this.mediaConnection != null) {
this.mediaConnection.leave();
}
this.mediaConnection = new RTCMultiConnection(mediaChannel);
var self = this;
var open = false;
this.mediaConnection.session = {
audio: shareAudio,
video: shareVideo
};
/*this.mediaConnection.mediaConstraints.audio = {
mandatory: {},
optional: [{
googEchoCancellation: true,
googAutoGainControl: true,
googNoiseSuppression: true,
googHighpassFilter: true,
googTypingNoiseDetection: true,
googAudioMirroring: true
}]
};*/
/*this.mediaConnection.privileges = {
canStopRemoteStream: true,
canMuteRemoteStream: true
};*/
this.mediaConnection.openSignalingChannel = function (config) {
var channel = config.channel || this.channel;
self.onMessageCallbacks[channel] = config.onmessage;
if (config.onopen) {
setTimeout(config.onopen, 1000);
}
// directly returning socket object using "return" statement
return {
send: function (message) {
self.socket.send("Media: " + JSON.stringify({
sender: self.nick,
channel: channel,
message: message
}));
},
channel: channel
};
};
this.mediaConnection.onstream = function(stream) {
open = true;
if (self.onMediaStream != null) {
self.onMediaStream(stream);
}
};
this.mediaConnection.onstreamended = function(stream) {
if (self.onMediaStreamEnded != null) {
self.onMediaStreamEnded(stream);
}
};
this.mediaConnection.onNewSession = function(session) {
session.join({
audio: shareAudio,
video: shareVideo
});
};
if (this.nick != null) {
this.mediaConnection.userid = this.nick;
}
//connection.log = false;
this.mediaConnection.onerror = function(error) {
SDK.error(error);
}
this.mediaConnection.onMediaError = function(error) {
SDK.error(error);
}
this.mediaConnection.connect();
setTimeout(function() {
if (!open) {
self.mediaConnection.open("room");
}
}, 5000);
}
/**
* Disconnect from the active channels media feed (video, audio).
*/
this.disconnectMedia = function() {
if (this.mediaConnection != null) {
this.mediaConnection.leave();
this.mediaConnection = null;
}
}
/**
* Reset the media feed (audio, video).
*/
this.resetMedia = function(shareAudio, shareVideo) {
this.mediaConnection.session = {
audio: shareAudio,
video: shareVideo
};
for (var streamid in this.mediaConnection.localStreams) {
var stream = this.mediaConnection.streams[streamid];
if (!shareAudio || !shareVideo) {
stream.mute({
audio: !shareAudio,
video: !shareVideo
});
}
if (shareAudio || shareVideo) {
stream.unmute({
audio: shareAudio,
video: shareVideo
});
}
}
}
/**
* Decrease the size of the video element for the userid.
*/
this.shrinkVideo = function(user) {
var streams = this.mediaConnection.streams.selectAll({remote:true, local:true});
for (i = 0; i < streams.length; i++) {
stream = streams[i];
if (stream.userid == user) {
stream.mediaElement.height = stream.mediaElement.height / 1.5;
}
}
};
/**
* Increase the size of the video element for the userid.
*/
this.expandVideo = function(user) {
var streams = this.mediaConnection.streams.selectAll({remote:true, local:true});
for (i = 0; i < streams.length; i++) {
stream = streams[i];
if (stream.userid == user) {
stream.mediaElement.height = stream.mediaElement.height * 1.5;
}
}
};
/**
* Mute the audio for the userid.
*/
this.muteAudio = function(user) {
var streams = this.mediaConnection.streams.selectAll({remote:true, local:true});
for (i = 0; i < streams.length; i++) {
stream = streams[i];
if (stream.userid == user) {
stream.mute({
audio: true
});
}
}
};
/**
* Mute the video for the userid.
*/
this.muteVideo = function(user) {
var streams = this.mediaConnection.streams.selectAll({remote:true, local:true});
for (i = 0; i < streams.length; i++) {
stream = streams[i];
if (stream.userid == user) {
stream.mute({
video: true
});
}
}
};
/**
* Sent a text message to the channel.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
* Note, the listener will receive its own messages.
*/
this.sendMessage = function(message) {
this.checkSocket();
this.socket.send(message);
};
this.sendAttachment = function(file, resize, form) {
var self = this;
var media = new MediaConfig();
if (this.channel == null) {
this.listener.error("Missing channel property");
return false;
}
media.instance = this.channel.id;
media.name = file.name;
media.type = file.type;
if (!resize && file.size > SDK.MAX_FILE_UPLOAD) {
this.listener.error("File exceeds maximum upload size of " + (SDK.MAX_FILE_UPLOAD / 1000000) + "meg");
} else {
this.sdk.error = function(message) {
self.listener.error(message);
}
this.sdk.createChannelAttachment(media, file, resize, form, function(media) {
var message = "file: " + file.name + " : " + file.type + " : " + self.sdk.fetchLink(media.file);
self.sendMessage(message);
})
}
return false;
};
/**
* Accept a private request.
* This is also used by an operator to accept the top of the waiting queue.
* This can also be used by a user to chat with the channel bot.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
*/
this.accept = function() {
this.checkSocket();
this.socket.send("accept");
};
/**
* Test the connection.
* A pong message will be returned, this message will not be broadcast to the channel.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
*/
this.ping = function() {
this.checkSocket();
this.socket.send("ping");
};
/**
* Exit from the current private channel.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
*/
this.exit = function() {
this.checkSocket();
this.socket.send("exit");
};
/**
* Change to spy mode.
* This allows admins to monitor the entire channel.
*/
this.spyMode = function() {
this.checkSocket();
this.socket.send("mode: spy");
};
/**
* Change to normal mode.
*/
this.normalMode = function() {
this.checkSocket();
this.socket.send("mode: normal");
};
/**
* Request a private chat session with a user.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
*/
this.pvt = function(user) {
this.checkSocket();
this.socket.send("pvt: " + user);
};
/**
* Boot a user from the channel.
* You must be a channel administrator to boot a user.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
*/
this.boot = function(user) {
this.checkSocket();
this.socket.send("boot: " + user);
};
/**
* Send a private message to a user.
* This call is asynchronous, any error or success with be sent as a separate message to the listener.
*/
this.whisper = function(user, message) {
this.checkSocket();
this.socket.send("whisper:" + user + ": " + message);
};
/**
* Disconnect from the channel.
*/
this.disconnect = function() {
this.setKeepAlive(false);
if (this.socket != null) {
this.socket.disconnect();
}
disconnectMedia();
};
this.checkSocket = function() {
if (this.socket == null) {
throw "Not connected";
}
};
this.toggleKeepAlive = function() {
this.setKeepAlive(!this.keepAlive);
}
this.setKeepAlive = function(keepAlive) {
this.keepAlive = keepAlive;
if (!keepAlive && this.keepAliveInterval != null) {
clearInterval(this.keepAliveInterval);
} else if (keepAlive && this.keepAliveInterval == null) {
this.keepAliveInterval = setInterval(
function() {
this.ping()
},
600000);
}
}
}
/**
* Connection class for a REST service connection.
* The SDK connection gives you access to the Paphus Live Chat or libre server services using a REST API.
*
* The services include:
*
*
User management (account creation, validation)
*
Bot access, chat, and administration
*
Forum access, posting, and administration
*
Live chat access, chat, and administration
*
Domain access, and administration
*
* @class
* @property user
* @property domain
* @property credentials
* @property debug
* @property error
*/
function SDKConnection() {
this.user;
this.domain;
this.credentials = new Credentials();
this.debug = SDK.debug;
this.error = SDK.error;
this.exception;
/**
* Validate the user credentials (password, or token).
* The user details are returned (with a connection token, password removed).
* The user credentials are soted in the connection, and used on subsequent calls.
* An SDKException is thrown if the connect failed.
*/
this.connect = function(config, processor) {
var self = this;
this.fetchUser(config, function(user) {
self.user = user;
processor(user);
});
}
/**
* Connect to the live chat channel and return a LiveChatConnection.
* A LiveChatConnection is separate from an SDKConnection and uses web sockets for
* asynchronous communication.
* The listener will be notified of all messages.
*/
this.openLiveChat = function(channel, listener) {
var connection = new LiveChatConnection();
connection.sdk = this;
connection.credentials = this.credentials;
connection.listener = listener;
connection.connect(channel, this.user);
return connection;
}
/**
* Connect to the domain.
* A domain is an isolated content space.
* Any browse or query request will be specific to the domain's content.
*/
this.switchDomain = function(config, processor) {
var self = this;
this.fetch(config, function(domain) {
self.domain = domain;
processor(domain);
});
}
/**
* Disconnect from the connection.
* An SDKConnection does not keep a live connection, but this resets its connected user and domain.
*/
this.disconnect = function() {
this.user = null;
this.domain = null;
}
/**
* Fetch the user details for the user credentials.
* A token or password is required to validate the user.
*/
this.fetchUser = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/check-user", config.toXML(), function(xml) {
if (xml == null) {
return;
}
var user = new UserConfig();
user.parseXML(xml);
processor(user);
});
}
/**
* Fetch the URL for the image from the server.
*/
this.fetchImage = function(image) {
return this.credentials.url + "/" + image;
}
/**
* Fetch the URL for the image from the server.
*/
this.fetchLink = function(image) {
return this.credentials.url + "/" + image;
}
/**
* Fetch the forum post details for the forum post id.
*/
this.fetchForumPost = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/check-forum-post", config.toXML(), function(xml) {
if (xml == null) {
return;
}
var post = new ForumPostConfig();
post.parseXML(xml);
processor(post);
});
}
/**
* Create a new user.
*/
this.createUser = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/create-user", config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var user = new UserConfig();
user.parseXML(xml);
this.user = user;
processor(user);
});
}
/**
* Create a new file/image/media attachment for a chat channel.
*/
this.createChannelAttachment = function(config, file, resize, form, processor) {
config.addCredentials(this);
if (resize) {
this.POST_IMAGE(this.credentials.rest + "/create-channel-attachment", file, form, config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var media = new MediaConfig();
media.parseXML(xml);
processor(media);
});
} else {
this.POST_FILE(this.credentials.rest + "/create-channel-attachment", form, config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var media = new MediaConfig();
media.parseXML(xml);
processor(media);
});
}
}
/**
* Create a new file/image/media attachment for a forum.
*/
this.createForumAttachment = function(config, file, resize, form, processor) {
config.addCredentials(this);
if (resize) {
this.POST_IMAGE(this.credentials.rest + "/create-forum-attachment", file, form, config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var media = new MediaConfig();
media.parseXML(xml);
processor(media);
});
} else {
this.POST_FILE(this.credentials.rest + "/create-forum-attachment", form, config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var media = new MediaConfig();
media.parseXML(xml);
processor(media);
});
}
}
/**
* Create a new file/image/media attachment for a forum and insert the http link into the textarea.
*/
this.uploadForumAttachment = function(forum, resize, processor) {
if (!(window.File && window.FileReader && window.FileList && window.Blob)) {
this.error('The File APIs are not fully supported in this browser.');
return false;
}
var form = document.createElement("form");
form.enctype = "multipart/form-data";
form.method = "post";
form.name = "fileinfo";
var fileInput = document.createElement("input");
var self = this;
fileInput.name = "file";
fileInput.type = "file";
form.appendChild(fileInput);
fileInput.onchange = function() {
var file = fileInput.files[0];
self.uploadForumFile(file, forum, resize, form, processor);
}
fileInput.click();
};
/**
* Create a new file/image/media attachment for a forum.
*/
this.uploadForumFile = function(file, forum, resize, form, processor) {
var self = this;
var media = new MediaConfig();
media.instance = forum;
media.name = file.name;
media.type = file.type;
if (!resize && file.size > SDK.MAX_FILE_UPLOAD) {
this.error("File exceeds maximum upload size of " + (SDK.MAX_FILE_UPLOAD / 1000000) + "meg");
} else {
this.createForumAttachment(media, file, resize, form, function(media) {
var link = self.fetchLink(media.file);
if (processor != null) {
processor(link, file.name);
}
})
}
};
/**
* Create a new forum post.
* You must set the forum id for the post.
*/
this.createForumPost = function(config, processor) {
config.addCredentials(this);
var xml = POST(this.credentials.rest + "/create-forum-post", config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var post = new ForumPostConfig();
post.parseXML(xml);
processor(post);
});
}
/**
* Create a reply to a forum post.
* You must set the parent id for the post replying to.
*/
this.createReply = function(config, processor) {
config.addCredentials(this);
var xml = POST(this.credentials.rest + "/create-reply", config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var reply = new ForumPostConfig();
reply.parseXML(xml);
processor(reply);
});
}
/**
* Fetch the content details from the server.
* The id or name and domain of the object must be set.
*/
this.fetch = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/check-" + config.type, config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var config2 = new config.constructor();
config2.parseXML(xml);
processor(config2)
});
}
/**
* Update the forum post.
*/
this.updateForumPost = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/update-forum-post", config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var config = new ForumPostConfig();
config.parseXML(xml);
processor(config);
});
}
/**
* Update the user details.
* The password must be passed to allow the update.
*/
this.updateUser = function(config) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/update-user", config.toXML(), function(xml) {
return;
});
}
/**
* Permanently delete the forum post with the id.
*/
this.deleteForumPost = function(config) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/delete-forum-post", config.toXML(), function(xml) {
return;
});
}
/**
* Flag the content as offensive, a reason is required.
*/
this.flag = function(config) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/flag-" + config.getType(), config.toXML(), function(xml) {
return;
});
}
/**
* Flag the forum post as offensive, a reason is required.
*/
this.flagForumPost = function(config) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/flag-forum-post", config.toXML(), function(xml) {
return;
});
}
/**
* Flag the user post as offensive, a reason is required.
*/
this.flagUser = function(config) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/flag-user", config.toXML(), function(xml) {
return;
});
}
/**
* Process the bot chat message and return the bot's response.
* The ChatConfig should contain the conversation id if part of a conversation.
* If a new conversation the conversation id is returned in the response.
*/
this.chat = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/post-chat", config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var responseMessage = new ChatResponse();
responseMessage.parseXML(xml);
processor(responseMessage);
});
}
/**
* Process the avatar message and return the avatar's response.
*/
this.avatarMessage = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/avatar-message", config.toXML(), function(xml) {
if (xml == null) {
return null;
}
var responseMessage = new ChatResponse();
responseMessage.parseXML(xml);
processor(responseMessage);
});
}
/**
* Return the list of user details for the comma separated values list of user ids.
*/
this.fetchAllUsers = function(usersCSV, processor) {
var config = new UserConfig();
config.user = usersCSV;
config.addCredentials(this);
this.POST(this.credentials.rest + "/get-users", config.toXML(), function(xml) {
var users = [];
if (xml != null) {
for (var index = 0; index < xml.childNodes.length; index++) {
var child = xml.childNodes[index];
var userConfig = new UserConfig();
userConfig.parseXML(child);
users[user.length] = userConfig;
}
}
processor(users);
});
}
/**
* Return the list of forum posts for the forum browse criteria.
*/
this.fetchPosts = function(config, processor) {
config.addCredentials(this);
var xml = this.POST(this.credentials.rest + "/get-forum-posts", config.toXML(), function(xml) {
var instances = [];
if (xml != null) {
for (var index = 0; index < xml.childNodes.length; index++) {
var child = xml.childNodes[index];
var post = new ForumPostConfig();
post.parseXML(child);
instances[instances.length] = post;
}
}
processor(instances);
});
}
/**
* Return the list of categories for the type, and domain.
*/
this.fetchCategories = function(config, processor) {
config.addCredentials(this);
var xml = this.POST(this.credentials.rest + "/get-categories", config.toXML(), function(xml) {
var categories = [];
categories[0] = "";
if (xml != null) {
for (var index = 0; index < xml.childNodes.length; index++) {
categories[categories.length] = (xml.childNodes[index].getAttribute("name"));
}
}
processor(categories);
});
}
/**
* Return the list of tags for the type, and domain.
*/
this.fetchTags = function(config, processor) {
config.addCredentials(this);
var xml = this.POST(this.credentials.rest + "/get-tags", config.toXML(), function(xml) {
var tags = [];
tags[0] = "";
if (xml != null) {
for (var index = 0; index < xml.childNodes.length; index++) {
tags[tags.length] = (xml.childNodes[index].getAttribute("name"));
}
}
processor(tags);
});
}
/**
* Return the users for the content.
*/
this.fetchUsers = function(config, processor) {
config.addCredentials(this);
var xml = this.POST(this.credentials.rest + "/get-" + config.getType() + "-users", config.toXML(), function(xml) {
var users = [];
if (xml != null) {
for (var index = 0; index < xml.childNodes.length; index++) {
var user = new UserConfig();
user.parseXML(xml.childNodes[index]);
users[users.length] = (user.user);
}
}
processor(users);
});
}
/**
* Initialize the bot's avatar for a chat session.
* This can be done before processing the first message for a quick response.
* @deprecated replaced by initChat()
*/
this.initAvatar = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/init-avatar", config.toXML(), function(xml) {
if (xml == null) {
return;
}
var response = new ChatResponse();
response.parseXML(xml);
processor(response);
});
}
/**
* Initialize the bot's avatar for a chat session.
* This can be done before processing the first message for a quick response.
*/
this.initChat = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/init-chat", config.toXML(), function(xml) {
if (xml == null) {
return;
}
var response = new ChatResponse();
response.parseXML(xml);
processor(response);
});
}
/**
* Return the conversation's chat settings.
*/
this.chatSettings = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/chat-settings", config.toXML(), function(xml) {
if (xml == null) {
return;
}
var settings = new ChatSettings();
settings.parseXML(xml);
processor(settings);
});
}
/**
* Return the bot's voice configuration.
*/
this.trainInstance = function(config) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/train-instance", config.toXML(), function(xml) {
return;
});
}
/**
* Return the bot's voice configuration.
*/
this.fetchVoice = function(config, processor) {
config.addCredentials(this);
this.POST(this.credentials.rest + "/get-voice", config.toXML(), function(xml) {
if (xml == null) {
return;
}
var voice = new VoiceConfig();
voice.parseXML(xml);
processor(voice);
});
}
/**
* Return the list of content for the browse criteria.
* The type defines the content type (one of Bot, Forum, Channel, Domain).
*/
this.browse = function(config, processor) {
config.addCredentials(this);
var type = "";
if (config.type == "Bot") {
type = "/get-instances";
} else if (config.type == "Forum") {
type = "/get-forums";
} else if (config.type == "Channel") {
type = "/get-channels";
} else if (config.type == "Domain") {
type = "/get-domains";
} else if (config.type == "Graphic") {
type = "/get-graphics";
} else if (config.type == "Avatar") {
type = "/get-avatars";
} else if (config.type == "Script") {
type = "/get-scripts";
}
this.POST(this.credentials.rest + type, config.toXML(), function(xml) {
var instances = [];
if (xml != null) {
for (var index = 0; index < xml.childNodes.length; index++) {
var instance = null;
if (config.type == "Bot") {
instance = new InstanceConfig();
} else if (config.type == "Forum") {
instance = new ForumConfig();
} else if (config.type == "Channel") {
instance = new ChannelConfig();
} else if (config.type == "Domain") {
instance = new DomainConfig();
} else if (config.type == "Avatar") {
instance = new AvatarConfig();
} else if (config.type == "Script") {
instance = new ScriptConfig();
} else if (config.type == "Graphic") {
instance = new GraphicConfig();
}
instance.parseXML(xml.childNodes[index]);
instances[instances.length] = (instance);
}
}
processor(instances);
});
}
this.GET = function(url, processor) {
if (this.debug) {
console.log("GET: " + url);
}
var xml = null;
var request = new XMLHttpRequest();
var debug = this.debug;
var self = this;
request.onreadystatechange = function() {
if (request.readyState != 4) return;
if (request.status != 200) {
console.log('Error: SDK GET web request failed');
if (debug) {
console.log(request.statusText);
console.log(request.responseText);
console.log(request.responseXML);
}
if (request.statusText != null && request.responseText != null && request.responseText.indexOf("") != -1) {
self.error(request.statusText);
} else {
self.error(request.responseText);
}
return;
}
processor(request.responseXML.childNodes[0]);
}
request.open('GET', url, true);
request.send();
}
this.POST = function(url, xml, processor) {
if (this.debug) {
console.log("POST: " + url);
console.log("XML: " + xml);
}
var request = new XMLHttpRequest();
var debug = this.debug;
var self = this;
request.onreadystatechange = function() {
if (debug) {
console.log(request.readyState);
console.log(request.status);
console.log(request.statusText);
console.log(request.responseText);
console.log(request.responseXML);
}
if (request.readyState != 4) return;
if (request.status != 200 && request.status != 204) {
console.log('Error: SDK POST web request failed');
if (debug) {
console.log(request.statusText);
console.log(request.responseText);
console.log(request.responseXML);
}
if (request.statusText != null && request.responseText != null && request.responseText.indexOf("") != -1) {
self.error(request.statusText);
} else {
self.error(request.responseText);
}
return;
}
processor(request.responseXML.childNodes[0]);
};
request.open('POST', url, true);
request.setRequestHeader("Content-Type", "application/xml");
request.send(xml);
}
this.POST_FILE = function(url, form, xml, processor) {
if (this.debug) {
console.log("POST FILE: " + url);
console.log("FORM: " + form);
console.log("XML: " + xml);
}
var request = new XMLHttpRequest();
var formData = new FormData(form);
formData.append("xml", xml);
var debug = this.debug;
var self = this;
request.onreadystatechange = function() {
if (debug) {
console.log(request.readyState);
console.log(request.status);
console.log(request.statusText);
console.log(request.responseText);
console.log(request.responseXML);
}
if (request.readyState != 4) return;
if (request.status != 200 && request.status != 204) {
console.log('Error: SDK POST web request failed');
if (debug) {
console.log(request.statusText);
console.log(request.responseText);
console.log(request.responseXML);
}
if (request.statusText != null && request.responseText != null && request.responseText.indexOf("") != -1) {
self.error(request.statusText);
} else {
self.error(request.responseText);
}
return;
}
processor(request.responseXML.childNodes[0]);
};
request.open('POST', url, true);
//request.setRequestHeader("Content-Type", "multipart/form-data");
request.send(formData);
}
this.POST_IMAGE = function(url, file, form, xml, processor) {
var self = this;
var debug = this.debug;
var reader = new FileReader();
reader.onloadend = function() {
var tempImg = new Image();
tempImg.src = reader.result;
tempImg.onload = function() {
var MAX_WIDTH = 300;
var MAX_HEIGHT = 300;
var tempW = tempImg.width;
var tempH = tempImg.height;
if (tempW > tempH) {
if (tempW > MAX_WIDTH) {
tempH *= MAX_WIDTH / tempW;
tempW = MAX_WIDTH;
}
} else {
if (tempH > MAX_HEIGHT) {
tempW *= MAX_HEIGHT / tempH;
tempH = MAX_HEIGHT;
}
}
var canvas = document.createElement('canvas');
canvas.width = tempW;
canvas.height = tempH;
var ctx = canvas.getContext("2d");
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(this, 0, 0, tempW, tempH);
var dataUrl = canvas.toDataURL('image/jpeg');
var blob = SDK.dataURLToBlob(dataUrl);
var request = new XMLHttpRequest();
var formData = new FormData();
formData.append("xml", xml);
formData.append('file', blob, file.name);
request.onreadystatechange = function() {
if (debug) {
console.log(request.readyState);
console.log(request.status);
console.log(request.statusText);
console.log(request.responseText);
console.log(request.responseXML);
}
if (request.readyState != 4) return;
if (request.status != 200 && request.status != 204) {
console.log('Error: SDK POST web request failed');
if (debug) {
console.log(request.statusText);
console.log(request.responseText);
console.log(request.responseXML);
}
if (request.statusText != null && request.responseText != null && request.responseText.indexOf("") != -1) {
self.error(request.statusText);
} else {
self.error(request.responseText);
}
return;
}
processor(request.responseXML.childNodes[0]);
};
request.open('POST', url, true);
//request.setRequestHeader("Content-Type", "multipart/form-data");
request.send(formData);
}
}
reader.readAsDataURL(file);
}
}
/**
* Abstract root class for all web API message objects.
* Defines the required application id, and common fields.
* @class
* @property application
* @property domain
* @property user
* @property token
* @property instance
* @property type
*/
function Config() {
/** The application ID. This is require to authenticate the API usage. You can obtain your application ID from your user page. */
this.application;
/** Optional domain id, if object is not on the server's default domain. */
this.domain;
/** User ID, required for content creation, secure content access, or to identify the user. */
this.user;
/** User's access token, returned from connect web API, can be used in place of password in subsequent calls, and stored in a cookie. The user's password should never be stored. */
this.token;
/** The id or name of the bot or content instance to access. */
this.instance;
/** Type of instance to access, ("Bot", "Forum", "Channel", "Domain") */
this.type;
this.addCredentials = function(connection) {
this.application = connection.credentials.applicationId;
if (connection.user != null) {
this.user = connection.user.user;
this.token = connection.user.token;
}
if (connection.domain != null) {
this.domain = connection.domain.id;
}
}
this.writeCredentials = function(xml) {
if (this.user != null && this.user.length > 0) {
xml = xml + (" user=\"" + this.user + "\"");
}
if (this.token != null && this.token.length > 0) {
xml = xml + (" token=\"" + this.token + "\"");
}
if (this.type != null && this.type.length > 0) {
xml = xml + (" type=\"" + this.type + "\"");
}
if (this.instance != null && this.instance.length > 0) {
xml = xml + (" instance=\"" + this.instance + "\"");
}
if (this.application != null && this.application.length > 0) {
xml = xml + (" application=\"" + this.application + "\"");
}
if (this.domain != null && this.domain.length > 0) {
xml = xml + (" domain=\"" + this.domain + "\"");
}
return xml;
}
}
/**
* This object models a user.
* It can be used from a chat UI, or with the Libre Web API.
* It can convert itself to/from XML for web API usage.
* This can be used to connect, create, edit, or browse a user instance.
* @class
* @property password
* @property newPassword
* @property hint
* @property name
* @property showName
* @property email
* @property website
* @property bio
* @property over18
* @property avatar
* @property connects
* @property bots
* @property posts
* @property messages
* @property joined
* @property lastConnect
*/
function UserConfig() {
/** Password, require to connect a user, or create a user. */
this.password;
/** New password for editting a user's password (password is old password). */
this.newPassword;
/** Optional password hint, in case password is forgotten. */
this.hint;
/** Optional real name of the user. */
this.name;
/** The real name can be hidden from other users. */
this.showName;
/** Email, required for message notification, and to reset password. */
this.email;
/** Optional user's website. */
this.website;
/** Optional user's bio. */
this.bio;
this.over18;
/** Read-only, server local URL for user's avatar image. */
this.avatar;
/** Read-only, total user connects. */
this.connects;
/** Read-only, total bots created. */
this.bots;
/** Read-only, total forum posts. */
this.posts;
/** Read-only, total chat messages. */
this.messages;
/** Read-only, date user joined. */
this.joined;
/** Read-only, date of user's last connect. */
this.lastConnect;
this.addCredentials = function(connection) {
this.application = connection.credentials.applicationId;
if (connection.domain != null) {
this.domain = connection.domain.id;
}
}
this.parseXML = function(element) {
this.user = element.getAttribute("user");
this.name = element.getAttribute("name");
this.showName = element.getAttribute("showName");
this.token = element.getAttribute("token");
this.email = element.getAttribute("email");
this.hint = element.getAttribute("hint");
this.website = element.getAttribute("website");
this.connects = element.getAttribute("connects");
this.bots = element.getAttribute("bots");
this.posts = element.getAttribute("posts");
this.messages = element.getAttribute("messages");
this.joined = element.getAttribute("joined");
this.lastConnect = element.getAttribute("lastConnect");
var node = element.getElementsByTagName("bio")[0];
if (node != null) {
this.bio = SDK.innerHTML(node);
}
node = element.getElementsByTagName("avatar")[0];
if (node != null) {
this.avatar = SDK.innerHTML(node);
}
}
this.toXML = function() {
var xml = "");
if (this.bio != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.bio));
xml = xml + ("");
}
xml = xml + ("");
return xml;
}
}
UserConfig.prototype = new Config();
UserConfig.prototype.constructor = UserConfig;
UserConfig.constructor = UserConfig;
/**
* This object models a chat message sent to a chat bot instance.
* It can be used from a chat UI, or with the Libre Web API.
* It can convert itself to XML for web API usage.
* @class
* @property conversation
* @property speak
* @property correction
* @property offensive
* @property disconnect
* @property emote
* @property action
* @property message
* @property debug
* @property debugLevel
* @property learn
*/
function ChatConfig() {
/** The conversation id for the message. This will be returned from the first response, and must be used for all subsequent messages to maintain the conversational state. Without the conversation id, the bot has no context for the reply. */
this.conversation;
/** Sets if the voice audio should be generated for the bot's response. */
this.speak;
/** Sets the message to be a correction to the bot's last response. */
this.correction;
/** Flags the bot's last response as offensive. */
this.offensive;
/** Ends the conversation. Conversation should be terminated to converse server resources. The message can be blank. */
this.disconnect;
/**
* Attaches an emotion to the user's message, one of:
* NONE,
* LOVE, LIKE, DISLIKE, HATE,
* RAGE, ANGER, CALM, SERENE,
* ECSTATIC, HAPPY, SAD, CRYING,
* PANIC, AFRAID, CONFIDENT, COURAGEOUS,
* SURPRISE, BORED,
* LAUGHTER, SERIOUS
*/
this.emote;
/** Attaches an action to the user's messages, such as "laugh", "smile", "kiss". */
this.action;
/** The user's message text. */
this.message;
/** Include the message debug log in the response. */
this.debug;
/** Set the debug level, one of: SEVER, WARNING, INFO, CONFIG, FINE, FINER. */
this.debugLevel;
/** Enable or disable the bot's learning for this message. */
this.learn;
/** Escape and filter the response message HTML content for XSS security. */
this.secure = true;
/** Strip any HTML tags from the response message. */
this.plainText;
/** Send extra info with the message, such as the user's contact info (name email phone). */
this.info;
/** Request a specific avatar (by ID). */
this.avatar;
/** Request the response avatar media in HD. */
this.avatarHD = SDK.hd;
/** Request the response avatar media in a video or image format. */
this.avatarFormat = SDK.format;
/** Translate between the user's language and the bot's language. */
this.language;
this.toXML = function() {
var xml = "");
if (this.message != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.message));
xml = xml + ("");
}
xml = xml + ("");
return xml;
}
}
ChatConfig.prototype = new Config();
ChatConfig.prototype.constructor = ChatConfig;
ChatConfig.constructor = ChatConfig;
/**
* This object models a chat message received from a chat bot instance.
* It can be used from a chat UI, or with the Libre Web API.
* It can convert itself from XML for web API usage.
* @class
* @property conversation
* @property avatar
* @property avatarType
* @property avatarTalk
* @property avatarTalkType
* @property avatarAction
* @property avatarActionType
* @property avatarActionAudio
* @property avatarActionAudioType
* @property avatarAudio
* @property avatarAudioType
* @property avatarBackground
* @property speech
* @property message
* @property question
* @property emote
* @property action
* @property pose
* @property log
*/
function ChatResponse() {
/** The conversation id for the message. This will be returned from the first response, and must be used for all subsequent messages to maintain the conversational state. Without the conversation id, the bot has no context for the reply. */
this.conversation;
/** Server relative URL for the avatar image or video. */
this.avatar;
/** Second avatar animation. */
this.avatar2;
/** Third avatar animation. */
this.avatar3;
/** Forth avatar animation. */
this.avatar4;
/** Fifth avatar animation. */
this.avatar5;
/** Avatar MIME file type, (mpeg, webm, ogg, jpeg, png) */
this.avatarType;
/** Server relative URL for the avatar talking image or video. */
this.avatarTalk;
/** Avatar talk MIME file type, (mpeg, webm, ogg, jpeg, png) */
this.avatarTalkType;
/** Server relative URL for the avatar action image or video. */
this.avatarAction;
/** Avatar action MIME file type, (mpeg, webm, ogg, jpeg, png) */
this.avatarActionType;
/** Server relative URL for the avatar action audio image or video. */
this.avatarActionAudio;
/** Avatar action audio MIME file type, (mpeg, wav) */
this.avatarActionAudioType;
/** Server relative URL for the avatar audio image or video. */
this.avatarAudio;
/** Avatar audio MIME file type, (mpeg, wav) */
this.avatarAudioType;
/** Server relative URL for the avatar background image. */
this.avatarBackground;
/** Server relative URL for the avatar speech audio file. */
this.speech;
/** The bot's message text. */
this.message;
/** Optional text to the original question. */
this.question;
/**
* Emotion attached to the bot's message, one of:
* NONE,
* LOVE, LIKE, DISLIKE, HATE,
* RAGE, ANGER, CALM, SERENE,
* ECSTATIC, HAPPY, SAD, CRYING,
* PANIC, AFRAID, CONFIDENT, COURAGEOUS,
* SURPRISE, BORED,
* LAUGHTER, SERIOUS
*/
this.emote;
/** Action for the bot's messages, such as "laugh", "smile", "kiss", or mobile directive (for virtual assistants). */
this.action;
/** Pose for the bot's messages, such as "dancing", "sitting", "sleeping". */
this.pose;
/** The debug log of processing the message. */
this.log;
this.parseXML = function(element) {
this.conversation = element.getAttribute("conversation");
this.avatar = element.getAttribute("avatar");
this.avatar2 = element.getAttribute("avatar2");
this.avatar3 = element.getAttribute("avatar3");
this.avatar4 = element.getAttribute("avatar4");
this.avatar5 = element.getAttribute("avatar5");
this.avatarType = element.getAttribute("avatarType");
this.avatarTalk = element.getAttribute("avatarTalk");
this.avatarTalkType = element.getAttribute("avatarTalkType");
this.avatarAction = element.getAttribute("avatarAction");
this.avatarActionType = element.getAttribute("avatarActionType");
this.avatarActionAudio = element.getAttribute("avatarActionAudio");
this.avatarActionAudioType = element.getAttribute("avatarActionAudioType");
this.avatarAudio = element.getAttribute("avatarAudio");
this.avatarAudioType = element.getAttribute("avatarAudioType");
this.avatarBackground = element.getAttribute("avatarBackground");
this.emote = element.getAttribute("emote");
this.action = element.getAttribute("action");
this.pose = element.getAttribute("pose");
this.speech = element.getAttribute("speech");
var node = element.getElementsByTagName("message")[0];
if (node != null) {
this.message = SDK.innerHTML(node);
}
node = element.getElementsByTagName("log")[0];
if (node != null) {
this.log = SDK.innerHTML(node);
}
}
}
ChatResponse.prototype = new Config();
ChatResponse.prototype.constructor = ChatResponse;
ChatResponse.constructor = ChatResponse;
/**
* This object is returned from the SDK chatSettings() API to retrieve a conversation's chat settings.
* It can convert itself from XML for web API usage.
* @class
* @property conversation
* @property allowEmotes
* @property allowCorrection
* @property allowLearning
* @property learning
*/
function ChatSettings() {
this.conversation;
this.allowEmotes;
this.allowCorrection;
this.allowLearning;
this.learning;
this.toXML = function() {
var xml = "");
return xml;
}
this.parseXML = function(element) {
this.allowEmotes = "true" == (element.getAttribute("allowEmotes"));
this.allowCorrection = "true" == (element.getAttribute("allowCorrection"));
this.allowLearning = "true" == (element.getAttribute("allowLearning"));
this.learning = "true" == (element.getAttribute("learning"));
}
}
ChatSettings.prototype = new Config();
ChatSettings.prototype.constructor = ChatSettings;
ChatSettings.constructor = ChatSettings;
/**
* DTO for XML avatar message config.
* @class
* @property avatar
* @property speak
* @property voice
* @property message
* @property emote
* @property action
* @property pose
*/
function AvatarMessage() {
this.avatar;
this.speak;
this.voice;
this.message;
this.emote;
this.action;
this.pose;
this.hd = SDK.hd;
this.format = SDK.format;
this.toXML = function() {
var xml = "");
if (this.message != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.message));
xml = xml + ("");
}
xml = xml + ("");
return xml;
}
}
AvatarMessage.prototype = new Config();
AvatarMessage.prototype.constructor = AvatarMessage;
AvatarMessage.constructor = AvatarMessage;
/**
* This object models the web API browse operation.
* It can be used to search a set of instances (bots, forums, or channels).
* @class
* @property type
* @property typeFilter
* @property category
* @property tag
* @property filter
* @property sort
*/
function BrowseConfig() {
/** Filters instances by access type, "Public", "Private", "Personal". */
this.typeFilter;
/** Filters instances by categories (csv) */
this.category;
/** Filters instances by tags (csv) */
this.tag;
/** Filters instances by name */
this.filter;
/** Sorts instances, "name", "date", "size", "stars", "thumbs up", "thumbs down", "last connect", "connects", "connects today", "connects this week ", "connects this month" */
this.sort;
this.toXML = function() {
var xml = "");
return xml;
}
}
BrowseConfig.prototype = new Config();
BrowseConfig.prototype.constructor = BrowseConfig;
BrowseConfig.constructor = BrowseConfig;
/**
* Abstract content class.
* This object models a content object such as a bot, forum, or channel.
* It can be used from a chat UI, or with the Libre Web API.
* It can convert itself to/from XML for web API usage.
* This can be used to create, edit, or browse a content.
* @class
* @property id
* @property name
* @property isAdmin
* @property isAdult
* @property isPrivate
* @property isHidden
* @property accessMode
* @property isFlagged
* @property flaggedReason
* @property isExternal
* @property description
* @property details
* @property disclaimer
* @property tags
* @property categories
* @property creator
* @property creationDate
* @property lastConnectedUser
* @property website
* @property license
* @property avatar
* @property connects
* @property dailyConnects
* @property weeklyConnects
* @property monthlyConnects
*/
function WebMediumConfig() {
/** Instance ID. */
this.id;
/** Instance name. */
this.name;
/** Read-only, returns if connected user is the content's admin. */
this.isAdmin;
this.isAdult;
/** Sets if the content is private to the creator, and its members. */
this.isPrivate;
/** Sets if the conent will be visible and searchable in the content directory. */
this.isHidden;
/** Sets the access mode for the content, ("Everyone", "Users", "Members", "Administrators"). */
this.accessMode;
/** Returns if the content has been flagged, or used to flag content as offensive (reason required). */
this.isFlagged;
/** Returns why the content has been flagged, or used to flag content as offensive. */
this.flaggedReason;
/** Can be used to create a link to external content in the content directory. */
this.isExternal;
/** Optional description of the content. */
this.description;
/** Optional restrictions or details of the content. */
this.details;
/** Optional warning or disclaimer of the content. */
this.disclaimer;
/** Tags to classify the content (csv). */
this.tags;
/** Categories to categorize the content under (csv). */
this.categories;
/** Read-only, returns content's creator's user ID. */
this.creator;
/** Read-only, returns content's creation date. */
this.creationDate;
/** Read-only, returns last user to access content */
this.lastConnectedUser;
/** Optional license to license the content under. */
this.license;
/** Optional website related to the content. */
this.website = "";
/** Read-only, server local URL to content's avatar image. */
this.avatar;
/** Read-only, returns content's toal connects. */
this.connects;
/** Read-only, returns content's daily connects. */
this.dailyConnects;
/** Read-only, returns content's weekly connects. */
this.weeklyConnects;
/** Read-only, returns content's monthly connects. */
this.monthlyConnects;
this.writeWebMediumXML = function(xml) {
xml = this.writeCredentials(xml);
if (this.id != null) {
xml = xml + (" id=\"" + this.id + "\"");
}
if (this.name != null) {
xml = xml + (" name=\"" + this.name + "\"");
}
if (this.isPrivate) {
xml = xml + (" isPrivate=\"true\"");
}
if (this.isHidden) {
xml = xml + (" isHidden=\"true\"");
}
if (this.accessMode != null && this.accessMode != "") {
xml = xml + (" accessMode=\"" + this.accessMode + "\"");
}
if (this.isAdult) {
xml = xml + (" isAdult=\"true\"");
}
if (this.isFlagged) {
xml = xml + (" isFlagged=\"true\"");
}
xml = xml + (">");
if (this.description != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.description));
xml = xml + ("");
}
if (this.details != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.details));
xml = xml + ("");
}
if (this.disclaimer != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.disclaimer));
xml = xml + ("");
}
if (this.categories != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.categories));
xml = xml + ("");
}
if (this.tags != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.tags));
xml = xml + ("");
}
if (this.license != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.license));
xml = xml + ("");
}
if (this.flaggedReason != null) {
xml = xml + ("");
xml = xml + (SDK.escapeHTML(this.flaggedReason));
xml = xml + ("");
}
return xml;
}
this.parseWebMediumXML = function(element) {
this.id = element.getAttribute("id");
this.name = element.getAttribute("name");
this.creationDate = element.getAttribute("creationDate");
this.isPrivate = element.getAttribute("isPrivate");
this.isHidden = element.getAttribute("isHidden");
this.accessMode = element.getAttribute("accessMode");
this.isAdmin = element.getAttribute("isAdmin");
this.isAdult = element.getAttribute("isAdult");
this.isFlagged = element.getAttribute("isFlagged");
this.creator = element.getAttribute("creator");
this.creationDate = element.getAttribute("creationDate");
this.connects = element.getAttribute("connects");
this.dailyConnects = element.getAttribute("dailyConnects");
this.weeklyConnects = element.getAttribute("weeklyConnects");
this.monthlyConnects = element.getAttribute("monthlyConnects");
var node = element.getElementsByTagName("description")[0];
if (node != null) {
this.description = SDK.innerHTML(node);
}
node = element.getElementsByTagName("details")[0];
if (node != null) {
this.details = SDK.innerHTML(node);
}
node = element.getElementsByTagName("disclaimer")[0];
if (node != null) {
this.disclaimer = SDK.innerHTML(node);
}
node = element.getElementsByTagName("categories")[0];
if (node != null) {
this.categories = SDK.innerHTML(node);
}
node = element.getElementsByTagName("tags")[0];
if (node != null) {
this.tags = SDK.innerHTML(node);
}
node = element.getElementsByTagName("flaggedReason")[0];
if (node != null) {
this.flaggedReason = SDK.innerHTML(node);
}
node = element.getElementsByTagName("lastConnectedUser")[0];
if (node != null) {
this.lastConnectedUser = SDK.innerHTML(node);
}
node = element.getElementsByTagName("license")[0];
if (node != null) {
this.license = SDK.innerHTML(node);
}
node = element.getElementsByTagName("avatar")[0];
if (node != null) {
this.avatar = SDK.innerHTML(node);
}
}
}
WebMediumConfig.prototype = new Config();
WebMediumConfig.prototype.constructor = WebMediumConfig;
WebMediumConfig.constructor = WebMediumConfig;
/**
* This object models a live chat channel or chatroom instance.
* It can be used from a chat UI, or with the Libre Web API.
* It can convert itself to/from XML for web API usage.
* This can be used to create, edit, or browse a channel instance.
* @class
* @property type
* @property messages
* @property usersOnline
* @property adminsOnline
*/
function ChannelConfig() {
/** Sets type, "ChatRoom", "OneOnOne". */
this.type;
/** Read-only: total number of messages. */
this.messages;
/** Read-only: current users online. */
this.usersOnline;
/** Read-only: current admins or operators online. */
this.adminsOnline;
this.type = "channel";
this.credentials = function() {
var config = new ChannelConfig();
config.id = this.id;
return config;
}
this.toXML = function() {
var xml = "");
return xml;
}
this.parseXML = function(element) {
this.parseWebMediumXML(element);
this.type = element.getAttribute("type");
this.messages = element.getAttribute("messages");
this.usersOnline = element.getAttribute("usersOnline");
this.adminsOnline = element.getAttribute("adminsOnline");
}
}
ChannelConfig.prototype = new WebMediumConfig();
ChannelConfig.prototype.constructor = ChannelConfig;
ChannelConfig.constructor = ChannelConfig;
/**
* DTO to parse response of a list of names.
* This is used for categories, tags, and templates.
* @class
* @property type
*/
function ContentConfig() {
this.type;
this.parseXML = function(element) {
this.type = element.getAttribute("type");
}
this.toXML = function() {
var xml = "");
return xml;
}
}
ContentConfig.prototype = new Config();
ContentConfig.prototype.constructor = ContentConfig;
ContentConfig.constructor = ContentConfig;
/**
* This object models a domain.
* It can be used from a chat UI, or with the Libre Web API.
* A domain is an isolated content space to create bots and other content in (such as a commpany, project, or school).
* It can convert itself to/from XML for web API usage.
* This can be used to create, edit, or browse a domain instance.
* @class
* @property creationMode
*/
function DomainConfig() {
this.creationMode;
this.type = "domain";
this.credentials = function() {
var config = new DomainConfig();
config.id = this.id;
return config;
}
this.toXML = function() {
var xml = "");
return xml;
}
this.parseXML = function(element) {
this.parseWebMediumXML(element);
this.creationMode = element.getAttribute("creationMode");
}
}
DomainConfig.prototype = new WebMediumConfig();
DomainConfig.prototype.constructor = DomainConfig;
DomainConfig.constructor = DomainConfig;
/**
* This object models an avatar.
* An avatar represents a bot's visual image, but can also be used independently with TTS.
* It can convert itself to/from XML for web API usage.
* This can be used to create, edit, or browse an avatar instance.
* @class
*/
function AvatarConfig() {
this.type = "avatar";
this.credentials = function() {
var config = new AvatarConfig();
config.id = this.id;
return config;
}
this.toXML = function() {
var xml = "");
return xml;
}
this.parseXML = function(element) {
this.parseWebMediumXML(element);
}
}
AvatarConfig.prototype = new WebMediumConfig();
AvatarConfig.prototype.constructor = AvatarConfig;
AvatarConfig.constructor = AvatarConfig;
/**
* This object models a script from the script library.
* It can convert itself to/from XML for web API usage.
* This can be used to create, edit, or browse an avatar instance.
* @class
*/
function ScriptConfig() {
this.type = "script";
this.credentials = function() {
var config = new AvatarConfig();
config.id = this.id;
return config;
}
this.toXML = function() {
var xml = "