|
|
|
**Die Autoren dieser Wiki-Unterseite:**
|
|
|
|
|
|
|
|
-S- aka Steffen Hähnle
|
|
|
|
|
|
|
|
-E- aka Emanuel Geiger
|
|
|
|
|
|
|
|
-D- aka Dina Kurbanismailova
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-----
|
|
|
|
|
|
|
|
|
|
|
|
## Inhalt
|
|
|
|
|
|
|
|
#### | 1 | [Einführung](#1--einführung)
|
|
|
|
#### | 2 | [Bedienelemente](#2--bedienelemente)
|
|
|
|
#### | 3 | [Framework - Dialogflow](#3--framework---dialogflow)
|
|
|
|
#### | 3.1 | [Auswahl des Frameworks](#31-auswahl-des-frameworks)
|
|
|
|
#### | 3.1.1 | [Allgemeine Auswahlkriterien für ein Chatbot Framework](#311-allgemeine-auswahlkriterien-für-ein-chatbot-framework)
|
|
|
|
#### | 3.1.2 | [Spezielle Kriterien für Dialogflow](#312-spezielle-kriterien-für-dialogflow)
|
|
|
|
#### | 3.2 | [Einführung in Dialogflow](#32-einführung-in-dialogflow)
|
|
|
|
#### | 3.3 | [Intents](#33-intents)
|
|
|
|
#### | 3.4 | [Entities](#34-entities)
|
|
|
|
#### | 3.5 | [Training](#35-training)
|
|
|
|
#### | 3.5.1 | [Wie trainiert man den Chatbot?](#351-wie-trainiert-man-den-chatbot)
|
|
|
|
#### | 3.6 | [Schnittstelle zu Accelerator](#36-schnittstelle-zu-accelerator)
|
|
|
|
#### | 4 | [Funktionalitäten](#4--funktionalitäten)
|
|
|
|
#### | 4.1 | [Bilinguale Sprachausgabe](#41-bilinguale-sprachausgabe)
|
|
|
|
#### | 4.2 | [Default Intent](#42-default-intent)
|
|
|
|
#### | 4.3 | [Small Talk](#43-small-talk)
|
|
|
|
#### | 4.3.1 | [Aufbau des Dialogs](#431-aufbau-des-dialogs)
|
|
|
|
#### | 4.3.2 | [*Contexts* im Small Talk](#432-contexts-im-small-talk)
|
|
|
|
#### | 4.3.3 | [Import des Small-Talk-Agenten](#433-import-des-small-talk-agenten)
|
|
|
|
#### | 4.3.4 | [Namenskonvention und Erweiterung mit neuen Intents](#434-namenskonvention-und-erweiterung-mit-neuen-intents)
|
|
|
|
#### | 4.4 | [Countdown](#44-countdown)
|
|
|
|
#### | 4.5 | [Random User List](#45-random-user-list)
|
|
|
|
#### | 4.6 | [Random User](#46-random-user)
|
|
|
|
#### | 4.7 | [Save Chat](#47-save-chat)
|
|
|
|
#### | 4.8 | [Chatbot als Accelerator-Guide (Guided Tour Schnittstelle)](#48-chatbot-als-accelerator-guide-guided-tour-schnittstelle)
|
|
|
|
#### | 4.9 | [E-Mail versenden - ToDo](#49-e-mail-versenden---todo)
|
|
|
|
#### | 4.10 | [Suchfunktion](#410-suchfunktion)
|
|
|
|
#### | 4.11 | [EasterEggs](#411-eastereggs)
|
|
|
|
#### | 4.11.1 | [Do a barrel roll](#4111-do-a-barrel-roll)
|
|
|
|
#### | 4.11.2 | [Cat Attack](#4112-cat-attack)
|
|
|
|
#### | 4.11.3 | [Destroy Page](#4113-destroy-page)
|
|
|
|
#### | 4.11.4 | [Upside Down](#4114-upside-down)
|
|
|
|
#### | 4.11.5 | ["Alexa" Easteregg](#4115-alexa-easteregg)
|
|
|
|
#### | 4.11.6 | [Easter Egg Verweis auf ELIZA](#4116-easter-egg-verweis-auf-eliza)
|
|
|
|
#### | 4.11.7 | [Badwords](#4117-badwords)
|
|
|
|
#### | 4.11.8 | [Intent mit viel "Wuff"](#4118-intent-mit-viel-wuff)
|
|
|
|
#### | 5 | [Systemarchitektur Chatbot](#5-systemarchitektur-chatbot)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 1 Einführung
|
|
|
|
Im Zuge des Moduls "Kollaborative Systeme" wurde im Verlaufe des Wintersemesters 2017/2018 ein Chatbot in das WebRTC-Tool "Accelerator" integriert. Die ursprüngliche Idee zur Implementierung eines Chatbots ging wohl durch den aktuellen Trend der Chatbots in den Weiten des Internets hervor. Beispielsweise findet man heutzutage Chatbots auf Social Media Plattformen wie Facebook, aber auch auf vielen Händler-Webseiten zur Unterstützung des Supports oder des Marketings, wie beispielsweise auf [Touchmagix.com](http://Touchmagix.com) (Letzter Zugriff: 27.01.2018). Die unterschiedlichen Einsatzgebiete zeigen, dass Chatbots Mehrwerte in diversen Anwendungsszenarien bringen. Dabei ist es jedoch wichtig, dass vor allem bei der Konzeption von den Funktionalitäten des Chatbots auf die Zielgruppe und den Anwendungsfall geachtet wird. Im Use-Case des WebRTC-Tools "Accelerator" wurden daher möglichst nur Funktionalitäten implementiert, die beispielsweise bei einem Webinar nützlich und unterstützend sein könnten und nicht zwingend vom eigentlichen Geschehen ablenken.
|
|
|
|
|
|
|
|
Man kann im Allgemeinen zwischen zwei Arten von Chatbots unterscheiden: So gibt es zum einen sprachgesteuerte und zum anderen textbasierte Chatbots. Einige namhafte Vertreter der sprachgesteuerten Chatbots sind zum Beispiel [Microsoft Cortana](http://support.microsoft.com/de-de/help/17214/windows-10-what-is) (Letzter Zugriff: 27.01.2018), [Google Assistant](https://assistant.google.com/intl/de_de/) (Letzter Zugriff: 27.01.2018) oder auch Amazon Echo mit der Stimme [Alexa](https://www.amazon.de/b?ie=UTF8&node=12775495031) (Letzter Zugriff: 27.01.2018). Bei der Konzeption eines Chatbots für den Anwendungsfall des WebRTC-Tools "Accelerator" haben wir uns für einen textbasierten Chatbot entschieden. Diese Entscheidung wurde aus einem technischen Blickwinkel getroffen: Für die Integration eines sprachbasierten Chatbots wird in den meisten Fällen ein externes Mikrofon benötigt, welches an den Laptop oder an den Rechner angeschlossen wird. Diese zusätzliche Hardware wird in diesem Falle benötigt, da es ansonsten zu Tonverzerrungen kommen kann, weil beispielsweise das integrierte Mikrofon des Laptops gleichzeitig als Ein- und Ausgang dienen würde. Dadurch wird das Sprachbild verzerrt, was dazu führen würde, dass nicht alle Sprachbefehle richtig identifiziert werden. Da jedoch nicht davon auszugehen ist, dass alle Teilnehmer eines Webinars über ein externes Mikrofon verfügen, haben wir uns für die textbasierte Variante entschieden.
|
|
|
|
|
|
|
|
Eine Hauptanforderung, die wir bei der Entwicklung des textbasierten Chatbots erfüllen wollten, war das Verständnis der natürlichen Sprache seitens des Chatbots. Eine Alternative zur Kommunikation des Chatbots mit natürlicher Sprache wäre eine Umsetzung, die von strikten Kommandos und Befehlen geprägt wird, welche ein Nutzer zur erfolgreichen Kommunikation exakt eingeben müsste. Initial war dies so umgesetzt, erwies sich jedoch prompt als ungeeignet, da hierdurch von Anwendern ein Set aus Befehlen und Kommandos gelernt werden müsste.
|
|
|
|
|
|
|
|
Die Abbildungen, des Frameworks Dialogflow sind Ausschnitte der [Dialogflow-Webseite](https://console.dialogflow.com/api-client/#/agent/007bcfaa-154a-420d-811c-c2ea089ab863/intents) (Letzter Zugriff 27.01.2018).
|
|
|
|
|
|
|
|
-S,E-
|
|
|
|
|
|
|
|
# 2 Bedienelemente
|
|
|
|
|
|
|
|
Der Chatbot kann durch das bestehende Chatfenster des Accelerators angesprochen werden. Da dieses Chat-Modul nicht nur ausschließlich zum Ansprechen des Chatbots, sondern auch zur textuellen Kommunikation der Teilnehmer und des Moderators eines Konferenzraums untereinander verwendet wird, wurde ein zusätzlicher Button implementiert, durch den der Chatbot an- oder ausgeschaltet werden kann. Dadurch wird einerseits die Situation vermieden, dass alle Teilnehmer sehen können, was ein Einzelner mit dem Chatbot kommuniziert - und andererseits antwortet der Chatbot nur dann, wenn dies auch vom jeweiligen Nutzer erwünscht ist.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 1: Chatbot-Button*
|
|
|
|
|
|
|
|
Der Button wurde innerhalb der Datei "index.html" definiert und in der "connect.js" und der "uiEvents.js" mit einer booleschen Variablen ("BotOnOff") (mit dichotomen Wertepaar: true/false) und einem Befehl verknüpft.
|
|
|
|
|
|
|
|
**Definition des Buttons in der index.html:**
|
|
|
|
```
|
|
|
|
<div class="btn-group contentOptions buttonToolbar buttonToolbar pull-right" role="group" aria-label="...">
|
|
|
|
<button id="chatbotBtn" type="button" title="Chatbot enable/disable" class="keepActiveBtn toolbar-icon btn btn-default">
|
|
|
|
<img style="max-width: 25px;" src="./img/Chatbot_Icon.png" alt="icon">
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Verknüpfung des Befehls mit dem Button in der uiEvents.js**
|
|
|
|
```
|
|
|
|
$("#chatbotBtn").click(function() {
|
|
|
|
if(!BotOnOff) {
|
|
|
|
sendChatMsg("Hi Chatbot");
|
|
|
|
} else {
|
|
|
|
sendChatMsg("Bye Chatbot");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
**Verknüpfung des Befehls mit der Variablen in der connect.js**
|
|
|
|
```
|
|
|
|
if(msg == "Hi Chatbot") {
|
|
|
|
BotOnOff = true;
|
|
|
|
$("#chatbotBtn").addClass("active alert-danger");
|
|
|
|
writeToChat("Chatbot", "Wie kann ich Ihnen weiterhelfen?");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(msg == "Bye Chatbot") {
|
|
|
|
BotOnOff = false;
|
|
|
|
$("#chatbotBtn").removeClass("active alert-danger");
|
|
|
|
writeToChat("Chatbot", "Tschüss");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Wird der Button betätigt oder wird in den Chat "Hi Chatbot" geschrieben, so wird die boolesche Variable auf den Wert "true" gesetzt. Wird der Button ein weiteres Mal betätigt oder wird in den Chat "Bye Chatbot" geschrieben, so setzt sich der Wert der Variablen auf "false". Alle Funktionalitäten, die angelegt wurden, sind entsprechend mit der Variablen verknüpft, so dass diese nur bei dem Wert "true", folglich wenn der Chatbot aktiv geschaltet ist, genutzt werden können.
|
|
|
|
|
|
|
|
Da es in den vorinstallierten Schriftarten (beispielsweise FontAwesome) kein geeignetes Symbol bzw. Icon gab, das mit einem Chatbot assoziiert werden könnte, wurde in der Icon-Produktion selbst Hand angelegt. Mithilfe einer kommerziell nutzbaren Software wurde ein schlichtes Icon für einen Chatbot erstellt. Um der Flat Design Methodik treu zu bleiben, die auch bei den anderen bereits verwendeten Icons und Buttons im Accelerator vorgefunden werden konnte, wurde das Icon mit schlichten Standard-Formen umgesetzt. Auf besondere Effekte, wie dreidimensionale Darstellungen, Schattenwürfe oder starken Details, wie es in der Design-Methodik des Skeuomorphismus häufig vorkommt, wurde verzichtet. Die folgende Abbildung zeigt die verwendete Endversion des Chatbot-Icons.
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 2: Chatbot-Icon*
|
|
|
|
|
|
|
|
Die Datei, in der das Icon für den Chatbot erstellt wurde, wurde im Google Drive Account des Chatbots abgelegt und kann von dort aus bearbeitet werden. Zugriff unter folgendem Link: [Google-Drive Chatbot - Icon Produktion](https://drive.google.com/open?id=1iONQZIGr-cEfqI11nYehY-r3efsU38QH) (Letzter Zugriff 27.01.2018)
|
|
|
|
|
|
|
|
-S-
|
|
|
|
# 3 Framework - Dialogflow
|
|
|
|
|
|
|
|
## 3.1 Auswahl des Frameworks
|
|
|
|
### 3.1.1 Allgemeine Auswahlkriterien für ein Chatbot Framework
|
|
|
|
|
|
|
|
Folgende Kriterien waren für uns wichtig:
|
|
|
|
* Bilinguale Sprache muss mit dem Framework möglich sein.
|
|
|
|
* Einfache Integration in dem Accelerator Code.
|
|
|
|
* Anbindung an eine Node.js Schnittstelle muss vorhanden sein.
|
|
|
|
* JavaScript als Programmiersprache muss vorhanden sein.
|
|
|
|
* Das Framwork muss kostenlos zur Verfügung stehen.
|
|
|
|
* Eine Vielzahl von unterschiedlichen Schnittstellen (wie Slack) soll ansprechbar sein.
|
|
|
|
* Einfaches Testen innerhalb des Frameworks muss möglich sein.
|
|
|
|
|
|
|
|
### 3.1.2 Umsetzung der Kritierien in Dialogflow
|
|
|
|
|
|
|
|
In der folgenden Liste haben wir die allgemeinen Kriterien in Dialogflow überprüft.
|
|
|
|
* Einfache Integration --> Code kann als JSON Datei exportiert und wieder in andere Dialogflow Projekte importiert werden.
|
|
|
|
* Bilinguale Sprachausgabe kann realisiert werden.
|
|
|
|
* Befehle können mit JavaScript gesendet und empfangen werden.
|
|
|
|
* Node.JS Schnittstelle liegt vor.
|
|
|
|
* Dialogflow ist kostenlos, da es sich noch in der Beta Phase befindet.
|
|
|
|
* Eine Vielzahl an weiteren Schnittstellen ist vorhanden.
|
|
|
|
* Testen innerhalb des Frameworks ist möglich.
|
|
|
|
|
|
|
|
|
|
|
|
Für die Entwicklung des Chatbots haben wir uns für Dialogflow entschieden, da dieses Framework die oben beschriebenen Kriterien alle erfüllt. Mit Hilfe von Dialogflow wird eine textbasierte Ausgabe in sehr vielen verschiedenen Sprachen ermöglicht. Die Chatbot Daten liegen als JSON Datei vor und werden auch in Dialogflow intern als solche abgespeichert. Da der Output in Form einer JSON Datei vorliegt, kann man diesen relativ einfach mit Hilfe von JavaScript ansprechen und auslesen. Des Weiteren bietet Dialogflow eine Node.js Schnittstelle an. Da die Entwicklung von Dialogflow noch nicht abgeschlossen ist, beziehungsweise manche Tools noch weiter entwickelt werden, werden Teile des Frameworks kostenlos angeboten. Der einzige Aspekt, bei dem Kosten enstehen können, ist die Integrations eines Chatbot in einer Webseite über das Dialogflow System. Dialogflow bietet zwei Rubriken an, so gibt es zum einen die Rubrik "Dialogflow Standard Edition" und die "Dialogflow Enterprise Edition". Beide Versionen bieten eine unlimitierte Anzahl an textbasierter Ausgabe über den entwickelten Chatbot an. Bei der Standardversion, die wir nutzen, werden lediglich drei Abfragen pro Sekunde zugelassen und auch bei der sprachbasierten Bedienung liegt eine Limitation vor. So dürfen hierbei lediglich 1000 Abfragen pro Tag gestellt werden und insgesamt nur 15. 0000 pro Monat. Da wir jedoch einen textbasierten Chatbot implementiert haben und wir in den meisten Fällen nicht mehr als drei Abfragen pro Sekunde an das System stellen, ist für dieses Projekt die Standardversion sehr gut geeignet. Mit Hilfe von Dialogflow wird die natürliche textbasierte Sprache simmuliert. So werden falsch geschriebene Wörter dem richtig gemeinten Wort zugewiesen, was dazu führt, dass die Ausgabe wiederrum funktioniert. Dialogflow unterstütz seit der aktuellen Version auch die Spracheingabe. Dies wurde mit Hilfe des Tools Google Assistant ermöglicht. Weiterhin haben wir darauf geachtet, welche weiteren Schnittstellen oder Anbindungen das Framework bietet. Dialogflow bietet eine Vielzahl von Integrationen in andere Tools, wie beispielsweise Microsoft Cortana, Slack, Amazon Alexa, Facebook Messenger, Skype. Mit diesen Tools kann man den Chatbot in einem weiteren Schritt verknüpfen, was die Anzahl an möglichen Umsetzungen erweitert. Dialogflow hebt sich von den anderen Frameworks dahingehend ab, dass man die verschiedenen Dialoge auf der Webseite ausprobieren kann. Diesen Service haben nicht alle Frameworks unterstützt. Dies reduziert die mögliche Fehlersuche innerhalb des geschriebenen Codes deutlich. Diese Gründe haben dazu geführt das wir uns für Dialogflow entschieden haben.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 3: Preistabelle dialogflow*
|
|
|
|
Quelle: https://cloud.google.com/dialogflow-enterprise/docs/editions (Letzter Zugriff 27.01.2018)
|
|
|
|
|
|
|
|
-E-
|
|
|
|
## 3.2 Einführung in Dialogflow
|
|
|
|
|
|
|
|
Unter Dialogflow (früher: Api.ai) versteht sich ein Programmiergerüst, das im WebRTC-Tool "Accelerator" eingesetzt wird, um dem darin integrierten Chatbot eine künstliche Intelligenz zu verleihen. Die Intelligenz besteht einerseits darin, dass man mit dem Chatbot nicht nur per Kommandos und Befehlen kommunizieren kann, sondern dass der Chatbot auch natürliche Sprache versteht und daraufhin entsprechend agieren (bzw. Funktionen ausführen) kann, andererseits dass der Chatbot zum Erkennen der natürlichen Sprache trainiert werden kann und dadurch lernt. Die darin verborgenen Grundmechaniken gehen auf das sogenannte Natural Language Processing (kurz: NLP) zurück. Ein Großteil aller Frameworks, die natürliche Sprache in Kommandos und Befehle übersetzen können, suchen in der Regel bei eingegebenen oder eingesprochenen Nutzertexten nach sogenannten Intents und Entities.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 4: Intents und Entities*
|
|
|
|
|
|
|
|
Während bei Intents die Absichten des Nutzers entarnt werden sollen, sind es bei den Entities die Entschlüsselungen der Objekte, um die es gehen soll. Auch bei Dialogflow gibt es sogenannte Intents und Entities, auf die in den nachfolgenden Kapiteln eingegangen wird.
|
|
|
|
|
|
|
|
Um sich Zugang zu Dialogflow zu verschaffen, benötigt man lediglich nur die Zugangsdaten zu dem für den Chatbot angelegten Google-Account. Aktuell werden diese Daten, sowie auch andere (streng-) vertrauliche Daten und Dokumente des Projektes von Raphael Fritsch verwaltet.
|
|
|
|
|
|
|
|
-S-
|
|
|
|
## 3.3 Intents
|
|
|
|
Mit Hilfe des in Abbildung 5 gezeigten Auswahlmenüs gelangt man zu den Intents. Mit Intents wird in Dialogflow ein Dialog simuliert. Ein Dialog beginnt immer damit, dass der Anwender anfängt mit dem Chatbot zu kommunzieren. So können entweder Aussagen oder Fragen an den Chatbot gesendet werden. Hierbei können viele verschiedene Abfragen definiert werden. Je mehr Abfragen definiert werden, desto höher wird die Wahrscheinlichkeit, dass am Schluss der richtige Intent ausgewählt wird.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 5: Menu des Dialogflow*
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 6: Eingabe des Benutzers im Dialogflow*
|
|
|
|
|
|
|
|
Nun gibt es verschiedene Möglichkeiten, wie es weitergehen kann. Zum einen können an diesem Punkt verschiedene Parameter abgefragt werden, zum anderen gibt es die Möglichkeit ohne Parameterabfrage eine Antwort zu formulieren. Die Möglichkeit weitere Abfragen durchzuführen wird in Abbildung 7 dargestellt. An dieser Stelle können verschiedene Parameter und weitere Fragen gestellt werden. Mit Hilfe des Feldes "Required" wird ausgewählt, ob dieser Input zwingend abgefragt werden muss. Das Feld Parametername kann frei benannt werden, es bietet sich jedoch an, dieses Feld gleich zu nennen, wie das Feld "Value". Die gleiche Nennung vereinfacht das spätere Vorgehen ungemein. In dem Feld "Entity" werden die Entitäten eingetragen. Diese können entweder selbst definiert werden oder aber mit Hilfe von System Entititys. Dialogflow bietet eine Reihe von Systementitys, die es einem ermöglichen, einen großen Teil der Parameterabfragen abzudecken. Die genaue Funktion der Entities wird in Kapitel 3.4 beschrieben. Das Feld Value beinhaltet den Wert der nachgefragt werden soll. Mit Hilfe der Values werden die Interaktionen, die der User nach dieser Eingabe tätigt gespeichert. Ein Value Feld wird mit Hilfe der folgenden Notation gesetzt: "$Value". Wobei die Begrifflichkeit Value durch jeden beliebigen Text ersetzt werden kann. Wenn man nun, wie in Abbildung 8 das Feld "Required" auswählt, erscheint das zusätzliche Feld "Prompts". Innerhalb dieses Feldes können nun individuelle Abfragetexte definiert werden. In userem Projekt wurde hierbei beispielsweise die Zeit des Countdown abgefragt. Wie in Abbildung 8 zu sehen ist, kann man hierbei durch die Aktivierung des Buttons new Parameter einen neuen Parameter hinzufügen und somit die Abfrage beliebig erweitern. Bei den von uns durchgeführten Abfragen wurde noch kein oberes Limit erreicht.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 7: Action Feld im Dialogflow Framework*
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbdilung 8: Action Feld im Dialogflow Framework mit markierten Required Feld*
|
|
|
|
|
|
|
|
Nach dem die Actions definiert sind, kommt nun der dritte Schritt: der sogenannte Text Response. Das Feld Text Response wird in der Abbildung 9 dargestellt. In diesem Feld kann man die Antwortmöglichkeiten definieren, die der Chatbot geben soll. Hierbei ist es möglich verschiedene Antworten zu definieren. Durch ein Zufallsprinzip wird dann die Antwort ausgesucht. Wenn man einen Parameter innerhalb der Antwort einsetzt, kann man dies mit Hilfe der Notation "$value" ermöglichen.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 9: Darstellung des Feldes Text Response im Dialogflow*
|
|
|
|
|
|
|
|
-E-
|
|
|
|
|
|
|
|
## 3.4 Entities
|
|
|
|
Dank Entities können verschiedene Parameterwerte aus dem Input des Benutzers extrahiert werden. Damit das funktioniert, markiert man in der Input-Aussage das Wort, dem ein Parameterwert verliehen werden soll.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 10: Anlegen von Entities*
|
|
|
|
|
|
|
|
Die im System angelegten Entities fangen mit dem Präfix `@sys` an. Das sind z.B. `@sys.flight-number`, `@sys.email`, `@sys.date-period`, `@sys.location` und viele andere. Diese System-Entities haben Referenzwerte. Zum Beispiel, wenn der Benutzer sagt "Ich habe heute Geburtstag" und "heute" ist als `@sys.date` - Entity angelegt, kommt die Antowrt des Chatbots "Ich merke mir, dass Ihr Geburtstag am *19-01-2018* ist". In dem folgenden Link werden die verschiedenen verfügbaren System Entities aufgeführt : https://dialogflow.com/docs/reference/system-entities (Letzter Zugriff: 27.01.2018).
|
|
|
|
|
|
|
|
Es besteht eine Möglichkeit benutzerdefinierte Entities zu erstellen. Momentan sind sie acht und werden in verschiedenen Intents verwendet: `@Ansprechsperson`, `@assistenten-name`, `@Countdownvalue`, `@feedback_schlecht`, `@Internetadresse`, `@ja`, `@searchEntity`, `@usersname`.
|
|
|
|
|
|
|
|
|
|
|
|
### *Entities* im Small Talk
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 11: Anlegen eines Entity im Bereich Small Talk*
|
|
|
|
|
|
|
|
Damit das Gespräch persönlicher aussieht, wird im Intent "smalltalk.agent.name" in der Antwort des Benutzers eine im Voraus erstellte Entity `@usersname` eingebaut (Siehe Abbildung unten). Auf die Aussage des Benutzers "Ich heiße Hans" antwortet der Chatbot "Sehr angenehm, Hans!"
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 12: Erstellen eines Entity im Bereich Small Talk Step 2*
|
|
|
|
|
|
|
|
Weitere Beispiele der Entity-Einsetzung:
|
|
|
|
- Kennst du **Cortana**?
|
|
|
|
- Ja, ich kenne **Cortana**, wir sind befreundet.
|
|
|
|
- Kennst du **andere Chatbots**?
|
|
|
|
- Ja, ich kenne **andere Chatbots**, wir sind befreundet.
|
|
|
|
|
|
|
|
Hier wurde für "Cortana" und "andere Chatbots" die Entity `@assistenten-name` gesetzt.
|
|
|
|
|
|
|
|
#### Fehlermeldung
|
|
|
|
Aus einem noch unklaren Grund funktionieren momentan (28.01.2018) nur System Entities im Small-Talk in Accelerator. Im Chat im Output, wo die von Benutzern erstellte Entity vorgesehen ist, kommt die Meldung "What ist the assistenten-name".
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
## 3.5 Training
|
|
|
|
Der Dialog mit dem Chatbot soll natürlich wirken. Natürliche Sprache weicht lexikalisch und strukturell von der Norm ab. Beim Schreiben im Chat benutzen Menschen oft Abkürzungen, lassen Hilfsverbe weg, machen Rechschreibfehler, aber verstehen einander trotzdem gut. Deswegen ist es sehr wichtig, in *Dialogflow Intents* eine hohe Anzahl von Beispielen natürlicher Sprache zur Verfügung zu stellen (im Feld *User Says*), um den Chatbot zu trainieren. Je mehr Beispiele, desto höher ist die Klassifizierungsgenauigkeit, d.h. je treffender wird die Antwort des Chatbots. Zum Beispiel, alle *SmallTalk*-Intents enthalten mindestens 5 synonymische Aussagen in *User Says*. Groß- und Kleinschreibung genauso wie falsch geschriebene Varianten müssen in Intents nicht erfasst werden, sie werden vom Chatbot problemlos erkannt.
|
|
|
|
|
|
|
|
### 3.5.1 Wie trainiert man den Chatbot?
|
|
|
|
|
|
|
|
Den Intent kann bzw. soll man direkt nach seiner Erstellung trainieren. Das kann man im Dialogflow im Panel "Try it now" (Siehe Abbildung unten) machen. In diesem Panel soll man alle im Intent vorgesehene Benutzeraussagen ausprobieren und kontrollieren, ob der Chatbot die zuerwartende Antworten gibt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 13: Training eines Chatbots in Dialogflow mit Hilfe von "Try It Now*
|
|
|
|
|
|
|
|
Wie bringe ich dem Chatbot bei, dass seine Antwort gerade falsch war?
|
|
|
|
Nachdem man mehrere Intents in einer flüßigen Dialogform ausprobiert hat, geht man in den Menüpunkt *Training* im Panel rechts (der sich mit Stand vom 20.01.2018 erst als eine Beta-Version vorhanden ist) um die Dialog-Logs zu sehen.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 14: Training eines Chatbots in Dialogflow mit Hilfe der Rubrk Training*
|
|
|
|
|
|
|
|
Die Logs sind unter dem Namen des Intents gespeichert, bei welchem das Training des Dialogs angefangen wurde. In der Abbildung unten ist das *Harlem Shake*, unter dem Namen sind aber natürlich viele verschiedene Intents zu finden, die im Dialog benutzt wurden.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 15: Training eines Chatbots*
|
|
|
|
|
|
|
|
In diesem Fenster kann man die vom Chatbot richtig beantwortete Fragen mit grünem Häckchen akzeptieren, ignorieren oder ablehnen bzw. löschen. Wenn der Chatbot die Benutzeraussage zu keinem Intent zuordnen konnte, markiert er das mit einem Ausführungszeichen. Nachdem alle Intents in diesem Training-Fenster auf solche Weise bearbeitet sind, bestätigt man das Training mit der Taste *Approve*.
|
|
|
|
|
|
|
|
Es ist sinnvoll, dass möglichst unterschiedliche Leute mit dem Chatbout einen Dialog/Smalltalk testen. Unterschiedliche Tester mit ihrem Gesprächstil helfen die Benutzeraussagen mit mehr Beispielen zu bereichern. Nach jedem Testen ist es sinnvoll den Chatbot zu trainieren.
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
|
|
|
|
## 3.6 Schnittstelle zu Accelerator
|
|
|
|
In der Datei "Chatbot.js" wird die Verbindung zu dem Framework Dialogflow aufgebaut. Im Folgenden wird der Code zur Generierung der Schnittstelle aufgeführt.
|
|
|
|
|
|
|
|
**Darstellung der Schnittstelle zu Dialogflow in der Chatbot.js**
|
|
|
|
|
|
|
|
```
|
|
|
|
var dialogflow = require('dialogflow');
|
|
|
|
|
|
|
|
//Google
|
|
|
|
var sessionId = 1;
|
|
|
|
const projectId = 'accelerator-chatbot';
|
|
|
|
|
|
|
|
const chatBotError = "\n WARNING: Chatbot not working because no GOOGLE_APPLICATION_CREDENTIALS env variable set! To fix it, run this in your command line:\n Win: set GOOGLE_APPLICATION_CREDENTIALS=Accelerator-Chatbot-b863bdff37fd.json\n Linux: GOOGLE_APPLICATION_CREDENTIALS=Accelerator-Chatbot-b863bdff37fd.json\n";
|
|
|
|
if(!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
|
|
console.log(chatBotError);
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
chat1 : function(msg, username,languageCode, callback) {
|
|
|
|
if(!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
|
|
|
|
console.log(chatBotError);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
chtext = msg.split("/cb ")[1];
|
|
|
|
if(chtext && chtext != "") {
|
|
|
|
var sessionId = username+(sessionId++);
|
|
|
|
const sessionClient = new dialogflow.SessionsClient();
|
|
|
|
var session = sessionClient.sessionPath(projectId, sessionId);
|
|
|
|
|
|
|
|
// The text query request.
|
|
|
|
const request = {
|
|
|
|
session: session,
|
|
|
|
queryInput: {
|
|
|
|
text: {
|
|
|
|
text: chtext,
|
|
|
|
languageCode: languageCode,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// Send request and log result
|
|
|
|
sessionClient
|
|
|
|
.detectIntent(request)
|
|
|
|
.then(responses => {
|
|
|
|
console.log('Detected intent');
|
|
|
|
const result = responses[0].queryResult;
|
|
|
|
console.log(` Query: ${result.queryText}`);
|
|
|
|
console.log(` Response: ${result.fulfillmentText}`);
|
|
|
|
callback(result.fulfillmentText,"chatbot", username, result.intent.displayName);
|
|
|
|
if (result.intent) {
|
|
|
|
console.log(` Intent: ${result.intent.displayName}`);
|
|
|
|
} else {
|
|
|
|
console.log(` No intent matched.`);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(err => {
|
|
|
|
console.error('ERROR:', err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Die Anbindung des Chatbots innerhalb der Chatbot.js wurde mit Hilfe der [Node.js](https://github.com/dialogflow/dialogflow-nodejs-client-v2) (Letzter Zugriff 27.01.2018) Schnittstelle des GITs umgesetzt. In dem oben aufgeführten Code wurde die Programmierschnittstelle (API) von Dialogflow hinzugefügt, um so die Verbindung zum Framework aufzubauen. In der folgenden Abbildung wird ein Screenshot der Google Plattform gezeigt, aus welcher der Code für die API entspringt. Da es sich bei einem Teil der Daten um vertrauliche Informationen handelt, wurden diese geschwärzt. Um die Daten zu erhalten, kann man auf einen Link in Dialogflow klicken, wodurch man auf die entsprechende Unterseite gelangt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 16: Herauslesen der Google Daten aus der Google Cloud Platform*
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 17: Dialogflow Link für die Google Plattform*
|
|
|
|
|
|
|
|
Die API kann auch in JSON-Dateien heruntergeladen werden. Diese wurden in das GIT des Accelerator Projektes bereits eingebaut. Beim lokalen Ausführen des Accelerators über den Test-Server Branch muss jedoch ein Link zu Dialogflow manuell in die Konsole eingegeben werden. Bislang haben wir hierzu leider keine Möglichkeit gefunden, dies zu automatisieren.
|
|
|
|
|
|
|
|
**Folgende Code-Zeile muss vor dem lokalen Start des Node-Servers in die CMD-Konsole eingegeben werden:**
|
|
|
|
```
|
|
|
|
set GOOGLE_APPLICATION_CREDENTIALS=Accelerator-Chatbot-b863bdff37fd.json
|
|
|
|
```
|
|
|
|
|
|
|
|
Durch diese Code-Zeile wird eine Referenz zwischen den Intents von Dialogflow und den lokal abgelegten Skripts geschaffen. In der Konsole werden nun die Intents, die Fragen und die Antworten aufgeführt. Die Intents werden nun an die jeweiligen Stellen in den anderen Dateien weiteregeleitet wie die Server.js, die connect.js und die uiHelper.js.
|
|
|
|
|
|
|
|
In dem nachfolgenden Code Beispiel wird die Weiterleitung des Intents in der Server.js Datei aufgezeigt. In der Server.js werden Informationen in dem Chatfenster vom Server eingetragen. Hierbei wird intern jede Nachricht mit dem Zeichen "/cb" versehen. In der nächsten Zeile wird die Sprache des Benutzers ausgegeben. Die Sprache des Benutzers wird hierbei definiert als Browsersprache, die der Benutzer eingestellt hat. Dann wird nun das eigentliche Intent eingetragen. Hierbei wird in dem Chatfenster die Message, die der Benutzer eingegeben hat und der Chatbotname angezeigt. Wenn es kein Intent gibt, wird eine Nachricht an alle Teilnehmer geschickt. Dieser Fall tritt aber nicht ein, da dies von den sogennannten Fallback Intents in Dialogflow abgedeckt wird. In der Server.js Datei passiert jedoch keine weitere Verknüpfung mit den Intents. Die Intents werden in der uiHelper-Klasse weiter behandelt.
|
|
|
|
|
|
|
|
**Darstellung des Intent Handling in der Server.js**
|
|
|
|
|
|
|
|
```
|
|
|
|
//For chat and mgs in the same room
|
|
|
|
socket.on('message', function(msg) {
|
|
|
|
if(typeof(msg)=="string") {
|
|
|
|
if(msg.indexOf("/cb")!==-1) {
|
|
|
|
console.log(userdata["userLang"])
|
|
|
|
chatbot.chat1(msg, userdata["username"],userdata["userLang"], function(newMsg, cbname, username, intent) {
|
|
|
|
socket.emit('message', {"msg":newMsg, "intent":intent, "id":socket.id, "username": cbname});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
sendToHoleRoomButNotMe(roomName,socket.id, 'message', {"msg":msg, "id":socket.id, "username": userdata["username"]});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(isModerator()) {
|
|
|
|
var newMsg = msg.msg;
|
|
|
|
var changendUserName = msg.changedName;
|
|
|
|
sendToHoleRoom(roomName, 'message', {"msg":newMsg, "id":socket.id, "username": changendUserName});
|
|
|
|
} else {
|
|
|
|
socket.emit('message', {"msg":"Diese Funktion ist nur für Moderatoren!", "id":socket.id, "username": "Chatbot"});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
```
|
|
|
|
In dem nachfolgenden Code-Beispiel wird beschrieben, wie die Intents weiter behandelt werden. Der Use-Case ist hierbei der, dass jeder Nutzer des Chats eine persönliche Nachricht an den Chatbot schreiben kann, welche von den anderen Benutzern nicht gesehen werden kann. Dies wird mit Hilfe der Methode "writeToChat" umgesetzt. In dieser Methode wird abgefragt, ob ein Intent existiert. Dies wird mit Hilfe des folgenden Aufrufes umgesetzt.
|
|
|
|
|
|
|
|
**Darstellung der writeToChat Methode in der uiHelper.js**
|
|
|
|
|
|
|
|
```
|
|
|
|
function writeToChat(clientName,text, noClean, intent) {
|
|
|
|
if(intent == "Countdown"){
|
|
|
|
```
|
|
|
|
|
|
|
|
-S,E,D-
|
|
|
|
|
|
|
|
|
|
|
|
# 4 Funktionalitäten
|
|
|
|
Die nachfolgenden Funktionen wurden jeweils mit Hilfe einer Anbindung (in Form von intents) an Dialogflow realisiert. Hierbei wurde sowohl eine englische, als auch eine deutsche Sprachausgabe umgesetzt.
|
|
|
|
|
|
|
|
## 4.1 Bilinguale Sprachausgabe
|
|
|
|
|
|
|
|
Die textuelle Ausgabe des Chatbots wurde in den Sprachen Deutsch und Englisch realisiert. Der Output der Sprachausgabe hängt von den Einstellungen innerhalb des Browsers ab. Dem liegt der Gedanke zugrunde, dass Leute, dessen Webbrowser auf der Sprache Deutsch eingestellt ist, vorwiegend auch Deutsch zur Kommunikation verwenden. Um die Sprache des Nutzers durch die Browsereinstellungen zu enttarnen, wurde die "langDB.js" in dem Skripte-Unterordner des GITs angelegt. Die langDB.js ist eine JavaScript-Datei, die einerseits die Browsereinstellung abfrägt und andererseits die verschiedenen sprachlichen Spezifikationen verwaltet. So werden hier alle sprachlichen Besonderheiten erfasst und in die jeweilige Sprache transferiert.
|
|
|
|
|
|
|
|
**Darstellung der language Datenbank langDB**
|
|
|
|
|
|
|
|
```
|
|
|
|
var langDb = {
|
|
|
|
"de" : {
|
|
|
|
"remainingTime" : "Verbleibende Zeit: ",
|
|
|
|
"timesup" : "Zeit abgelaufen ",
|
|
|
|
"haveToBeModerator" : "Sie müssen Moderator sein um die Funktion zu benutzen ",
|
|
|
|
"minutes" : "Minute(n) ",
|
|
|
|
"seconds" : "Sekunde(n) ",
|
|
|
|
"hours" : "Stunde(n) ",
|
|
|
|
"noUserAvaliable" : "Kein Teilnehmer vorhanden ",
|
|
|
|
"randomUser" : "Zufälliger Teilnehmer ",
|
|
|
|
"randomUserList" : "Zufällige Teilnehmerliste "
|
|
|
|
},
|
|
|
|
"en" : {
|
|
|
|
"remainingTime" : "Remaining time: ",
|
|
|
|
"timesup" : "Times up ",
|
|
|
|
"haveToBeModerator" : "You have to be moderator to use this function ",
|
|
|
|
"minutes" : "Minutes ",
|
|
|
|
"seconds" : "Second(s) ",
|
|
|
|
"hours" : "hour(s) ",
|
|
|
|
"noUserAvaliable" : "No user available ",
|
|
|
|
"randomUser" : "Random User ",
|
|
|
|
"randomUserList" : "Random list of participants "
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getLang(index) {
|
|
|
|
if(userLang != "de") {
|
|
|
|
userLang = "en";
|
|
|
|
}
|
|
|
|
if(langDb[userLang][index])
|
|
|
|
return langDb[userLang][index];
|
|
|
|
else
|
|
|
|
return "lang not found for index:"+index;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Außerdem wurde in Dialogflow für jede Funktion sowohl für die deutsche, als auch für die englische Sprache ein Intent angelegt. Dies war leider von Nöten, da der von uns entwickelte Chatbot als DEFAULT Sprache deutsch eingestellt hat. Hierbei kann man zwar weitere Sprachen ergänzen, diese werden aber im Moment noch nicht von Dialogflow abgeprüft und weiter behandelt. Ein weitere Möglichkeit wäre gewesen, die Sprache in den Intents sowohl in Deutsch als auch in Englisch zu pflegen. Mit Hilfe der Browsersprache sollte dann der Chatbot die richtige Sprache wählen. Dies hat aber nicht geklappt, da beim Intent "Countdown" Parameterabfragen benötigt werden, welche im Dialogflow nicht vorhanden waren. So gab es nicht die Möglichkeit minutes, seconds oder hours einzupflegen und abzufragen. Aufgrund dieser Restriktion wurden zwei Abfragen eingebaut, sodass erst nach der gewünschten Zeit und anschließend nach der Zeiteinheit abgefragt wird.
|
|
|
|
|
|
|
|
-S,E,D-
|
|
|
|
|
|
|
|
## 4.2 Default Intent
|
|
|
|
Da der Chatbot garantiert nicht alle Wünsche der Nutzer erfüllen kann, war zunächst die Definition wichtig, wie der Chatbot auf Eingaben reagiert, die zu keinen bereits vorhandenen Intents und daher zu implementierten Funktionen zugeordnet werden können. Dialogflow liefert hierzu einen sogenannten "Default Fallback Intent". Dies ist derjenige Intent, der angesprungen wird, wenn eine Nutzereingabe nicht verstanden bzw. nicht zugeordnet werden kann.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 18: Default Fallback Intent auf Dialogflow*
|
|
|
|
|
|
|
|
Die auf Dialogflow angelegten Responses (zu Deutsch: Antworten), die der Chatbot genau dann von sich gibt, wenn eine Eingabe nicht verstanden oder nicht zugeordnet werden kann, wurden darüber hinaus mit einem Link ergänzt, der zu einem Google-Formular führt. Über dieses Formular können Nutzer Wünsche bezüglich Implementierungen beim Chatbot äußern.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 19: Anlegen eines Formular-Eintrags für zukünftige Implementierungen des Chatbots*
|
|
|
|
|
|
|
|
Das Formular wurde über das Google-Profil des Chatbots, welches auch für Dialogflow verwendet wird, in Google-Drive angelegt. Von dort aus kann die Liste kontinuierlich durch Nutzerwünsche ergänzt werden. Als Administrator und **eingeloggt in den Google-Account des Chatbots** können die Eingaben unter folgendem Link eingesehen werden: [Google-Formular Responses](http://goo.gl/EtFRSS) (Letzter Zugriff 27.01.2018)
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 20: Angelegte Liste von Nutzern für zukünftige Implementierungen des Chatbots*
|
|
|
|
|
|
|
|
-S-
|
|
|
|
|
|
|
|
## 4.3 Small Talk
|
|
|
|
Die Hauptaufgabe von einem Chatbot besteht darin, einen Dialog mit Benutzern zu führen. Zusätzlich zu der Assistentenfunktion hat der Accelerator-Chatbot eine unterhaltende Rolle. Der Chatbot kann mit Benutzern einen Small-Talk führen. Im Dialogflow wird ein zusätzlicher Small-Talk-Agent (*Prebuilt Agent*) mit vorgefertigten 87 *Intents* bereitgestellt. Diese können mit eigenen Intents nach Bedarf vervollständigt werden. Intents sind nach Themen klassifiziert und bieten eine Vielzahl von Phrasen, die ein Benutzer beim Chatten mit dem Chatbot sagen könnte - *User Says*. Wenn man einen den *Intents* öffnet, finden Sie diese Sätze im Feld *User Says*. Das Feld "User Says" soll synonymische Ausdrücke beinhalten. Zum Beispiel, wenn der User den Chatbot nach seinem Alter fragt, kann er die Frage unterschiedlich formulieren: Wie alt bist du? Wann wurdest du geboren? Wann wurdest du entwickelt? usw.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 21: Small Talk User Says*
|
|
|
|
|
|
|
|
*Intents* sind ursprünglich nicht vollständig und nicht immer korrekt ausgefüllt, man kann sie also nicht direkt einsetzen. Um sie zu verwenden, muss man das Feld *Text Response* selbstständig ausfüllen und *Entities* nach Bedarf erstellen und einbauen. Das Feld "User Says" sollte auch angepasst werden, da z.B. im Intent *"good evening"* sowohl eine Bregüßung als auch ein Abschied mit einem Schönen-Abend-Wunsch zu finden war. Die ausgefüllten Antworte werden vom Chatbot randomisiert, um den Effekt echter Live-Sprache zu erreichen. Daher ist es im Feld *Text Response* wünschenswert, mindestens drei Varianten der Antwort einzugeben. Auch mehr Varianten sind möglich.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 22: Small Talk Antworten*
|
|
|
|
|
|
|
|
Die Intents des Agenten *Small Talk* sind nach folgenden Kategorien klassifiziert:
|
|
|
|
* **Greetings** - Begrüßungsformen, die der Benutzer sagen kann.
|
|
|
|
* **Agent** - Fragen, die der Benutzer dem Chatbot stellen kann, um Informationen über ihn zu erhalten.
|
|
|
|
* **User** - Aussagen bzw. die der Benutzer dem Chatbot über sich mitteilt.
|
|
|
|
* **Appraisal** - Der Benutzer lobt oder kritisiert den Chatbot.
|
|
|
|
* **Dialog** - Der Benutzer bietet mit ihm zu sprechen und kommentiert das Gespräch.
|
|
|
|
* **Emotions** - Der Benutzer drückt seine Emotionen aus, wie Lachen und Verwunderung.
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
### 4.3.1 Aufbau des Dialogs
|
|
|
|
Aus technischen Gründen kann ein Dialog mit dem Chatbot vom Benutzer initiiert werden und nicht umgekehrt. Der Chatbot kann den Benutzer als Erster nicht ansprechen, aus diesem Grund hat der Dialog mit dem Chatbot eine Form des Interviews, in dem der Benutzer stellt fragen und der Chatbot antwortet. Wenn der Benutzer aufhört, fragt der Chatbot ihn nichts zurück.
|
|
|
|
|
|
|
|
Damit der Dialog natürlicher aussieht, soll in der Antwort des Chatbots bereits eine Rückfrage beinhaltet werden. Solches Vorgehen macht die Kette aus Fragen und Antworten natürlicher. Genau aus dem Grund der Natürlichkeit, soll nicht jede Antwort des Chatbots eine Rückfrage beinhalten.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 23: Aufbau von Small Talk*
|
|
|
|
|
|
|
|
In dem Dokument "Chatbeispiele mit Intents" sind Dialogbeispiele zu finden. Dort kann man sehen, dass jede Input-Output-Aussage einem Intent gehört und wie manche Intents mit *Contexts* (siehe Abschnitt 4.3.2) verbunden sind: https://docs.google.com/spreadsheets/d/1xf9HERH_oCdYPEQNodvIFRClGeMarbwWhUKiS660fQ8/edit?usp=sharing
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3.2 *Contexts* im Small Talk
|
|
|
|
Im Dialogaufbau werden *Contexts* benutzt, um eine bestimmte Reihenfolge den Aussagen festzulegen. Ein Context muss nicht im Voraus vordefiniert werden, sondern er wird direkt im Intent eingelegt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbbildung 24: Contexts in Intents*
|
|
|
|
|
|
|
|
Im Intent, in dem eine bestimmte Frage gestellt wird, soll *Context* als *Output* eingelegt werden. Im *Intent*, der danach folgt und die Antwort auf die Frage liefert, soll der *Context* mit dem selben Namen im *Input* stehen (Siehe Abbildung 24). Die Intents die mit solchen Output-Input-Contexts verbunden sind, werden nur in der vordefinierten Reihenfolge funktionieren.
|
|
|
|
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
### 4.3.3 Import des Small-Talk-Agenten
|
|
|
|
Der Small-Talk-Agent ist einer der *Prebuilt Agenten* von *Dialogflow*. Er wurde nicht direkt in den Accelerator-Chatbot importiert, sondern als ein separater Agent. Man kann nun im Rahmen des Accounts zwischen den zwei (bzw. mehreren) Agenten umschalten.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 25: Import eines Agenten*
|
|
|
|
|
|
|
|
Um die *Small-Talk-Intents* im Accelerator-Chatbot zu verwenden, muss man im Dialogflow wie Folgendes vorgehen:
|
|
|
|
- Im *Small-Talk-Agent* einen Backup mit "EXPORT ALS ZIP" erstellen;
|
|
|
|
- Zu dem *Accelerator-Chatbot-Agenten* wechseln und mit dem Button "IMPORT FROM ZIP" die Intents hochladen.
|
|
|
|
-
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 26: Export eines Agenten*
|
|
|
|
|
|
|
|
Es wird kein Namenskonflikt entstehen, da alle Small-Talk-Intents einen Prefix "smalltalk" haben (Siehe Abschnitt 4.1.5).
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
### 4.3.4 Namenskonvention und Erweiterung mit neuen Intents
|
|
|
|
Im Laufe des Trainings des Chatbots wird ein Bedarf entstehen, diesen mit neuen Intents zu erweitern. Dafür gibt es zwei Möglichkeiten.
|
|
|
|
|
|
|
|
1. Small-Talk-Intents direkt im Accelerator-Chatbot-Agent bearbeiten und erweitern. Die Liste der Intents wird mit der Zeit wachsen und wird nicht mehr übersichtlich sein, da im Accelerator-ChatBot-Agenten sind alle Intents gemischt. Zur Zeit
|
|
|
|
umfasst sie bereits 5 Seiten.
|
|
|
|
2. Die Itents für den Small-Talk ausschließlich im Small-Talk-Agenten bearbeiten und sie danach importieren.
|
|
|
|
|
|
|
|
Es ist deswegen notwendig die Namenskonvention zu beachten.
|
|
|
|
`smalltalk.agent.happy` -> `derNameDesAgenten.thema.aussage`
|
|
|
|
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
## 4.4 Countdown
|
|
|
|
Diese Funktion wurde in englischer, sowie deutscher Sprache umgesetzt. Der Use Case der Funktion ist es, dass der Moderator eine Aufgabe stellt die innerhalb eines gesetzten Zeitrahmens von den Teilnehmern erfüllt werden muss. Nun kann der
|
|
|
|
Moderator in dem Chat beispielsweise "Starte den Countdown" reinschreiben. Anschließend erscheint nun die Frage, wie lange dieser laufen soll? Dieser Dialog wird in der folgenden Abbildung visualisiert. Der Moderator kann aber auch eine Abfrage stellen, wie "starte den Countdown von 5 Minuten". Bei dieser Abfrage wird der entsprechende Countdown gestartet.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 27 : Darstellung des Countdown Dialogs*
|
|
|
|
|
|
|
|
Nun können verschiedene Werte eingeben werden, wie beispielsweise 5 Sekunden, Minuten oder Stunden. Der Ablauf wird in Abbilung 27 visualisiert.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 28: Darstellung des zweiten Teil des Countdown Dialogs*
|
|
|
|
|
|
|
|
Anschließend wird die Zeit in Bezug zu der jeweiligen Zeiteinheit heruntergezählt. Dies wird in der folgenden Abbildung visualisiert.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 29: Darstellung des dritten Teil des Countdown Dialogs*
|
|
|
|
|
|
|
|
Die Eingaben werden vom Dialogflow gesendet und vom Accelerator empfangen. In den folgenden Abbildungen sieht man, wie der oben dargestellte Dialog innerhalb von Dialogflow abgedeckt wird.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 30: Darstellung des Countdown Dialogs Teil 1 in Dialogflow*
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 31: Darstellung des Countdown Dialogs Teil 2 in Dialogflow*
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 32: Darstellung des Countdown Dialogs Teil 3 in Dialogflow*
|
|
|
|
|
|
|
|
Anschließend wird im Accelerator Code die folgende Funktion aufgerufen.
|
|
|
|
|
|
|
|
**Darstellung der Countdown Funktion in der uiHelper.js**
|
|
|
|
|
|
|
|
```
|
|
|
|
if(intent == "Countdown"){
|
|
|
|
|
|
|
|
if(roomImIn["moderator"] === ownSocketId){
|
|
|
|
console.log(roomImIn["moderator"], ownSocketId)
|
|
|
|
if(text.indexOf("Wie lange")!==-1){
|
|
|
|
//nothing to do
|
|
|
|
} else if(text.indexOf("gestartet")!==-1){
|
|
|
|
//Countdown stuff
|
|
|
|
var numberTimeDurationUnit = 0;
|
|
|
|
var msgSplit = text.split(" ");
|
|
|
|
if(msgSplit.length >0 && msgSplit[2] >0){
|
|
|
|
var timeDuartionUnit = msgSplit[3];
|
|
|
|
time = msgSplit[2];
|
|
|
|
if(countDownInterval){
|
|
|
|
clearInterval(countDownInterval);
|
|
|
|
}
|
|
|
|
if(timeDuartionUnit == "min" || timeDuartionUnit == "minutes"){
|
|
|
|
numberTimeDurationUnit = 60000;}
|
|
|
|
if(timeDuartionUnit == "s"){
|
|
|
|
numberTimeDurationUnit = 1000; }
|
|
|
|
if(timeDuartionUnit == "stunde" || timeDuartionUnit=="hours"){
|
|
|
|
numberTimeDurationUnit = 120000;}
|
|
|
|
|
|
|
|
countDownInterval = setInterval( function(){
|
|
|
|
|
|
|
|
if(time>1){
|
|
|
|
time--;
|
|
|
|
if(timeDuartionUnit== "min"){
|
|
|
|
signaling_socket.emit('message', { "msg" : getLang("remainingTime") +" "+time+" "+getLang("minutes"), "changedName":"Chatbot"});
|
|
|
|
}
|
|
|
|
if(timeDuartionUnit == "s"){
|
|
|
|
signaling_socket.emit('message', { "msg" : getLang("remainingTime") +" "+time+" "+getLang("seconds"), "changedName":"Chatbot"});
|
|
|
|
}
|
|
|
|
if(timeDuartionUnit=="stunde"){
|
|
|
|
signaling_socket.emit('message', { "msg" : getLang("remainingTime") +" "+time+" "+getLang("hours"), "changedName":"Chatbot"});
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
signaling_socket.emit('message', { "msg" : getLang("timesup"), "changedName":"Chatbot"});
|
|
|
|
clearInterval(countDownInterval);
|
|
|
|
}
|
|
|
|
},numberTimeDurationUnit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
writeToChat("Chatbot", getLang("haveToBeModerator"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
In der ersten Zeile wird übeprüft, ob die Texteingabe die im Accelerator getätigt wird einem Intent zugeordnet werden kann. Wenn dies der Fall ist, wird die Funktion aufgerufen. Anschließend wird überprüft, ob die Person, die die Funktion aufruft ein Moderator ist. Sollte sie kein Moderator sein, wird ein entsprechender Text auf dem Bildschirm ausgegeben. Der nächste Schritt ist das Auslesen der Zahl auf dem Bildschirm. In dem Code Fragment kann man erkennen, dass von Dialoglfow sowohl die Zeit als auch die Zeiteinheit gesendet wird. Diese wird nun ausgelesen und der Countdown wird gestartet.
|
|
|
|
|
|
|
|
-E-
|
|
|
|
|
|
|
|
## 4.5 Random User List
|
|
|
|
Mit Hilfe der Funktion Random User List werden die Teilnehmer des Webinars in einer zufälligen Reihenfolge aufgezeigt. In der folgenden Abbildung werden die jeweiligen Abfragen abgebildet. Der Name des Intents lautet in Dialogflow in der deutschen Version "Zufällige Liste"
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 33: Dialogflow Intent zufällige Liste der Teilnehmer*
|
|
|
|
|
|
|
|
Im Chatfenster des Dialogflow wird anschließend der folgende Output erzeugt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 34: zufällige Liste der Teilnehmer*
|
|
|
|
|
|
|
|
Wenn mehr als ein Teilnehmer im Acclerator ist, wird anschließend eine Liste der Namen der Teilenehmer erzeugt und diese im Chatfenster ausgegeben. Die Ausgabe wird in der folgenden Abbildung visualisiert, in dieser wird auch der Code der Funktion gezeigt.
|
|
|
|
|
|
|
|
**Darstellung der Funktion Generierung einer zufälligen Liste in der uiHelper**
|
|
|
|
|
|
|
|
```
|
|
|
|
else if(intent == "Zufällige Liste"){
|
|
|
|
if(roomImIn["moderator"]== ownSocketId){
|
|
|
|
var userNameArray = [];
|
|
|
|
$.each($("#userPanel").find(".userdiv"),function(){
|
|
|
|
userNameArray.push($(this).find(".username").text());
|
|
|
|
});
|
|
|
|
if(userNameArray.length == 0) {
|
|
|
|
writeToChat("Chatbot", getLang("noUserAvaliable"));
|
|
|
|
} else {
|
|
|
|
signaling_socket.emit('message', { "msg" : getLang("randomUserList"), "changedName":"Chatbot"});
|
|
|
|
var shuffledUserArray = shuffleArray(userNameArray);
|
|
|
|
for(var i=0;i<shuffledUserArray.length;i++) {
|
|
|
|
signaling_socket.emit('message', { "msg" : (i+1)+") "+shuffledUserArray[i], "changedName":"Chatbot"});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
writeToChat("Chatbot", getLang("haveToBeModerator"));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Am Anfang der Methode wird überprüft, ob der jeweilige Text, der im Chatfenster eingegeben wird, zu dem Intent passt. Wenn dies der Fall ist, wird die Funktion weiter durchgeführt. Anschließend wird überprüft, ob die Person, die den Intent aufgerufen hat, ein Moderator ist. Wenn die Person kein Moderator ist, wird zurückgegeben, dass die Funktion nur für Moderatoren verfügbar ist und die Methode wird verlassen. Wenn die Person, die die Funktion aufgerufen hat, ein Moderator ist, wird überprüft, ob mehr als ein User im Accelerator vorhanden ist. Wenn nur der Moderator im Accelerator ist, wird keine Teilnehmerliste ausgegeben. Im Falle, dass mehr als ein Teilnehmer vorhanden ist, wird eine Lister der Teilnehmer in das Chatfenster eingetragen.
|
|
|
|
|
|
|
|
-E-
|
|
|
|
|
|
|
|
## 4.6 Random User
|
|
|
|
Mithilfe der Funktion "Random User" wählt der Chatbot randomisiert genau einen Namen der aktuellen Teilnehmerliste aus und schreibt diesen Namen in den Chat. Der Hintergrundgedanke zur Implementierung dieser Funktionalität begründet sich aus der Moderatorsicht heraus: Wenn beispielsweise eine Frage offen bleibt und sicht kein Teilnehmer freiwillig äußern möchte, kann diese Funktion taktisch genutzt werden, um tatsächlich randomisiert eine Person aus der Liste auszuwählen. Ähnlich allen anderen Funktionen wurde auch diese bilingual implementiert und mit Intents von Dialogflow referenziert. Daher werden keine exakten Kommandos zum Ansprechen der Funktion benötigt, sondern hierbei reicht lediglich eine ähnliche Eingabe, wie sie in den dazugehörigen Intents bestenfalls bereits eingelernt wurden. Die Code-Zeilen wurden zu der uiHelper.js-Datei ergänzt. Die entsprechenden Intents "Zufälliger Teilnehmer" und "randomUser" wurden auf Dialogflow angelegt. Nachfolgend wird ein Screenshot der Implementierung und der zugehörige Code aufgeführt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 35: Zufälliger User*
|
|
|
|
|
|
|
|
|
|
|
|
**Verknüpfung des Intents und Anlage der Funktion in uiHelper.js**
|
|
|
|
```
|
|
|
|
else if (intent == "Zufälliger Teilnehmer"){
|
|
|
|
if(roomImIn["moderator"] == ownSocketId){
|
|
|
|
|
|
|
|
var userNameArray = [];
|
|
|
|
$.each($("#userPanel").find(".userdiv"),function(){
|
|
|
|
userNameArray.push($(this).find(".username").text());
|
|
|
|
});
|
|
|
|
if(userNameArray.length==0){
|
|
|
|
writeToChat("Chatbot",getLang("noUserAvaliable"));
|
|
|
|
}else{
|
|
|
|
var randomUserNr = Math.floor(Math.random() * userNameArray.length)
|
|
|
|
signaling_socket.emit('message', { "msg" : getLang("randomUser")+userNameArray[randomUserNr], "changedName":"Chatbot"});
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
writeToChat("Chatbot", getLang("haveToBeModerator"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (intent == "randomUser"){
|
|
|
|
if(roomImIn["moderator"] == ownSocketId){
|
|
|
|
|
|
|
|
var userNameArray = [];
|
|
|
|
$.each($("#userPanel").find(".userdiv"),function(){
|
|
|
|
userNameArray.push($(this).find(".username").text());
|
|
|
|
});
|
|
|
|
if(userNameArray.length==0){
|
|
|
|
writeToChat("Chatbot",getLang("noUserAvaliable"));
|
|
|
|
}else{
|
|
|
|
var randomUserNr = Math.floor(Math.random() * userNameArray.length)
|
|
|
|
signaling_socket.emit('message', { "msg" : getLang("randomUser")+userNameArray[randomUserNr], "changedName":"Chatbot"});
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
writeToChat("Chatbot", getLang("haveToBeModerator"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
-S-
|
|
|
|
|
|
|
|
## 4.7 Save Chat
|
|
|
|
Der Chatbot liefert auch eine Funktion, einen Chatverlauf eines Meetings in der Accelerator-Cloud abzuspeichern. Hierzu wurde für beide verwendeten Sprachen (DE/EN) in der Datei "uiHelper.js" eine Funktion definiert. Damit diese Funktion auch mit natürlicher Sprache aufgerufen werden kann, man also nicht strikt den genauen Befehl in das Chatfenster eingeben muss, wurden auf Dialogflow zugehörige Intents (DE/EN) angelegt.
|
|
|
|
|
|
|
|
Im Folgenden wird die Implementierung anhand einem Screenshot beispielhaft aufgezeigt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 36: Save Chat in der Anwendung*
|
|
|
|
|
|
|
|
Der Code zur Implementierung dieser Funktion sieht wie folgt aus:
|
|
|
|
|
|
|
|
**Verknüpfung des Intents und Anlage der Funktion in uiHelper.js**
|
|
|
|
```
|
|
|
|
else if(intent == "Save Chat"){
|
|
|
|
if(text.indexOf("gespeichert")!=-1){
|
|
|
|
var textfile = "";
|
|
|
|
$.each($("#chatContent").find("div"), function() {
|
|
|
|
textfile = textfile + "" + $(this).text() + "\n";
|
|
|
|
});
|
|
|
|
sendSharNotes(textfile, "chat");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(intent == "SaveChatEN"){
|
|
|
|
if(text.indexOf("Chat")!=-1){
|
|
|
|
var textfileOne = "";
|
|
|
|
$.each($("#chatContent").find("div"), function() {
|
|
|
|
textfileOne = textfileOne + "" + $(this).text() + "\n";
|
|
|
|
});
|
|
|
|
sendSharNotes(textfileOne, "chat");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
-S-
|
|
|
|
|
|
|
|
## 4.8 Chatbot als Accelerator-Guide (Guided Tour Schnittstelle)
|
|
|
|
In diesem Abschnitt wird die etwas Codezeilen-reichere Funktionalität des Chatbots in der Rolle eines Guides durch den Accelerator erläutert. Durch diese implementierte Funktion erhält der Chatbot Wissen über das ganze Accelerator-Tool und kann daher Fragen wie beispielsweise "Wie spricht man?", "Wie verwaltet man 3D-Objekte?" oder wie "Wie kann ich mein Bild ändern?" uvm. beantworten. Für alle Interaktionsmöglichkeiten, die ein Nutzer im Accelerator-Tool hat, wurden entsprechend jeweils zwei Intents auf Dialogflow angelegt (für DE und EN) und entsprechend in den Skripten referenziert.
|
|
|
|
|
|
|
|
Die Grundvoraussetzung zur Implementierung dieser Funktionalität war zunächst die Anlage einer Guided Tour. Hierzu wurde zunächst das Grundgerüst der sogenannten [Bootstrap Tour](http://bootstraptour.com/) (Letzter Zugriff 27.01.2018) von Raphael Fritsch in das Accelerator-Tool eingebettet. Nachdem das Grundgerüst für die Guided Tour in Accelerator integriert war, konnten die sogenannten "Steps" (dt.: Schritte) angelegt werden. Unter den Steps werden die Schritte verstanden, die bei einer Guided Tour angesprungen werden können. Im Falle von Accelerator wurden daher Steps für alle Interaktionsmöglichkeiten, die ein User im Accelerator hat, angelegt. In diesem Zusammenhang entstand die Datei "tourGuid.js", die in der "index.html" referenziert wurde. Da die Datei ziemlich viele Codezeilen beinhaltet, wird an dieser Stelle auf die Datei verwiesen, anstatt der Einbettung des kompletten Codes: [tourGuid.js](http://git.reutlingen-university.de/ksystem/Accelerator/src/5a8d445f9b655fc64c1a52b6663775c7a71f0c49/public/js/tourGuid.js) (Letzter Zugriff 27.01.2018) .
|
|
|
|
|
|
|
|
Wie bereits erwähnt wurde, wurden auf Dialogflow für jede Interaktionsmöglichkeit zwei Intents angelegt. Ein deutscher und ein englischer Intent. In der "uiHelper.js" wurden die entsprechenden Intents von Dialogflow mit der "tourPartsDb" der "tourGuid.js" verknüpft.
|
|
|
|
|
|
|
|
**Verknüpfung der angelegten Intents mit den Steps der Guided Tour in der uiHelper.js**
|
|
|
|
```
|
|
|
|
else {
|
|
|
|
if(tourPartsDb[intent]) {
|
|
|
|
showSingleTourStep(intent);
|
|
|
|
} else {
|
|
|
|
console.log("No intent found for tourstep", intent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Der Chatbot ist daher in der Lage, bei der Enttarnung eines gewissen Intents, das auf eine Interaktionsmöglichkeit mit dem Accelerator beruht, auch den entsprechenden Step der Guided Tour aufzuzeigen. Im folgenden Screenshot wird dies beispielhaft demonstriert.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 37: Chatbot als Guide durch Accelerator*
|
|
|
|
|
|
|
|
Da alle einzelnen Steps der Guided Tour, sowie auch alle Intents auch auf Englisch angelegt wurden, funktionieren die Funktionen selbstverständlich auch auf Englisch, wie im folgenden Screenshot demonstriert wird.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 38: Chatbot als internationaler Guide durch Accelerator*
|
|
|
|
|
|
|
|
|
|
|
|
-S-
|
|
|
|
|
|
|
|
## 4.9 E-Mail versenden - ToDo
|
|
|
|
Der Chatbot könnte Einladung-E-Mails an die Benutzer senden.
|
|
|
|
##### Usecase
|
|
|
|
Die Teilnehmer des Meetings befinden sich im Meeting-Raum und möchten einen weiteren Teilnehmer einladen. Sie bitten den Chatbot, eine E-Mail mit der Einladung an den gewünschten Teilnehmer zu versenden.
|
|
|
|
Dafür wurde ein Intent "E-Mail versenden" erstellt in dem der Chatbot die dafür benötigte E-Mail-Adresse abfragt.
|
|
|
|
* Benutzer: Bitte E-Mail versenden.
|
|
|
|
* Chatbot: Wie lautet die Sendeadresse?
|
|
|
|
* Benutzer: maxmusterman@musterbox.de
|
|
|
|
* Chatbot: Alles klar. Wird gemacht. Ich sende E-Mail an *$email.
|
|
|
|
|
|
|
|
Diese Idee kann erst dann realisiert werden, nachdem Anmeldevorgang eingeführt worden ist. In node.js kann die Funktion der Mailsendung mit dem Modul *nodemailer* realisiert werden. Der Intent-Code *E-Mail versenden* (siehe untent) soll in der Datei chatbot.js eingepflegt werden und auf die Server-Zugangsparameter in *config.js* zugreifen.
|
|
|
|
|
|
|
|
```
|
|
|
|
sessionClient
|
|
|
|
.detectIntent(request)
|
|
|
|
.then(responses => {
|
|
|
|
console.log('Detected intent');
|
|
|
|
const result = responses[0].queryResult;
|
|
|
|
console.log(` Query: ${result.queryText}`);
|
|
|
|
console.log(` Response: ${result.fulfillmentText}`);
|
|
|
|
if(result.intent.displayName=="E-Mail versenden") {
|
|
|
|
if(chtext.indexOf("Sendeadresse")!=-1){
|
|
|
|
|
|
|
|
}else if(chtext.indexOf("klar")!=-1){
|
|
|
|
var msgSplit = chtext.split(" ");
|
|
|
|
if(msgSplit.length>0){
|
|
|
|
var email = msgSplit[8];
|
|
|
|
transporter.sendMail({
|
|
|
|
from: mailAccountName,
|
|
|
|
to: chtext.split("/cb ")[1],
|
|
|
|
subject: "Accelerator Invitation",
|
|
|
|
text: "SENDMESSAGETEXT"
|
|
|
|
```
|
|
|
|
|
|
|
|
Bezüglich Server-Zugangsdaten bzw. ihre Änderung soll man sich an Raphael Fritsch, die zentrale Ansprechperson, anwenden.
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
## 4.10 Suchfunktion
|
|
|
|
Der Use Case dieser Funktion, war das ein Teilnehmer auf einer bestimmten Seite einen bestimmten Begriff suchen möchte. Die erste Umsetzungsidee war die Suchergebnisse innerhalb des Chats zu visualisieren. Hierbei gab es aber das Problem, das mehrere Informationen auf einmal darstellbar sein müsste und wir hierbei nicht wussten wie wir den Autor zusätzlich anzeigen konnten. Aus diesem Grund haben wir uns dazu entschieden statt dem Suchergebniss den fertigen Suchlink anzugeben. So werden dem Teilnehmer eine Reihe von Suchergebnissen angezeigt, die er auswählen kann. Hierbei wurde der Use Case mit Hilfe der drei folgenden Webseiten durchgeführt: Zeit.de, youtube.de und google.de. Die Restriktion war hierbei, das die Webseite ein Suchfeld haben musste. Die Funktion ist mit jeder beliebigen Webseite erweiterbar. Es wurden in der Iteration erstmal die drei Webseiten umgesetzt, da die Webseiten jeweils unterschiedliche Suchurls haben, was dazuführt, das der Suchlink sich anders zusammensetzt. In dem folgenden Abschnitt wird der Code der Funktion beschrieben.
|
|
|
|
|
|
|
|
**Darstellung der Suchfunktion in der uiHelper**
|
|
|
|
|
|
|
|
```
|
|
|
|
else if(intent == "specific search"){
|
|
|
|
if(text.indexOf("Seite")!=-1){
|
|
|
|
//do nothing
|
|
|
|
}else if(text.indexOf("suchen")!=-1){
|
|
|
|
//seiten stuff
|
|
|
|
}else if (text.indexOf("Webseite")!=-1){
|
|
|
|
var msgSplit = text.split(" ");
|
|
|
|
if(msgSplit.length>0){
|
|
|
|
var url = msgSplit[3];
|
|
|
|
var searchterm = msgSplit[8];
|
|
|
|
if(url.indexOf("zeit")!=-1){
|
|
|
|
var searchUrl = "www.zeit.de/suche/index?q="+searchterm;
|
|
|
|
}
|
|
|
|
else if(url.indexOf("youtube")!=-1){
|
|
|
|
var searchUrl = "www.youtube.com/results?search_query="+searchterm;
|
|
|
|
}
|
|
|
|
else if(url.indexOf("google")!=-1){
|
|
|
|
var searchUrl = "www.google.de/search?source=hp&ei=h9ZMWqqFJOWbgAaxt6_oCg&q="+searchterm+"&oq="+searchterm+"&gs_l=psy-ab.3..35i39k1j0j0i131k1j0l7.32711.33232.0.33385.9.6.0.0.0.0.173.467.0j3.3.0....0...1c.1.64.psy-ab..6.3.466.0...0.63GBfWzsnWM";
|
|
|
|
}
|
|
|
|
writeToChat("Chatbot", "Suchergebnis"+searchUrl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
In der ersten Zeile wird überprüft ober der Intent zu dem jeweiligen Intent in dialogflow passt. Der Intent wird durch die in der nachfolgenden Abbildung dargestellten Wörter ausgelöst. Diese Abfrage wurde in Dialogflow definiert.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 39: Darstellung der Specific Search Abfragen in Dialogflow*
|
|
|
|
|
|
|
|
Anschließend wurde nun nach den Parametern der präferierten Webseite sowie den gewünschten Suchterm abgefragt. Die Abfrage wird in der folgenden Abbildung visualisiert. Hierbei wird mit Hilfe der Frage "Auf welcher Seite wollen Sie suchen?" und "Nach was wollen Sie suchen?" die Parameter abgefragt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 40: Darstellung der Parameterabfrage in Dialogflow*
|
|
|
|
|
|
|
|
Nach der Abfrage wird nun der folgende String erstellt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 41: Darstellung der Antworten*
|
|
|
|
|
|
|
|
Der ausgegebene String wird dafür benutzt um innerhalb der Funktion die Parameter auszulesen. Der Link der zum Suchen auf den jeweiligen Seiten, wie zeit.de und google.de, benutzt wird wurde vorher herausgesucht. Innerhalb dieses Links wird nun der gewünschte Suchterm ergänzt. Nach dem Ablauf der Funktion hat der Anwender nun einen Suchlink zu dem von ihm gewünschten Suchbegriff
|
|
|
|
|
|
|
|
-E-
|
|
|
|
|
|
|
|
## 4.11 EasterEggs
|
|
|
|
|
|
|
|
### 4.11.1 Do a barrel roll
|
|
|
|
Der Google-Klassiker "do a barrel roll" kann auch vom Chatbot auf Accelerator gestartet werden. Hierzu einfach "do a barell roll" in den Chat eingeben. Auch kleine Schreibfehler sind hierbei erlaubt, da im Hintergrund ein intent hinterlegt wurde, der verschiedene Eingabevariationen hinsichtlich der "barrel roll" beinhaltet.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 40: Do a barrel roll*
|
|
|
|
|
|
|
|
|
|
|
|
**Definition des "do a barrel roll" intents in der uiHelper.js**
|
|
|
|
```
|
|
|
|
else if(intent == "Do a barrel roll"){
|
|
|
|
if(text.indexOf("Here")!=-1){
|
|
|
|
$({deg: 0}).animate({deg: 360}, {
|
|
|
|
duration: 6000,
|
|
|
|
step: function(now){
|
|
|
|
$("body").css({
|
|
|
|
transform: "rotate(" + now + "deg)"
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
-S-
|
|
|
|
|
|
|
|
### 4.11.2 Cat Attack
|
|
|
|
Da alle Easter-Eggs mit bestimmten Intents aufgerufen werden, sind sie als Code in der Datei *uiHelper.js* angelegt.
|
|
|
|
Ein ziemlich süßes Easter-Egg "Cat Attack" besteht darin, dass alle Bilder im Meeting-Raum, und zwar die Benutzerbilder, das Präsentationssymbol und das Chatbot-Symbol mit einem Kätzchenbild ersetzt werden. Die JavaScript-Funktion ist in den Intent "Cat Attack_GIG" eingepflegt. Das Easter-Egg kann der Benutzer mit dem folgenden Input aufrufen: "Miau", "Kitten Attack", "Cat Attack", "Kätzchen Attack", "Kätzchen Angriff". Der Effekt geht in 10 Minuten wieder weg.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 43: Darstellung des Easter Eggs Cat Attack*
|
|
|
|
|
|
|
|
```
|
|
|
|
else if(intent == "Cat Attack_GIG"){
|
|
|
|
if(text.indexOf("Wer")!=-1){
|
|
|
|
setTimeout(function(){
|
|
|
|
$(".kitten").removeClass("kitten"); //Remove kitten after 10Sec
|
|
|
|
}, 10000);
|
|
|
|
$("img").addClass("kitten");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
-D-
|
|
|
|
|
|
|
|
### 4.11.3 Destroy Page
|
|
|
|
Das Easter-Egg "Destroy Page" macht den Aufbau der Webseite kaputt. Nach dem Befehl "Destroy (the) page" werden die Elemente der Webseite schief und verschoben. In so einem "kaputten" Meeting-Raum kann man aber trotzdem weiter schreiben, was ziemlich lustig aussieht. Der Effekt geht in 10 Minuten wieder weg.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 44: Darstellung des Easter Eggs Destroy Page*
|
|
|
|
|
|
|
|
```
|
|
|
|
else if(intent == "destroy the page_GIG"){
|
|
|
|
if(text.indexOf("Sieht")!=-1){
|
|
|
|
$.each($('div,p,span,img,a,body'), function() {
|
|
|
|
setTimeout(function(){
|
|
|
|
$('div,p,span,img,a,body').css("transform", ""); //Remove transformation after 10Sec
|
|
|
|
}, 10000);
|
|
|
|
$(this).css("transform", 'rotate(' + (Math.floor(Math.random() * 3) - 1) + 'deg)')
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
-D-
|
|
|
|
### 4.11.4 Upside Down
|
|
|
|
In diesem Easter Egg wird der Bildschirm mit der Texteingabe "Upside Down" kopfüber gestellt. Solange der Bildschirm umgedreht ist, kann man im Chatfenster immer noch schreiben. In 10 Sekunden ist der Effekt wieder weg.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 45: Darstellung des Easter Egg Upside Down*
|
|
|
|
|
|
|
|
```
|
|
|
|
else if(intent == "upside down_GIG"){
|
|
|
|
if(text.indexOf("Können")!=-1){
|
|
|
|
setTimeout(function(){
|
|
|
|
$('body').css("transform", ""); //Remove upsidedown after 10Sec
|
|
|
|
}, 10000);
|
|
|
|
|
|
|
|
$('body').css("transform", 'rotate(180deg)');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
-D-
|
|
|
|
|
|
|
|
### 4.11.5 "Alexa" Easteregg
|
|
|
|
Dieses Easteregg spielt auf die missverständliche Erkennung von Befehlen des Chatbots Alexa von Amazon an. So wurden hierbei falsche Order getätigt, indem ein Papagei ["Geschenkpapier"](http://www.computerbild.de/artikel/cb-News-Panorama-Amazon-Alexa-Papagei-Buddy-bestellt-19035157.html) (Letzter Zugriff 27.01.2018) geordert hat oder ein kleines Mädchen ein [Pupenhaus](http://www.computerbild.de/artikel/cb-News-Internet-Alexa-Panne-Amazon-Echo-Puppenhaeuser-17145863.html) (Letzter Zugriff 27.01.2018) . Das Intent wurde mit Hilfe von Dialogflow und im Accelerator umgesetzt.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 46: Intent Easteregg*
|
|
|
|
|
|
|
|
In Dialogflow wurde die folgende Antwort definiert:
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 47: Intent Antworten*
|
|
|
|
|
|
|
|
Hierbei wird ein Bild eines über 1000 Euro [Laptops](https://www.amazon.de/Acer-Predator-PH317-51-75SD-Notebook-i7-7700HQ/dp/B0778FC3ND/ref=sr_1_1?ie=UTF8&qid=1517060400&sr=8-1&keywords=acer+predator+helios+300+ph317-51-75sd) (Letzter Zugriff 27.01.2018) angezeigt, der sich gerade in einem Warenkorb befindet. Wenn man nun die Wörter Bestellung stornieren eingibt verschwindet das Bild wieder und man kann den Accelerator wieder normal weiter benutzten. Um dies zu bewerkstelligen wurde im Accelerator der Intent "bestellung" angelegt. Der folgende Codesnipptet beinhaltet das Aufzeigen des Bildes und das Verschwinden des Bildes mit Hilfe der Intents.
|
|
|
|
|
|
|
|
**Darstellung des Alexa EasterEggs in der uiHelper.js**
|
|
|
|
|
|
|
|
```
|
|
|
|
else if (intent == "easterEggAlexa"){
|
|
|
|
if(text.indexOf("Ja")!=-1){
|
|
|
|
var caption = $('<div id="amazonCaption">'+
|
|
|
|
'<img src="./img/amazon_Bild.png" style="height: 550px; position: absolute; right: 3px; top: 0px;">'+
|
|
|
|
'</div>');
|
|
|
|
$(".praesiMainContent:visible").append(caption);
|
|
|
|
}
|
|
|
|
}else if (intent == "bestellung"){
|
|
|
|
if(text.indexOf("Bestellung wurde storniert")!=-1){
|
|
|
|
$("#amazonCaption").remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
### 4.11.6 Easter Egg Verweis auf ELIZA
|
|
|
|
Dieser Easter Egg verweist auf den Chatbot ELIZA. ELIZA war der erste Chatbot und wurde von Joseph Weizenbaum entwickelt. Wenn man im Chatfenster den Dialog startet und schreibt "Ich bin ängstlich" erwidert daraufhin der Chatbot mit Hilfe der folgenden Antwort:
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 48: Intent ELIZA Easter EGG*
|
|
|
|
|
|
|
|
Mit Hilfe des dargestellten Links kann man nun auf die Seite kommen, wo ELIZA visualisiert wird. Dieses Easteregg wurde komplett in Dialogflow entwickelt.
|
|
|
|
|
|
|
|
-E-
|
|
|
|
|
|
|
|
|
|
|
|
### 4.11.7 Badwords
|
|
|
|
Auch bei scharfen Zungen, zumindest wenn diese an den Chatbot gerichtet sind, agiert der Chatbot vorbildlich. Um einer naiven Schneeballschlacht aus dem Wege zu gehen, wird der entsprechende "giftige Teilnehmer" nach drei Sekunden aus dem Konferenzraum entfernt und gesteht automatisch im Chat an Alle ein, was er gemacht hat.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 49: Badwords*
|
|
|
|
|
|
|
|
|
|
|
|
**Verknüpfung von Intents und Funktion in der uiHelper.js**
|
|
|
|
```
|
|
|
|
else if(intent == "badwords" || intent == "badwordsEN"){
|
|
|
|
|
|
|
|
enableChatbot(false);
|
|
|
|
sendChatMsg(getLang("removedbychatbot"));
|
|
|
|
|
|
|
|
setInterval(function() {
|
|
|
|
window.location.replace(window.location.href.split("/?")[0]);
|
|
|
|
}, 3*1000)
|
|
|
|
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
**Codezeilen-Ergänzung in der langDb.js**
|
|
|
|
```
|
|
|
|
"de" : {
|
|
|
|
"removedbychatbot" : "Ich habe den Chatbot beleidigt und werde gleich aus dem Raum entfernt..."
|
|
|
|
}
|
|
|
|
|
|
|
|
"en" : {
|
|
|
|
"removedbychatbot" : "I've just insulted the Chatbot and that's why I'm getting kicked in a few seconds"
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
-S-
|
|
|
|
|
|
|
|
### 4.11.8 Intent mit viel "Wuff"
|
|
|
|
Steffen's Husky namens "Bonnie" versteckt sich im Accelerator. Doch wie gehorcht die Husky-Dame wohl?
|
|
|
|
|
|
|
|
Zur Realisierung der Funktion wurde die Husky-Dame freigestellt und die resultierende .png-Grafik auf 64 x 64 Pixel komprimiert. Diese Grafik wurde im GIT innerhalb dem Emoji-Ordner (accelerator\public\images\emoji) abgelegt und in der "emojify.min.js" an der entsprechenden Stelle referenziert. Zur Aktivierung der Funktion dient ein Intent, der auf Dialogflow angelegt wurde. Zusätzlich wurde ein lizenzfreier .mp3-Sound eines bellenden Hundes eingefügt (weil ein Husky leider sehr selten bellt) (Quelle: [Freesoundeffects.com](https://www.freesoundeffects.com/free-track/dog-89459/). Letzter Zugriff: 28.01.2018).
|
|
|
|
|
|
|
|
|
|
|
|
**Verknüpfung von Intent und Funktion in der uiHelper.js**
|
|
|
|
```
|
|
|
|
else if(intent == "Wuff"){
|
|
|
|
if(text.indexOf("husky")!=-1){
|
|
|
|
var audio = new Audio('./sounds/dog.mp3');
|
|
|
|
audio.play();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Das Husky-Emoticon selbst kann mit der Eingabe **:husky:** im Chat erzeugt werden.
|
|
|
|
|
|
|
|
-S-
|
|
|
|
|
|
|
|
|
|
|
|
# 5 Systemarchitektur Chatbot
|
|
|
|
Die [Systemarchitektur von Accelerator](http://git.reutlingen-university.de/ksystem/Accelerator/wiki/Systemarchitektur) (Letzter Zugriff: 28.01.2018) wurde durch die Integration des Chatbots etwas erweitert, wie die folgende Abbildung zusammenfassend darstellen soll.
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
*Abbildung 50: Systemarchitektur Chatbot*
|
|
|
|
|
|
|
|
-S-
|
|
|
|
|
|
|
|
|
|
|
|
|