Konfigurace vlastní mikrostránky
Vlastní mikrostránky slouží jako samostatné vstupní brány pro klienty do aplikace mluvii, svou funkčností jde v podstatě o velké widgety. Postup tvorby vyžaduje nastavit WebChat widget, vytvořit HTML dokument, přidat CSS styly, přidat Javascript a uložit stránku na libovolný hosting podporující protokol HTTPS.
Pro svou jednoduchost, tak jako v jiných návodech, budeme používat codepen.io. Začít můžete zde.
Nastavení konfiguračního balíčku
V administraci aplikace v sekci WebChat si vytvoříte nový / upravíte stávající WebChat widget. WebChat tlačítko nastavíte na "žádné tlačítko" - tím se vám tlačítko nebude zobrazovat, nicméně všechny funkcionality s tlačítkem spojené vám budou k dispozici. Nastavení chatovacího okna je libovolné.
Postup tvorby
V tomto návodu si můžete vytvořit mikrostránku pro Callback/Pozvánku, příp. chat a AV hovor, která bude umět připojit uživatele do aplikace mluvii, budou umět zobrazit stav tlačítka a pracovat s parametry hovorů (přednastavenými i vlastními parametry). Konečná podoba bude následující (Live verze zde):
Vytvoření HTML souboru
HTML dokument je následující. Použité obrázky jsou uloženy na github stránkách, kde celou mikrostránku nakonec uložíte.
Přidání CSS stylů
Přidání Javascriptu
Javascriptem přivedete vaší mikrostránku k životu. Nejdříve vložíte kód vašeho konfiguračního balíčku.
(function () {
var scr = document.createElement('script'); scr.type = 'text/javascript'; scr.async = true; scr.charset = 'UTF-8';
scr.src = '//app.mluvii.com/widget/OOWidget.js';
scr.$owidgetOnLoad = function (owidget) {
if (!owidget.isSupported) { return; }
owidget.init('295b1064-cf5b-4a5d-9e05-e7a74f86ae5e', 'navodMicroSite');
owidget.connectToServer();
};
var ffs = document.getElementsByTagName('script')[0]; ffs.parentNode.insertBefore(scr, ffs);
})();
Do funkce $owidgetOnLoad vložíme téměř celý náš javascriptový kód:
scr.$owidgetOnLoad = function (owidget) {
// Náš kód
};
Indikace stavu balíčku
Jako první začněte s indikací stavu balíčku, tedy to, zdali jsou operátoři přiřazení k danému WebChat widgetu online, zaneprázdnění nebo offline. A to touto funkcí:
owidget.setStatusUpdateCallback()
Tato funkce bere jako parametr callback funkci, která bude volána pokaždé, kdy ze serveru přijdou informace o stavu operátorů. Tento callback bere parametr code
, tedy číslo 0 v případě, že operátoři jsou offline, 1 - v případě, že jsou online a 2 - v případě zaneprázdnění.
Kód funkce $owidgetOnLoad bude zatím vypadat takto:
if (!owidget.isSupported) { return; }
owidget.init('295b1064-cf5b-4a5d-9e05-e7a74f86ae5e', 'navodMicroSite');
let widgetOnline = true;
owidget.setStatusUpdateCallback(function(code) {
const statusIndicatorImage = document.getElementById('StatusIndicatorCore-imageSelf');
const statusIndicatorText = document.getElementById('StatusIndicatorCore-textSelf');
switch(code) {
case 0:
statusIndicatorImage.src = 'Images/ikonka_konverzace-01_offline.png';
statusIndicatorText.innerText = 'Jsme offline';
statusIndicatorText.style.color = '#bf464f';
widgetOnline = false;
break;
case 1:
statusIndicatorImage.src = 'Images/ikonka_konverzace-01_online.png';
statusIndicatorText.innerText = 'Jsme online';
statusIndicatorText.style.color = '#8dc63f';
widgetOnline = true;
break;
case 2:
statusIndicatorImage.src = 'Images/ikonka_konverzace-01_busy.png';
statusIndicatorText.innerText = 'Máme toho hodně';
statusIndicatorText.style.color = '#ffbb06';
widgetOnline = true;
break;
}
});
Input a WebChat widget aplikace
Dalším krokem je zprovoznění tlačítka pro vstup do aplikace mluvii. Nejprve se podívejme na variantu pro Callback/Pozvánku.
Na stránce máte input pro zadání čísla pozvánky nebo telefonního čísla a tlačítko pro vstup do aplikace. Na tomto tlačítku budete naslouchat klepnutí, jakmile se tak stane, otevřeme velkou místnost aplikace mluvii, pokud nejsou všichni operátoři offline:
const widgetButton = document.getElementById('WidgetInput-button');
const widgetInput = document.getElementById('WidgetInput-input');
widgetButton.addEventListener('click', function() {
if(!widgetOnline) return; // tuto proměnnou deklarujeme a nastavujeme výše.
owidget.openApp('callshow', widgetInput.value);
}
Nyní přidáte validaci inputu regulárním výrazem, aby bylo možné na server posílat pouze šesti a devítimístná čísla a uživateli zobrazíte i zprávu o tomto stavu:
const hints = document.getElementById('Hints');
const regNumberLength6 = new RegExp('^\\d{6}$');
const regNumberLength9 = new RegExp('^\\d{9}$');
widgetButton.addEventListener('click', function() {
if(!widgetOnline) return; // tuto proměnnou deklarujete a nastavujete výše.
// V případě, že input neprošel jedním z našich testů, zobrazíte nápovědu
if(!regNumberLength6.test(widgetInput.value) || !regNumberLength9.test(widgetInput.value)) {
hints.classList.remove('isHidden');
}
// Pokud je číslo šestimístné, zahájíte Pozvánku v novém okně
if(regNumberLength6.test(widgetInput.value)) {
owidget.openApp('callshow', widgetInput.value)
}
// Pokud je číslo devítimístné, zahájíte callback v novém okně
if(regNumberLength9.test(widgetInput.value)) {
owidget.openApp('callback', widgetInput.value);
}
}
Případ pro callback musíte ještě poupravit a použít funkce:
owidget.numberNormalization(string)
// nebo
owidget.setCustomNumberNormalization(vaseNormalizacniFunkce);
První z funkcí je přednastavená normalizační funkce, která telefonnímu číslu přidá mezinárodní předčíslí a případně odstraní mezery apod.
Druhá funkce umožňuje přidat vlastní normalizační funkci, např. s vlastním mezinárodním číslem apod.
Otevření callbacku pak bude vypadat takto:
if(regNumberLength9.test(widgetInput.value)) {
owidget.numberNormalization(widgetInput.value)
const normalizedNumber = owidget.numberNormalization(widgetInput.value);
owidget.openApp('callback', normalizedNumber);
}
Abyste si byli jistí, že nápověda zmizí, jakmile uživatel zadá šesti nebo devítimístné číslo do inputu, vytvořte „event listener“ pro tento případ:
widgetInput.addEventListener('input', function() {
if(regNumberLength6.test(widgetInput.value) || regNumberLength9.test(widgetInput.value)) {
hints.classList.add('isHidden');
}
});
Tím máte základní funkčnost vaší mikrostránky zajištěnou.
Chat, videohovor
Pokud byste chtěli zákazníkům místo Callback/Pozvánky poskytovat služby chatu nebo AV hovoru, stačí k tomu ve vašem případě vyměnit funkci pro inicializaci Callbacku/Pozvánky za funkce pro inicializaci chatu, nebo AV hovoru. Můžete také odstranit input pro číslo pozvánky /telefonní číslo, jelikož tyto funkce daný parametr nepotřebují - s tím odstraníte i vaše testování vloženého čísla.
Inicializace chatu:
owidget.openChat();
Inicializace AV hovoru:
owidget.openApp("av");
„Event listener“ na tlačítku začít hovor by tedy v případě AV hovoru vypadal takto:
widgetButton.addEventListener('click', function() {
if(!widgetOnline) return;
owidget.openApp("av");
}
Vlastní parametry
Spolu s tel. číslem nebo číslem pozvánky můžete operátorům odeslat vlastní proměnné. Na mikrostránce jsme k tomuto účelu vytvořili input, který, bude-li vyplněn, pošle na server proměnnou (parametr hovoru). Kód vložíte před testy regulárními výrazy:
const nameInput = document.getElementById('inputName');
if(nameInput.value !== '') {
owidget.addCustomData('navod_clientName', nameInput.value);
}
Na mikrostránce můžete počítat i s dalšími libovolnými interakcemi, např. v podobě přihlášení /odhlášení uživatele. Za listenerem pro tlačítko „Začít hovor“ bychom vytvořili další listnery pro Login a Logout tlačítka, u kterých je předpoklad, že web má vlastní logiku autentizace uživatelů. V momentě zdařilé autentizace /odhlášení využijte funkcí mluvii:
const login = document.getElementById('login');
const logout = document.getElementById('logout');
login.addEventListener('click', function() {
// Logika autentizace zde, výsledek autentizace je přiřazené id uživatele, v callbacku autentizace bychom přidali naší funkci:
const foundUserId = 'as3d21sad351as-as1d';
owidget.addCustomData('navod_clientId', foundUserId);
});
logout.addEventListener('click', function() {
// Logika odhlášení zde, v callbacku odhlášení pak použijeme funkce:
owidget.removeCustomData('navod_clientId');
// owidget.clearCustomData();
});
Funkce owidget.removeCustomData si bere jako parametr název proměnné, kterou chcete smazat. Funkce owidget.clearCustomData() smaže všechny proměnné.
Javascript vaší mikrostránky nakonec vypadá následovně:
Publikace mikrostránky
Pokud jste při tvorbě vlastního Pop-upu využili codepen.io, je nyní potřeba Pop-up exportovat. Klikněte na tlačítko „Save“, poté exportujte v „.zip“ formátu:
Vytvořený pop-up můžete uložit buď jako podstránku vašeho webu, nebo využít jakýkoliv webhosting, např. Github stránky.
Pokud jste využili textového editoru, výsledná stránka bude vypadat následovně:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
<title>Document</title>
<style>
body {
background-image: linear-gradient(to right, #6ca6bd, #8dc63f);
font-size: Raleway;
}
html, body {
margin: 0;
padding: 0;
}
input, button, p, label {
font-family: Raleway;
}
.Logo {
position: absolute;
width: 25%;
margin: 20px;
min-width: 200px;
}
.Page {
display: flex;
width: 100%;
height: 100vh;
align-items: center;
justify-content: center;
}
.Frame {
background-color: white;
width: 450px;
height: 350px;
border-radius: 10px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.StatusIndicator {
flex: 3;
display: flex;
flex-direction: row;
justify-content: center;
}
.StatusIndicatorCore {
width: 300px;
display: flex;
}
.StatusIndicatorCore-image {
flex: 3;
display: flex;
align-items: center;
}
.StatusIndicatorCore-image>img {
max-height: 100%;
max-width: 100%;
}
.StatusIndicatorCore-text {
flex: 7;
display: flex;
align-items: center;
}
#StatusIndicatorCore-textSelf {
font-size: 35px;
font-family: Raleway;
font-weight: bold;
color: #8dc63f;
text-align: center;
margin: 0;
}
.WidgetInput {
width: 100%;
flex: 7;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
}
#WidgetInput-input {
width: 60%;
height: 40px;
border-radius: 8px;
border: 1px solid #6ca6bd;
font-size: 20px;
text-align: center;
color: #8dc63f;
margin-bottom: 10px;
box-sizing: border-box;
}
#WidgetInput-input:focus, #WidgetInput-button:focus, .LoginButtons:focus {
outline: 0;
border: 2px solid #6ca6bd;
}
#WidgetInput-button {
width: 60%;
border-radius: 8px;
border: 1px solid #6ca6bd;
background-color: #8dc63f;
transition: all 0.3s;
color: #fff;
height: 40px;
font-size: 20px;
margin-bottom: 20px;
}
#WidgetInput-button:hover, .LoginButtons:hover {
background-color: #6ca6bd;
}
#Hints {
position: absolute;
bottom: 0;
background-color: #bf464f;
color: white;
width: 100%;
padding: 10px 8px;
text-align: center;
box-sizing: border-box;
margin: 0;
transition: all ease-out 0.3s;
}
#Hints.isHidden {
transform: translateY(100%);
}
.CustomVariables {
position: absolute;
bottom: 0;
margin: 0 auto;
height: 50px;
width: 800px;
border-radius: 10px 10px 0 0;
background-color: #fff;
display: flex;
flex-direction: row;
align-content: center;
}
.CustomVariables-input {
flex: 1;
text-align: center;
}
.CustomVariables-input:first-of-type {
flex: 2;
}
.CustomInput {
width: 250px;
height: 30px;
border-radius: 8px;
border: 1px solid #6ca6bd;
font-size: 18px;
text-align: center;
color: #8dc63f;
box-sizing: border-box;
margin: 10px 0;
margin-left: 5px;
outline: 0;
}
.CustomInput:focus {
border: 2px solid #6ca6bd;
}
label {
font-size: 20px;
color: #5b5b5b;
}
.LoginButtons {
width: 150px;
border-radius: 8px;
border: 1px solid #6ca6bd;
background-color: #8dc63f;
transition: all 0.3s;
color: #fff;
height: 30px;
font-size: 20px;
margin: 10px 0;
}
</style>
</head>
<body>
<img src="Images/logo-transparent-no-safezone.png" alt="" class="Logo">
<div class="Page">
<div class="Frame">
<div class="StatusIndicator">
<div class="StatusIndicatorCore">
<div class="StatusIndicatorCore-image">
<img id="StatusIndicatorCore-imageSelf" src="Images/ikonka_konverzace-01_online.png" alt="">
</div>
<div class="StatusIndicatorCore-text">
<p id="StatusIndicatorCore-textSelf">
Jsme online
</p>
</div>
</div>
</div>
<div class="WidgetInput">
<p id="Hints" class="isHidden">Zadejte prosím devítimístné telefonní číslo nebo šestímístné číslo pozvánky.</p>
<input type="text" id="WidgetInput-input" placeholder="Telefon / č. pozvánky">
<button id="WidgetInput-button">Začít hovor</button>
</div>
</div>
<div class="CustomVariables">
<div class="CustomVariables-input">
<label for="inputName">Jméno:</label>
<input type="text" class="CustomInput" id="inputName">
</div>
<div class="CustomVariables-input">
<button class="LoginButtons" id="login">Login</button>
</div>
<div class="CustomVariables-input">
<button class="LoginButtons" id="logout">Logout</button>
</div>
</div>
</div>
<script type="text/javascript">
(function () {
var scr = document.createElement('script'); scr.type = 'text/javascript'; scr.async = true; scr.charset = 'UTF-8';
scr.src = '//app.mluvii.com/widget/OOWidget.js';
scr.$owidgetOnLoad = function (owidget) {
if (!owidget.isSupported) { return; }
owidget.init('295b1064-cf5b-4a5d-9e05-e7a74f86ae5e', 'navodMicroSite');
let widgetOnline = true;
owidget.setStatusUpdateCallback(function(code) {
const statusIndicatorImage = document.getElementById('StatusIndicatorCore-imageSelf');
const statusIndicatorText = document.getElementById('StatusIndicatorCore-textSelf');
switch(code) {
case 0:
statusIndicatorImage.src = 'Images/ikonka_konverzace-01_offline.png';
statusIndicatorText.innerText = 'Jsme offline';
statusIndicatorText.style.color = '#bf464f';
widgetOnline = false;
break;
case 1:
statusIndicatorImage.src = 'Images/ikonka_konverzace-01_online.png';
statusIndicatorText.innerText = 'Jsme online';
statusIndicatorText.style.color = '#8dc63f';
widgetOnline = true;
break;
case 2:
statusIndicatorImage.src = 'Images/ikonka_konverzace-01_busy.png';
statusIndicatorText.innerText = 'Máme toho hodně';
statusIndicatorText.style.color = '#ffbb06';
widgetOnline = true;
break;
}
});
const widgetButton = document.getElementById('WidgetInput-button');
const widgetInput = document.getElementById('WidgetInput-input');
const hints = document.getElementById('Hints');
const nameInput = document.getElementById('inputName');
const login = document.getElementById('login');
const logout = document.getElementById('logout');
const regNumberLength6 = new RegExp('^\\d{6}$');
const regNumberLength9 = new RegExp('^\\d{9}$');
widgetButton.addEventListener('click', function(e) {
if(!widgetOnline) return;
if(nameInput.value !== '') {
owidget.addCustomData('navod_clientName', nameInput.value);
}
if(!regNumberLength6.test(widgetInput.value) || !regNumberLength9.test(widgetInput.value)) {
hints.classList.remove('isHidden');
}
if(regNumberLength6.test(widgetInput.value)) {
owidget.openApp('callshow', widgetInput.value)
}
if(regNumberLength9.test(widgetInput.value)) {
owidget.numberNormalization(widgetInput.value)
const normalizedNumber = owidget.numberNormalization(widgetInput.value);
owidget.openApp('callback', normalizedNumber);
}
});
widgetInput.addEventListener('input', function() {
if(regNumberLength6.test(widgetInput.value) || regNumberLength9.test(widgetInput.value)) {
hints.classList.add('isHidden');
}
});
login.addEventListener('click', function() {
const foundUserId = 'as3d21sad351as-as1d';
owidget.addCustomData('navod_clientId', foundUserId);
});
logout.addEventListener('click', function() {
owidget.removeCustomData('navod_clientId');
// owidget.clearCustomData();
});
owidget.connectToServer();
};
var ffs = document.getElementsByTagName('script')[0]; ffs.parentNode.insertBefore(scr, ffs);
})();
</script>
</body>
</html>
Last updated
Was this helpful?