@claudio.giuliano/fm-chatbot-client
Version:
A chat widget to deploy virtual assistants made with Rasa on any website
962 lines (837 loc) • 37.7 kB
JavaScript
/* global console*/
function FmChatbotEs5() {
'use strict';
var _this = this;
var UID = new IDGenerator().generate();
var DEFAULT_FONT_FAMILY = "\"Titillium Web\", \"Geneva\", \"Tahoma\", sans-serif, serif";//"Arial, Helvetica, sans-serif";
var DEFAULT_PAY_LOAD = "/start";
var apiUrl = null;
var selector = "fm-chatbot";
/**
* Gets the browser's name and version
* @constructor
*/
function Browser() {
this.get = function getBrowser() {
var ua = navigator.userAgent, tem,
M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
console.debug("user agent", ua);
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return {name: 'IE', version: (tem[1] || '')};
}
if (M[1] === 'Chrome') {
tem = ua.match(/\bOPR|Edge\/(\d+)/);
if (tem !== null) {
return {name: 'Opera', version: tem[1]};
}
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) !== null) {
M.splice(1, 1, tem[1]);
}
return {
name: M[0],
version: parseInt(M[1])
};
};
}
var BROWSER = new Browser().get();
/**
* Creates the chatbot widget
* @param args
*/
this.create = function (args) {
console.info("creating the chatbot widget...", args);
console.info("browser", BROWSER);
//todo polling to check the connection
// selector contains the chatbot in the host page
if (args.hasOwnProperty("selector")) {
selector = args.selector;
}
if (args.hasOwnProperty("apiUrl")) {
try {
apiUrl = new URL(args.apiUrl);
} catch (e) {
console.error(e);
return;
}
} else {
console.warn("no apiURL");
}
//todo load/save the conversations?
document.addEventListener("DOMContentLoaded", function () {
// create and show the chatbot widget
init(args);
// change the widget size based on media type
media(args);
// welcome the user, or send a notification if the service is not available
// to in this case che chatbot could be closed
welcome(args);
});
// todo change position based on the page scroll
// document.addEventListener("scroll", function () {
// console.info("scrolling...");
// let chatbotContainer = document.getElementById(selector);
//
// console.info("scrolling...", document.documentElement.scrollTop);
// if (document.documentElement.scrollTop > 0) {
// chatbotContainer.style.paddingBottom = "100px";
// } else {
// chatbotContainer.style.paddingBottom = "0";
// }
// });
};
var MAX_WIDTH = 640;
var MAX_HEIGHT = 420;
/**
* Sets the chatbot widget size based on the media type.
* @param args
*/
function media(args) {
console.log("changing the chatbot widget size...");
var maxWidthQuery = window.matchMedia("screen and (max-width: " + MAX_WIDTH + "px)");
fitToWidth(maxWidthQuery);
var maxHeightQuery = window.matchMedia("screen and (max-height: " + MAX_HEIGHT + "px)");
fitToHeight(maxHeightQuery);
// addEventListener is not supported on Safari < 14 (See https://stackoverflow.com/questions/35719526/safari-ignore-window-matchmedia)
if (BROWSER.version >= 14) {
maxWidthQuery.addEventListener('change', fitToWidth);
maxHeightQuery.addEventListener('change', fitToHeight);
} else {
maxWidthQuery.addListener(fitToWidth);
maxHeightQuery.addListener(fitToHeight);
}
}
/**
* Sets the chatbot widget width.
* @param e
*/
function fitToWidth(e) {
console.info("fit the chatbot widget to screen width", e);
var chatbotContainer = document.getElementById(selector);
var chatbotOpenIcon = document.getElementById("fm-chatbot-open-icon");
var chatbotOpenBtn = document.getElementById("fm-chatbot-open-btn");
var chatbotGrid = document.getElementById("fm-chatbot-grid");
var viewportSize = getViewportSize();
console.debug("chatbot size", viewportSize);
//todo use padding if back-to-top is displayed: back-to-top-show
if (e.matches) {
/* the viewport is MAX_WIDTH pixels wide or less */
console.debug("the viewport is " + MAX_WIDTH + "pixels wide or less", e);
chatbotContainer.style.margin = "16px";
chatbotOpenBtn.style.width = "40px";
chatbotOpenBtn.style.height = "40px";
chatbotOpenIcon.style.fontSize = "20px";
//var w = viewportSize["width"] - 32;
//let h = viewportSize["height"] - 60 - 70 - 100;
//console.info("w,h", w, h);
//chatbotGrid.style.gridTemplateColumns = w + "px";
chatbotGrid.style.gridTemplateColumns = "auto";
} else {
/* the viewport is more than than MAX_WIDTH pixels wide */
console.debug("the viewport is more than than " + MAX_WIDTH + " pixels wide", e);
chatbotContainer.style.margin = "32px";
chatbotOpenBtn.style.width = "56px";
chatbotOpenBtn.style.height = "56px";
chatbotOpenIcon.style.fontSize = "32px";
// chatbotContainer.style.bottom = "32px";
// chatbotContainer.style.right = "32px";
var w = MAX_WIDTH - 64;
//let h = 300 - 60 - 70;//viewportSize["height"] - 200;
//console.info("w,h", w, h);
chatbotGrid.style.gridTemplateColumns = w + "px";
}
}
/**
* Sets the chatbot widget height.
* @param e
*/
function fitToHeight(e) {
console.info("fit the chatbot widget to screen height", e);
var chatbotContainer = document.getElementById(selector);
var chatbotGrid = document.getElementById("fm-chatbot-grid");
var chatbotHeader = document.getElementById('fm-chatbot-header');
var chatbotFooter = document.getElementById('fm-chatbot-footer');
var viewportSize = getViewportSize();
console.debug("chatbot size", viewportSize);
var h;
if (e.matches) {
/* the viewport is MAX_HEIGHT pixels high or less */
console.debug("the viewport is " + MAX_HEIGHT + " pixels high or less", e);
h = viewportSize["height"] - chatbotHeader.offsetHeight - chatbotFooter.offsetHeight - 100;
console.debug("h,w,h,f", h, viewportSize["height"], chatbotHeader.offsetHeight, chatbotFooter.offsetHeight);
//chatbotGrid.style.gridTemplateColumns = w + "px";
//chatbotGrid.style.gridTemplateColumns = "auto";
chatbotGrid.style.gridTemplateRows = "auto " + h + "px auto";
//chatbotGrid.style.gridTemplateRows = "auto auto auto";
} else {
/* the viewport is more than than MAX_HEIGHT pixels high */
console.debug("the viewport is more than than " + MAX_HEIGHT + " pixels high", e);
h = MAX_HEIGHT - chatbotHeader.offsetHeight - chatbotFooter.offsetHeight;//viewportSize["height"] - 200;
console.debug("h,w,h,f", h, viewportSize["height"], chatbotHeader.offsetHeight, chatbotFooter.offsetHeight);
chatbotGrid.style.gridTemplateRows = "auto " + h + "px auto";
}
}
/**
* Issues intent /start to get the welcome message.
* @param args
*/
function welcome(args) {
console.info("getting the welcome message...");
var initPayload = DEFAULT_PAY_LOAD;
if (args.hasOwnProperty("initPayload") && args.initPayload.length) {
initPayload = args.initPayload;
}
call(initPayload, args);
}
function deleteCookie(name, path, domain) {
if (getCookie(name)) {
document.cookie = name + "=" +
((path) ? ";path=" + path : "") +
((domain) ? ";domain=" + domain : "") +
";expires=Thu, 01 Jan 1970 00:00:01 GMT";
}
console.debug("chatbot cookies", document.cookie);
}
function setCookie(name, value, days) {
var d = new Date();
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = name + "=" + value + ";" + expires + ";path=/";
console.debug("set the chatbot cookies", document.cookie);
}
function getCookie(name) {
console.debug("getting the chatbot cookies", document.cookie);
name += "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
/**
* Inits the chatbot widget.
* @param args
*/
function init(args) {
console.info("initializing the chatbot widget...")
addChatbotStyle(args);
//let position = getPosition(args);
var chatbotContainer = document.getElementById(selector);
chatbotContainer.style.position = "relative";
chatbotContainer.style.zIndex = "2";
chatbotContainer.style.fontFamily = DEFAULT_FONT_FAMILY;
chatbotContainer.style.position = "fixed";
chatbotContainer.style.bottom = "0";
chatbotContainer.style.right = "0";
// chatbotContainer.setAttribute("role", "region");
// chatbotContainer.setAttribute("aria-label", "Finestra del chatbot");
//<h1 id="tchat-title" class="sr-only">Finestra del chatbot</h1>
// chatbotContainer.style.bottom = position["bottom"] + "px";
// chatbotContainer.style.right = position["right"] + "px";
var chatbotButton = addAndGetChatbotButton(args);
var chatbotComponent = addAndGetChatbotComponent(args);
//todo set not visible when created
chatbotContainer.appendChild(chatbotButton);
chatbotContainer.appendChild(chatbotComponent);
var open = args.hasOwnProperty("open") ? args.open : true;
var isVisible = getCookie("is_visible");
//showChatbotSwitch(isVisible);
if (open && isVisible !== null && isVisible === "true") {
showChatbotComponent(args);
} else {
hideChatbotComponent(args);
}
var botInput = document.getElementById("fm-chatbot-input");
botInput.addEventListener("keyup", function (event) {
console.trace(event);
if (event.code === "Enter") {
// Cancel the default action, if needed
event.preventDefault();
submitMessage(args);
}
updateSubmitMessage();
});
var closeBtn = document.getElementById("fm-chatbot-close-btn");
closeBtn.onclick = function () {
hideChatbotComponent(args);
setCookie("is_visible", false, 90);
// toggleChatbotComponent()
};
var openBtn = document.getElementById("fm-chatbot-open-btn");
openBtn.onclick = function () {
showChatbotComponent(args);
setCookie("is_visible", true, 90);
};
var sendBtn = document.getElementById("fm-chatbot-send-btn");
sendBtn.onclick = function () {
submitMessage(args);
updateSubmitMessage();
};
}
/**
* Shows/hides the send button.
*/
function updateSubmitMessage() {
var botInput = document.getElementById("fm-chatbot-input");
var sendBtn = document.getElementById("fm-chatbot-send-btn");
//console.debug("input",botInput.value);
if (botInput.value.length === 0) {
sendBtn.style.visibility = "hidden";
sendBtn.setAttribute("aria-hidden", "true");
} else {
sendBtn.style.visibility = "visible";
sendBtn.setAttribute("aria-hidden", "false");
}
}
/**
* Dynamically sets the chatbot style.
*/
function addChatbotStyle(args) {
console.info("adding chatbot style...", args);
//Google fonts
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = "https://fonts.googleapis.com/icon?family=Material+Icons";
var head = document.getElementsByTagName('head')[0];
head.appendChild(link);
//.sr-only
// see https://a11y-guidelines.orange.com/en/web/components-examples/chatbot/
var srOnlyStyle = document.createElement('style');
//style.type = 'text/css';
srOnlyStyle.innerHTML = '.sr-only { position: absolute;\n' +
' width: 1px;\n' +
' height: 1px;\n' +
' padding: 0;\n' +
' margin: -1px;\n' +
' overflow: hidden;\n' +
' clip: rect(0,0,0,0);\n' +
' border: 0; }';
head.appendChild(srOnlyStyle);
// // .tooltip
// var tooltipStyle = document.createElement('style');
// tooltipStyle.innerHTML = '.tooltip {\n' +
// ' position: relative;\n' +
// ' display: inline-block;\n' +
// ' }';
//
// head.appendChild(tooltipStyle);
//
// var tooltipAndTextStyle = document.createElement('style');
// tooltipAndTextStyle.innerHTML = '.tooltip .tooltiptext1 {\n' +
// ' visibility: hidden;\n' +
// ' width: 200px;\n' +
// ' background-color: #F5F5F5;\n' +
// ' color: black;\n' +
// ' /*text-align: center;*/\n' +
// ' border-radius: 4px;\n' +
// ' padding: 5px;\n' +
// ' position: absolute;\n' +
// ' z-index: 1;\n' +
// ' bottom: 150%;\n' +
// ' right: 0%;\n' +
// ' margin-left: -120px;\n' +
// ' opacity: 0;\n' +
// ' transition: opacity 0.3s;\n' +
// ' text-align: left;\n' +
// ' font-size: 0.8em;\n' +
// ' padding: 5px;\n' +
// ' }';
//
//
// head.appendChild(tooltipAndTextStyle);
//
// var tooltipAndTextAfterStyle = document.createElement('style');
// tooltipAndTextAfterStyle.innerHTML = '.tooltip .tooltiptext1::after {\n' +
// ' content: "";\n' +
// ' position: absolute;\n' +
// ' top: 100%;\n' +
// ' right: 10%;\n' +
// ' /*margin-left: -5px;*/\n' +
// ' border-width: 5px;\n' +
// ' border-style: solid;\n' +
// ' border-color: #F5F5F5 transparent transparent transparent;\n' +
// ' }';
//
//
// head.appendChild(tooltipAndTextAfterStyle);
//
// var tooltipHoverAndTextStyle = document.createElement('style');
// tooltipHoverAndTextStyle.innerHTML = '.tooltip:hover .tooltiptext1 {\n' +
// ' visibility: visible;\n' +
// ' opacity: 1;\n' +
// ' }';
//
//
// head.appendChild(tooltipHoverAndTextStyle);
}
/**
* Returns the viewport size.
* @returns {{width, height}}
*/
function getViewportSize() {
var e = window;
var a = 'inner';
if (!('innerWidth' in window)) {
a = 'client';
e = document.documentElement || document.body;
}
return {width: e[a + 'Width'], height: e[a + 'Height']};
}
/**
* Creates and returns the chatbot component.
* @param args
* @returns {HTMLDivElement}
*/
function addAndGetChatbotComponent(args) {
console.info("adding the chatbot component...", args);
//let dimensions = getDimensions(args);
var chatbotComponent = document.createElement('div');
chatbotComponent.id = "fm-chatbot-container";
// chatbotContainer.style.position = "fixed";
// chatbotContainer.style.bottom = "161px";
// chatbotContainer.style.right = "20px";
chatbotComponent.style.background = "transparent";
chatbotComponent.style.borderRadius = "4px 4px 4px 4px";
chatbotComponent.style.boxShadow = "0 0 5px 2px rgba(0,0,0,.15)";
chatbotComponent.setAttribute("role", "region");
chatbotComponent.setAttribute("aria-labelledby", "fm-chatbot-title");
var chatbotGrid = document.createElement('div');
chatbotGrid.id = "fm-chatbot-grid";
chatbotGrid.style.display = "grid";
chatbotGrid.style.borderStyle = "none";
// chatbotGrid.style.gridTemplateColumns = dimensions["width"] + "px";
// chatbotGrid.style.gridTemplateRows = "60px " + dimensions["height"] + "px 70px";
chatbotGrid.style.background = "transparent";
var chatbotHeader = document.createElement('div');
chatbotHeader.id = "fm-chatbot-header";
chatbotHeader.style.background = "#3980E8";
chatbotHeader.style.color = "white";
chatbotHeader.style.borderRadius = "4px 4px 0 0";
chatbotHeader.style.padding = "10px";
chatbotHeader.style.display = "grid";
chatbotHeader.style.borderStyle = "none";
chatbotHeader.style.gridTemplateColumns = "90% 10%";
chatbotHeader.style.gridTemplateRows = "auto auto";
// chatbotHeader.style.gridTemplateColumns = "80%";
// chatbotHeader.style.gridTemplateRows = "50% 25% 25%";
var chatbotCloseButton = document.createElement('button');
chatbotCloseButton.id = "fm-chatbot-close-btn";
//chatbotCloseButton.style.visibility = "hidden";
chatbotCloseButton.type = "button";
if (args.hasOwnProperty("closeTooltip") && args.closeTooltip.length > 0) {
chatbotCloseButton.title = args.closeTooltip;
//Used by Bootstrap
chatbotCloseButton.setAttribute("data-toggle", "tooltip");
}
chatbotCloseButton.style.border = "none";
chatbotCloseButton.style.color = "white";
chatbotCloseButton.style.background = "transparent";
chatbotCloseButton.style.position = "relative";
//chatbotCloseButton.style.float = "right";
//chatbotCloseButton.style.textAlign = "center";
//chatbotCloseButton.style.verticalAlign = "center";
chatbotCloseButton.style.cursor = "pointer";
//chatbotCloseButton.style.float = "right";
chatbotCloseButton.innerHTML = "<span class=\"material-icons\" style=\"font-size:24px;\">close</span>";
chatbotCloseButton.setAttribute("aria-label", "Chiudi il chatbot");
//chatbotCloseButton.appendChild(chatbotSendButton);
var chatbotTitle = document.createElement('h1');
chatbotTitle.id = "fm-chatbot-title";
chatbotTitle.style.margin = "0";
chatbotTitle.style.padding = "0";
chatbotTitle.style.fontSize = "1.1em";
chatbotTitle.style.fontWeight = "bolder";
if (args.hasOwnProperty("title")) {
// title + close
//chatbotTitle.innerHTML = "<span style='font-size: 1.1em;font-weight: bolder'>" + args["title"] + "</span>" + "<button type='button'><span id=\"fm-chatbot-close-btn\" class=\"material-icons\" style=\"cursor: pointer; float: right;font-size:24px;\">close</span></button>";
chatbotTitle.innerHTML = "<span>" + args.title + "</span>";
}
// chatbotTitle.style.fontSize = "1.1em";
// chatbotTitle.style.fontWeight = "bolder";
var chatbotSubtitle = document.createElement('h2');
chatbotSubtitle.id = "fm-chatbot-subtitle";
chatbotSubtitle.style.margin = "0";
chatbotSubtitle.style.padding = "0";
chatbotSubtitle.style.fontSize = "0.8em";
chatbotSubtitle.style.fontWeight = "lighter";
//chatbotSubtitle.innerHTML = "Chiedi su vaccini, tamponi, quarantena…";
if (args.hasOwnProperty("subtitle")) {
//chatbotSubtitle.innerHTML = "Chiedi su vaccini, tamponi, quarantena…";
chatbotSubtitle.innerHTML = "<span>" + args.subtitle + "</span>";
}
//chatbotSubtitle.style.fontStyle = "italic";
chatbotSubtitle.style.fontWeight = "lighter";
chatbotSubtitle.style.fontSize = "0.8em";
//chatbotSubtitle.style.color = "#e8e4c9";
chatbotSubtitle.style.whiteSpace = "nowrap";
chatbotSubtitle.style.overflow = "hidden";
chatbotSubtitle.style.textOverflow = "ellipsis";
// white-space: nowrap;
// overflow: hidden;
// text-overflow: ellipsis;
chatbotHeader.appendChild(chatbotTitle);
chatbotHeader.appendChild(chatbotCloseButton);
// chatbotHeader.appendChild(chatbotTitle);
chatbotHeader.appendChild(chatbotSubtitle);
var chatbotMain = document.createElement('div');
chatbotMain.id = "fm-chatbot-main-container";
chatbotMain.className = "fm-chatbot-main";
chatbotMain.style.background = "white";
//chatbotMain.style.color="gray";
chatbotMain.style.overflow = "scroll";
chatbotMain.style.padding = "10px";
chatbotMain.setAttribute("tabindex", "0");
chatbotMain.setAttribute("aria-live", "polite");
var chatbotFooter = document.createElement('div');
chatbotFooter.id = "fm-chatbot-footer";
//chatbotFooter.className = "fm-chatbot-footer";
chatbotFooter.style.background = "#F5F5F5";
chatbotFooter.style.color = "black";
chatbotFooter.style.padding = "10px";
chatbotFooter.style.borderRadius = "0 0 4px 4px";
var chatbotInput = document.createElement('textarea');
chatbotInput.id = "fm-chatbot-input";
//chatbotInput.className = "fm-chatbot-input";
chatbotInput.autocomplete = "off";
//chatbotInput.rows = 2;
//chatbotInput.cols = 26;
chatbotInput.style.width = "80%";
chatbotInput.style.height = "100%";
if (args.hasOwnProperty("inputTextFieldHint")) {
//chatbotInput.placeholder = "Fai una domanda";
chatbotInput.placeholder = args.inputTextFieldHint;
}
//chatbotInput.textContent = "posso fare il tampone privatamente?";
chatbotInput.style.background = "#F5F5F5";
chatbotInput.style.border = "none";
chatbotInput.style.cursor = "pointer";
chatbotInput.style.color = "black";
chatbotInput.style.fontSize = "0.9em";
chatbotInput.style.fontStyle = "normal";
chatbotInput.style.position = "relative";
chatbotInput.style.float = "left";
chatbotInput.style.textAlign = "left";
chatbotInput.style.verticalAlign = "auto";
chatbotInput.style.resize = "none";
chatbotInput.style.overflow = "hidden";
chatbotInput.style.outline = "none";
chatbotInput.style.fontFamily = DEFAULT_FONT_FAMILY;
chatbotInput.setAttribute("aria-label", "Messaggio da inviare");
chatbotFooter.appendChild(chatbotInput);
var chatbotSendButton = document.createElement('button');
chatbotSendButton.id = "fm-chatbot-send-btn";
chatbotSendButton.style.visibility = "hidden";
chatbotSendButton.type = "button";
chatbotSendButton.style.border = "none";
chatbotSendButton.style.color = "#3980E8";
chatbotSendButton.style.background = "transparent";
chatbotSendButton.style.position = "relative";
chatbotSendButton.style.float = "right";
chatbotSendButton.style.textAlign = "center";
chatbotSendButton.style.verticalAlign = "center";
chatbotSendButton.style.cursor = "pointer";
chatbotSendButton.innerHTML = "<span class=\"material-icons\" style=\"font-size:24px;\">send</span>";
chatbotSendButton.setAttribute("aria-label", "Invia il messaggio");
chatbotFooter.appendChild(chatbotSendButton);
chatbotGrid.appendChild(chatbotHeader);
chatbotGrid.appendChild(chatbotMain);
chatbotGrid.appendChild(chatbotFooter);
chatbotComponent.appendChild(chatbotGrid);
//chatbot.appendChild(chatbotContainer);
return chatbotComponent;
}
/**
* Creates and returns the chatbot button.
* @param args
* @returns {HTMLDivElement}
*/
function addAndGetChatbotButton(args) {
console.info("adding chatbot open button...", args);
var chatbotSwitchContainer = document.createElement('div');
chatbotSwitchContainer.id = "fm-chatbot-button-container";
//chatbotSwitchContainer.className = "tooltip";
// chatbotSwitchContainer.style.position = "relative";
// chatbotSwitchContainer.style.bottom = "0";//position["bottom"];
// chatbotSwitchContainer.style.right = "0";//position["right"];
//chatbotSwitchContainer.style.fontFamily = ""
//chatbotSwitchContainer.style.zIndex = "1";
var chatbotOpenButton = document.createElement('button');
chatbotOpenButton.id = "fm-chatbot-open-btn";
chatbotOpenButton.type = "button";
if (args.hasOwnProperty("tooltip") && args.tooltip.length > 0) {
chatbotOpenButton.title = args.tooltip;
//Used by Bootstrap
chatbotOpenButton.setAttribute("data-toggle", "tooltip");
}
chatbotOpenButton.style.border = "none";
chatbotOpenButton.style.color = "white";
chatbotOpenButton.style.background = "#3980E8";
//chatbotOpenButton.style.padding = "10px";
chatbotOpenButton.style.height = "56px";
chatbotOpenButton.style.width = "56px";
chatbotOpenButton.style.borderRadius = "50%";
//chatbotSwitchButton.style.position = "relative";
chatbotOpenButton.style.float = "right";
chatbotOpenButton.style.textAlign = "center";
chatbotOpenButton.style.verticalAlign = "center";
chatbotOpenButton.style.cursor = "pointer";
chatbotOpenButton.style.boxShadow = "0 0 5px 2px rgba(0,0,0,.15)";
chatbotOpenButton.setAttribute("aria-label", "Apri il chatbot");
chatbotOpenButton.innerHTML = "<span id=\"fm-chatbot-open-icon\" class=\"material-icons\" style=\"font-size:36px;\">smart_toy</span>";
// if (args.hasOwnProperty("tooltip") && args.tooltip.length > 0) {
// var chatbotOpenBtnTooltip = document.createElement('div');
// chatbotOpenBtnTooltip.className = "tooltiptext1";
// //chatbotOpenBtnTooltip.innerHTML = String.format("<span>{0}</span>", args["tooltip"]);
// chatbotOpenBtnTooltip.innerHTML = "<span>" + args.tooltip + "</span>";
// chatbotSwitchContainer.appendChild(chatbotOpenBtnTooltip);
// }
chatbotSwitchContainer.appendChild(chatbotOpenButton);
return chatbotSwitchContainer;
}
//todo remove
// if (!String.format) {
// String.format = function (format) {
// var args = Array.prototype.slice.call(arguments, 1);
// return format.replace(/{(\d+)}/g, function (match, number) {
// return typeof args[number] !== 'undefined' ? args[number] : match;
// });
// };
// }
/**
* Shows the chatbot component and hides the chatbot button.
* @param args
*/
function showChatbotComponent(args) {
console.info("showing the chatbot component...");
var chatbotContainer = document.getElementById("fm-chatbot-container");
var switchContainer = document.getElementById("fm-chatbot-button-container");
chatbotContainer.style.display = "block";
chatbotContainer.setAttribute("aria-hidden", "false");
switchContainer.style.display = "none";
switchContainer.setAttribute("aria-hidden", "true");
if (args.hasOwnProperty("onWidgetEvent")) {
args.onWidgetEvent.onChatOpen();
}
}
/**
* Hides the chatbot component and shows the chatbot button.
* @param args
*/
function hideChatbotComponent(args) {
console.info("hiding the chatbot component...");
var chatbotContainer = document.getElementById("fm-chatbot-container");
var switchContainer = document.getElementById("fm-chatbot-button-container");
chatbotContainer.style.display = "none";
chatbotContainer.setAttribute("aria-hidden", "true");
switchContainer.style.display = "block";
switchContainer.setAttribute("aria-hidden", "false");
if (args.hasOwnProperty("onWidgetEvent")) {
args.onWidgetEvent.onChatClose();
}
}
/**
* Shows and sends the user message.
* @param args
*/
function submitMessage(args) {
var input = document.getElementById("fm-chatbot-input");
console.debug("sending input", input.value);
if (input.value) {
var message = input.value.trim();
if (message.length > 0) {
addUserInput(message);
call(message, args);
}
input.value = "";
}
}
/**
* Adds the user message to the chat thread.
* @param value
*/
function addUserInput(value) {
console.debug("showing user input", value);
var botMain = document.getElementById("fm-chatbot-main-container");
var div = document.createElement('div');
div.className = "user-input";
div.style.background = "#3980E8";
div.style.color = "white";
div.style.borderRadius = "4px 4px 4px 4px";
div.style.margin = "10px 10px 10px 40px";
div.style.padding = "10px";
div.style.wordWrap = "break-word";
div.style.fontSize = "0.9em";
//div.innerHTML = "<span>" + value + "</span>";
div.innerHTML = "<span class=\"sr-only\">Io dico:</span>" + value;
botMain.appendChild(div);
botMain.scrollTop = botMain.scrollHeight;
}
/**
* Adds the bot message to the chat thread.
* @param value
*/
function addBotOutput(value) {
console.debug("showing bot output", value);
var botMain = document.getElementById("fm-chatbot-main-container");
var div = document.createElement('div');
div.style.background = "#F5F5F5";
div.style.color = "black";
div.style.borderRadius = "4px 4px 4px 4px";
div.style.margin = "10px 40px 10px 10px";
div.style.padding = "10px";
div.style.wordWrap = "break-word";
div.style.fontSize = "0.9em";
div.className = "bot-output";
// div.innerHTML = "<span>" + value + "</span>";
div.innerHTML = "<span class=\"sr-only\">Covibot dice:</span>" + value;
botMain.appendChild(div);
botMain.scrollTop = botMain.scrollHeight;
}
/**
* Generates a uniq session id.
*/
function IDGenerator() {
this.length = 8;
this.timestamp = +new Date();
var _getRandomInt = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
this.generate = function () {
//console.info("getting a new SID...");
var ts = this.timestamp.toString();
var parts = ts.split("").reverse();
var id = "0ES5V111-";
for (var i = 0; i < this.length; ++i) {
var index = _getRandomInt(0, parts.length - 1);
id += parts[index];
}
return id;
};
}
/**
* Calls the Rasa's rest endpoint.
* @param value
* @param args
*/
//time curl -s -w "\n" -XPOST https://rasa5007.pokedem.com/webhooks/rest/webhook -H "Content-Type: application/json" -H "Accept-Charset: UTF-8" -d '{"sender": "user_240", "message": "scarica moduli per la prima dose"}'|jq .
function call(value, args) {
var data = {sender: UID, message: value};
console.debug("calling the chatbot rest endpoint...", data);
var delay = (typeof args.customMessageDelay === 'number') ? args.customMessageDelay : 0;
//
addWaitAnimation(200);
//console.debug("url", apiUrl);
fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept-Charset': 'UTF-8'
},
body: JSON.stringify(data),
})
.then(function (response) {
return response.json();
})
.then(function (data) {
console.debug('chatbot uttered', data);
//todo
setTimeout(function () {
if (data && data.length > 0) {
removeWaitAnimation();
for (var i = 0; i < data.length; i++) {
var output = replaceMarkdown(data[i].text);
console.trace("bot said", i, output);
addBotOutput(output);
args.onApiEvent.bot_uttered();
}
}
}, delay);
})
.catch(function (error) {
console.error('Error:', error);
//todo according to the error the bot could be hidden
removeWaitAnimation();
if (args.hasOwnProperty("hideWhenServiceNotAvailable") && args.hideWhenServiceNotAvailable) {
console.debug("hiding the chatbot components...");
hideChatbotComponent(args);
//todo remove the open button?
} else {
if (args.hasOwnProperty("serviceNotAvailableMessage") && args.serviceNotAvailableMessage.length > 0) {
addBotOutput(args.serviceNotAvailableMessage);
}
}
//todo try to connect again? or wait for a refresh?
}).finally(function () {
console.debug('chatbot call ended');
// removeWaitAnimation();
});
}
/**
* Starts the waiting state.
* @param speed
*/
function addWaitAnimation(speed) {
console.debug("adding wait animation...", speed);
speed = (typeof speed !== 'undefined') ? speed : 200;
var botMain = document.getElementById("fm-chatbot-main-container");
var div = document.createElement('div');
div.className = "fm-chatbot-wait-animation";
//div.style.verticalAlign= "center";
div.textContent = "Ooo";
// div.style.color = "gray";
// div.style.fontSize = "1.2em";
// div.style.letterSpacing = "0.5em";
// div.style.marginLeft = "10px";
div.style.background = "#F5F5F5";
div.style.color = "black";
div.style.borderRadius = "10px 10px 10px 10px";
div.style.margin = "10px 40px 10px 10px";
div.style.padding = "10px";
div.style.wordWrap = "break-word";
div.style.fontSize = "0.9em";
//div.textContent = "attendi..."
//div.innerHTML = "○●○●";
//div.innerHTML = "◯○○"
//div.innerHTML = ". . . ";
//div.innerHTML = "<span style='vertical-align: center;'>◯○○</span>"
botMain.appendChild(div);
botMain.scrollTop = botMain.scrollHeight;
// const element = document.getElementById("id");
var textNode = div.childNodes[0]; // assuming no other children
var text = textNode.data;
setInterval(function () {
text = text[text.length - 1] + text.substring(0, text.length - 1);
textNode.data = text;
}, speed);
}
var italicRegex = /\*([^*]+)\*/g;
var strongRegex = /\*\*([^*]+)\*\*/g;
var aRegex = /\[([^\]]+)]\(([^)]+)\)/g;
/**
* Replaces markdown with html tags.
* Currently, link and font style are supported.
* @param input
*/
function replaceMarkdown(input) {
return input.replace(strongRegex, '<strong>$1</strong>').replace(aRegex, '<a href="$2">$1</a>').replace(italicRegex, '<em>$1</em>');
}
/**
* Stops the waiting status
*/
function removeWaitAnimation() {
console.debug("removing wait animation...");
var waitAnimations = document.getElementsByClassName("fm-chatbot-wait-animation");
for (var i = 0; i < waitAnimations.length; i++) {
waitAnimations[i].remove();
}
}
}