npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@botfabrik/engine-webclient

v4.109.6

Published

Webclient for Botfabriks Bot Engine

Readme

Webclient

Der Webclient kann Anfragen via Webbrowser entgegennehmen und darauf antworten.

Name

Der Name des Clients ist zugleich die Adresse unter welcher er deployed wird.

Beispiel:

bot.addClient(Webclient('acme-webclient', webclientProps));

Der Webclient wird auf http://meinserver.ch/acme-webclient deployed.

Properties

Nachfolgende Properties können dem Client mitgegeben werden:

getStartedAction (optional)

Action die ausgeführt wird, wenn der Client das erste mal aufgerufen wird.

enableStartScreen (optional)

Legt fest, ob vor dem Beginn eines neuen Chats ein Startbildschirm angezeigt wird. Dieser ist besonders nützlich, wenn vom Benutzer eine ausdrückliche Zustimmung, wie beispielsweise die Akzeptanz der Nutzungsbedingungen, erforderlich ist.

Der Startbildschirm ist in drei Breiche unterteilt:

Einleitung

Die Einleitung wird durch einen Text repräsentiert, der via Übersetzungs-Key start-screen.intro konfiguriert werden kann. Der Text kann mit Markdown formatiert werden.

Formular

Optional kann unterhalb des Bodies ein Formular integriert werden. Dies kann u.A. verwendet werden, um Informationen über den Benutzer abzufragen, bevor ein Chat gestartet wird. Die Konfiguration des Formulars wird via Übersetzungs-Keys gemacht.

Anzuzeigende Felder

Via Übersetzungs-Key start-screen.form.fields wird bestimmt, welche Felder im Formular angezeigt werden sollen. Die Namen der Felder werden durch ; Getrennt definiert.

Beispiel start-screen.form.fields : name;email;accept

Danach wird pro Feld ein Objekt definiert, das als Key den Feldname und als Value ein Objekt mit folgende Attributen enthalten kann:

| Attribut | Zwingen / Optional | Mögliche Werte | Beschreibung | | ------------ | ---------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | | type | zwingend | text, email, tel, number, date, time, datetime-local, week, month, password, radio, checkbox, select | Bestimmt das Aussehen und Verhalten des Feldes. | | name | zwingend | | Name des Feldes | | label | zwingend | Text | Label das beim Feld angezeigt wird | | placeholder | optional | Text | Platzhalter, u.A. bei Texteingaben | | defaultValue | optional | | Standardwert | | options | zwingend bei Type radio und select | z.B. man:Mann;woman:Frau | Bestimmt die Radio Buttons die angezeigt werden | | required | optional | 'true' oder 'false' | Bestimmt, ob das Feld zwingend ausgefüllt werden muss | | min | optional | eine Zahl als String | siehe https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#min | | max | optional | eine Zahl als String | siehe https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#max | | pattern | optional | Gültiges Regex Pattern | siehe https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#pattern |

Beispiel:

"start-screen": {
  "form": {
    "fields": "email;accept",
    "email": {
        "label": "E-Mail",
        "type": "email",
        "placeholder": "Deine E-Mail-Adresse.",
        "required": "true"
    },
    "accept": {
        "label": "Ich akzeptiere die Nutzungsbedingungen",
        "type": "checkbox",
        "required": "true"
    },
  }
}
Fromulardaten nutzen

Die Formulardaten werden in der Session-Info des Benutzers gespeichert, nachdem er den "Start-Chat-Button" klickt.

Pfad: sessionInfo.client.payload.querystrings

Beispiel:

{
  client: {
    payload: {
      querystrings: {
        "email": "[email protected]",
        "accept: "true",
      }
    }
  }
}

Start-Chat-Button

Zuunterst im Startbildschirm wird der Start-Chat-Button angezeigt. Das Label kann via Übersetzungs-Key start-screen.start-chat konfiguriert werden kann. Klickt der Benutzer auf den Button, verschwindet der Startbildschirm und der Chat beginnt mit der Begrüssung des Chatbots.

Es werden keine Benutzerdaten erfasst, bis der Benutzer durch den Klick auf den Button den Chat startet.

commands (optional)

Eine Liste von Befehlen, die der Chatbot unterstützt.

Beispiel:

  commands: ['summarise', 'optimize']

Wenn der Benutzer eine neue Nachricht mit / beginnt, werden ihm die konfigurierten Befehle zur Auswahl gegeben. Wichtig ist, dass der Chatbot diese Befehle dann auch interpretiert.

Mittels Übersetzungsdatei kann pro Befehl eine Beschreibung hinterlegt werden.

Beispiel

{
  "commands": {
    "summarise": "Fasst den nachfolgenden Text präzise und verständlich zusammen.",
    "optimize": "Optimiert den nachfolgenden Text hinsichtlich Rechtschreibung, Grammatik und Stil."
  }
}

menuItems (optional)

Eine Liste von projektspezifischen Einträgen, die im Chat-Menü angezeigt werden sollen.

requestUserInfos (optional)

Diese Funktion wird beim Erzeugen eines neuen Session Records aufgerufen. Man hat damit die Möglichkeit, die Session Daten unter session.getSessionInfo().user projektspezifisch anzupassen.

Die Funktion erhält als Parameter sämtliche Querystrings in Form eines JSON Objektes. Als Resultat wird wiederum ein JSON Objekt erwartet. Alle Werte unter session.getSessionInfo().user werden damit überschrieben.

Beispiel:

export default async (querystrings: any): Promise<any> => {
  const accessToken = querystrings.accessToken;
  const userProfile: UserProfile = await fetchUserProfile(accessToken);

  return {
    id: userProfile.username + '@' + userProfile.domain,
    displayName: userProfile.firstName + ' ' + userProfile.lastName,
    payload: userProfile,
  };
};

requestSessionRecordQuery (optional)

Diese Funktion wird aufgerufen, wenn sich der Webclient via Websocket verbindet. Sie erlaubt, das zuordnen des Session Records projektspezifisch zu steuern.

UseCase: Der Webclient ist in einer Webseite integriert, an der sich die Benutzer anmelden müssen (z.B. mittels OAuth). Das Access Token wird dem Webclient via Query Parameter mitgegeben.

In der Funktion requestSessionRecordQuery suchen wir nun anhand des Access Tokens den angemeldeten Benutzer und suchen anhand des Benutzernamens seinen Session Record in der DB. Dadurch können wir dem Benutzer, unabhängig vom Gerät an dem er sich anmeldet, den Chatverlauf anzeigen.

Beispiel:

export default async (querystrings: any): Promise<any> => {
  const accessToken = querystrings.accessToken;
  const userProfile: UserProfile = await fetchUserProfile(accessToken);
  return {
    'sessionInfo.user.id': userProfile.username + '@' + userProfile.domain,
  };
};

speech (optional)

Aktiviert die Sprachsteuerung

Folgende Parameter müssen mitgegeben werden:

  • clientEmail
  • privateKey

Folgende Parameter sind optional:

  • contextPhrases: Hier können Wörter und Sätze angegeben werden, welche in diesem Kontext häufig verwendet werden. So kann z.B. sichergestellt werden, dass bei der Umwandlung von Sprache zu Text "Botfabrik" und nicht "Brotfabrik" rauskommt. Texte können pro Locale erfasst werden.

Beispiel:

const webclientProps = {
  getStartedAction: requestNLUEvent('WELCOME'),
  speech: process.env.GOOGLE_CLOUD_SPEECH_PRIVATE_KEY
    ? {
        clientEmail: process.env.GOOGLE_CLOUD_SPEECH_CLIENT_EMAIL || '',
        privateKey: process.env.GOOGLE_CLOUD_SPEECH_PRIVATE_KEY || '',
        contextPhrases: {
          de: ['Bot', 'Was ist die Botfabrik?', 'Botfabrik'],
        },
      }
    : undefined,
};
bot.addClient(Webclient('webclient', webclientProps));

expandChatWindowAtStart (optional)

Mit diesem Property kann gesteuert werden, ob das Chatfenster beim Aufruf der Webseite automatisch geöffnet werden soll. Standardmässig ist das Fenster geschlossen.

Beispiel:

const webclientProps = {
  getStartedAction: requestNLUEvent('Welcome'),
  expandChatWindowAtStart: Devices.Desktop,
};
bot.addClient(Webclient('webclient', webclientProps));

enableTranscriptExportEmail (optional, true | false [default])

Erlaubt es, den Chatverlauf an eine Email-Adresse zu verschicken. Idealerweise wird dazu die Middleware @botfabrik/engine-transcript-mail verwendet.

Beispiel:

import { requestNLUEvent } from '@botfabrik/engine-domain';

const webclientProps = {
  getStartedAction: requestNLUEvent('WELCOME'),
  enableTranscriptExportEmail: true,
};

bot.addClient(Webclient('webclient', webclientProps));

enableTranscriptExportPdf (optional, true | false [default])

Erlaubt es, den Chatverlauf als PDF herunterzuladen. Siehe auch @botfabrik/engine-transcript-export.

Beispiel:

const webclientProps = {
  enableTranscriptExportPdf: true,
};

bot.addClient(Webclient('webclient', webclientProps));

enableGeneralConditions (optional, true | false [default])

Mit dieser Option können allgemeine Bedingungen zu Beginn des Chats angezeigt werden.

Beispiel:

import { requestNLUEvent } from '@botfabrik/engine-domain';

const webclientProps = {
  getStartedAction: requestNLUEvent('WELCOME'),
  enableGeneralConditions: true,
};

bot.addClient(Webclient('webclient', webclientProps));

Die Bedingungen beinhalten drei Elemente:

  • Header: Titel der Bedingungen
  • Body: Eigentlicher Inhalt der Bedingungen
  • Accept-Condition-Note: Hinweis, dass man die Bedingungen akzeptiert, sobald man mit dem Bot kommuniziert.

Diese Texte können auch Markdown beinhalten. Um die Standardtexte zu überschreiben, kann man den Übersetzungsmechanismus verwenden.

enableConversationRating (optional, true | false [default])

Ist dieses Property aktiviert, so können Benutzer den Chat mittels Stärnchen bewerten. Durch das Bewerten des Chats wird die Action core.conversation.rating.from.guest ausgelöst. Die Bewertung wird in Bubble Chat gespeichert (sofern die Middleware aktiv ist).

enableStandaloneView (optional, true | false [default])

Ermöglicht die Option, den Chat-Client in einem eigenständigen Tab oder Fenster zu öffnen. Wenn diese Option auf true gesetzt ist, wird eine Button angezeigt, die es den Benutzern ermöglicht, den Chat ausserhalb eines eingebetteten Iframe in einem neuen Browser-Tab öffnen können.

### auth (optional)

Diese Konfiguration stellt sicher, dass sich Benutzer vor der Nutzung des Chats über SAML authentifizieren. Ist die Funktion aktiviert, erscheint automatisch der Startbildschirm. Beim Klick auf „Chat starten“ öffnet sich das Login-Fenster des Identity Providers in einem neuen Fenster. Nach erfolgreicher Anmeldung schliesst sich dieses automatisch und der Chat wird gestartet. Im Rahmen des Logins werden die E-Mail-Adresse sowie der Vor- und Nachname des Benutzers in der Session gespeichert.

fabVisible (optional, true [default] | false)

Falls dieses Property auf false ist, erscheint z.B. der FAB (Floating Action Button) auf der Webseite nicht. Der Chatbot kann via FAB nur mittels Bookmarklet verwendet werden. Diese Einstellung ist nützlich, wenn der Chatbot noch in Entwicklung ist und die Webagentur ihn bereits in der Webseite integrieren will. Wir können damit steuern, ob er auf der Webseite sichtbar ist oder nicht.

Texte / Übersetzungen anpassen

Sämtliche Texte des Webclients können angepasst werden. Dazu müssen im Bot-Projekt die Locale-Dateien modifiziert werden. Die anzupassenden Texte sind unter website-messenger aufzuführen.

Beispiel (de.json)

{
  "website-messenger": {
    // Texte die für alle Client-Instanzen gelten
    "defaults": {
      "page.title": "Apptiva Chatbot",
      "message-input-label": "Nachricht eingeben ...",
      "export-transcript": {
        "email": {
          "title": "Konversation per E-Mail versenden",
          "description": "Geben Sie Ihre E-Mail-Adresse ein, um den Chatverlauf zu erhalten.",
          "cancel": "Abbrechen",
          "send": "Senden",
          "placeholder": "Ihre E-Mail-Adresse",
          "invalid": "Bitte gültige E-Mail-Adresse eingeben.",
          "success": "Ich habe den Chatverlauf an Ihre E-Mail-Adresse gesendet."
        },
        "pdf": {
          "title": "Konversation als PDF",
          "description": "Laden Sie die Konversation als PDF herunter.",
          "cancel": "Abbrechen",
          "download": "Herunterladen"
        }
      }
    },
    "overrides": {
      // Texte die nur für die Client-Instanz `webclient` gelten
      "webclient": {
        "general-conditions": {
          "header": "**Nutzungsbedingungen**", // Wird hier der Text leer gelassen, wird der Header inkl. Body nicht angezeigt.
          "body": "Bitte berücksichtigen Sie die folgenden Punkte:\n\n - ...",
          "accept-conditions-note": "Mit der Verwendung des Chats erklären Sie sich mit den Nutzungsbedingungen einverstanden." // Wird hier der Text leer gelassen, so wird dieses Element nicht angezeigt.
        },
        "powered-by": "Bubble Chat by [Apptiva](https://apptiva.ch)"
      }
    }
  }
}

Anpassungen am Aussehen

Das Aussehen des Webclients kann pro Projekt angepasst werden. Dazu kann eine eigene CSS Datei namens 'custom.css' im Verzeichnis public/\${name-meines-webclients}/ abgelegt werden. Auf gleiche Art und Weise können auch der FAB (fab.svg), der Bot-Avatar (bot.svg) sowie das Logo (logo.svg) angepasst werden.

### Favicon

Um ein eigenes Favicon zu haben, müssen folgende Dateien im Chatbot Projekt hinterlegt werden:

  • apple-touch-icon.png
  • favicon-96x96.png
  • favicon.ico
  • favicon.svg
  • web-app-manifest-192x192.png
  • web-app-manifest-512x512.png

Favicons können z.B. mittels https://realfavicongenerator.net/ generiert werden.

Standard CSS Variabeln

:root {
  --aspect-ratio: calc(16 / 9);
  --brand-primary-color: rgb(4, 47, 97);
  --brand-secondary-color: white;
  --danger-color: #cd2147;

  /* FAB */
  --fab-size: 6em;
  --fab-size-mobile: var(--fab-size, 5em);
  --fab-top: auto;
  --fab-top-mobile: var(--fab-top, auto);
  --fab-right: 1.5em;
  --fab-right-mobile: var(--fab-right, 1.5em);
  --fab-bottom: 1.5em;
  --fab-bottom-mobile: var(--fab-bottom, 1.5em);
  --fab-left: auto;
  --fab-left-mobile: var(--fab-left, auto);

  /* Text */
  --text-primary-color: var(--color-gray-800);
  --text-secondary-color: var(--color-gray-500);
  --text-link-color: var(--text-primary-color);
  --text-link-color-hover: var(--brand-primary-color);

  /* chat window */
  --window-top: auto;
  --window-right: 1em;
  --window-bottom: 1em;
  --window-left: auto;
  --window-height: 46em;
  --window-max-height: calc(100vh - 2em);
  --window-width: 26em;
  --window-border-radius: 8px;
  --header-height: 4em;
  --header-background-color: var(--brand-primary-color);
  --header-logo-url: url('../logo.svg');
  --header-logo-padding: 1em;
  --header-icons-padding: 1rem 0.75rem;
  --header-icon-size: 1.5rem;
  --header-icon-color: white;

  /* chat body */
  --body-background-color: white;

  --avatar-size: 2rem;
  --avatar-radius: 50%;
  --bot-avatar-display: initial;
  --bot-avatar-background-color: rgb(233, 239, 246);
  --agent-avatar-background-color: rgb(233, 239, 246);

  --bubble-padding: 0.9em 1.3em;
  --bubble-margin-small: 3px;
  --bubble-margin-large: 1.2rem;
  --bubble-radius-large: 20px;
  --bubble-radius-small: 4px;

  --bot-bubble-background-color: white;
  --bot-bubble-text-color: #2e2e2e;
  --bot-bubble-border-color: #434343;
  --bot-bubble-border-width: 2px;
  --bot-bubble-top-left-radius: var(--bubble-radius-small);
  --bot-bubble-top-right-radius: var(--bubble-radius-large);
  --bot-bubble-bottom-right-radius: var(--bubble-radius-large);
  --bot-bubble-bottom-left-radius: var(--bubble-radius-small);
  --bot-bubble-source-background-color: var(--body-background-color);
  --bot-bubble-source-text-color: var(--bot-bubble-text-color);


  --guest-bubble-background-color: var(--brand-primary-color);
  --guest-bubble-text-color: white;
  --guest-bubble-border-color: white;
  --guest-bubble-border-width: 0px;
  --guest-bubble-top-left-radius: var(--bubble-radius-large);
  --guest-bubble-top-right-radius: var(--bubble-radius-small);
  --guest-bubble-bottom-right-radius: var(--bubble-radius-small);
  --guest-bubble-bottom-left-radius: var(--bubble-radius-large);
  --guest-bubble-command-background-color,
    rgba(255, 255, 255, 0.3);

  --scrollbar-thumb-color: #bfbfbf;

  /* commands */
  --commands-background-color: var(--brand-primary-color);
  --commands-text-color: white;
  --commands-active-background-color: rgba(255, 255, 255, 0.3);
  --commands-active-text-color: white;
}

CSS Klassenname via IFrame URL übergeben

Mithilfe des Query-Parameters cssClassName kann dem Chatclient ein CSS Klassenname mitgebeben werden. Damit lässt sich das Aussehen des Chatclients via URL beeinflussen.

Kleiner / grosser Chat-Client

Ab einer Fensterbreite von 1024 Pixel wechselt das Design in einen "Grosser Chat-Client" Modues. Hier können u.A. Informationen zu den verwendeten Quellen angezeigt werden.

Um das Aussehen abhäng der Grösse beeinflussen zu können, werden folgende beide CSS Klassen gesetzt:

  • chat__small bei einer Fensterbreite unter 1024 Pixel
  • chat__large ab einer Fensterbreite von 1024 Pixel

Möchte man also z.B. beim grossen Client ein anderes Logo verwenden, kann man dies wie folgt machen:

.chat__large {
  --header-logo-url: url('/chatbot/logo-blue.svg');
  --header-height: 6em;
}

Einbinden auf einer Webseite

Unter der Chatbot-Route unter "/embed/ des Servers (z.B. http://localhost:3000/chatbot/embed) läuft einen Beispielseite wie der Chatbot eingebetet werden kann. Dort gibt es ebenfalls einen Button, mit welchem das benötigte Snippet angezeigt werden kann. Das Aussehen kann im File /public/webclient/embed/custom.css jegliches CSS überschreiben (siehe Beispiel).

Strategie zur Speicherung des Chatverlaufs

Sämtliche Actions, die die Botengine ausführt, werden in der Datenbank gespeichert. Damit kann jeder beliebige Chatverlauf zu einem späteren Zeitpunkt wiederhergestellt werden.

Verbindet sich der Webclient mit dem Backend, so wird der Chatverlauf von der DB gelesen und an den Client übermittelt.

Webclient lokal entwickeln

Nur Client-Teil mit Hot-Reloading

Um den Client-Teil des Webclients mit Hot-Reloading lokal zu entwickeln, kannst du wie folgt vorgehen:

  1. Das Chatbot-Projekt starten, welches die Chatbot-Engine verwendet.
  2. In socketMiddleware.js in io('/bf-webclient?' + action.querystrings); die absolute URL des gestarteten Chatbot-Projekts hinzufügen. Z.B. io('http://localhost:3333/bf-webclient?' + action.querystrings);
  3. In der Root der Chatbot-Engine npm i && npm run bootstrap ausführen
  4. In die Root des Webclient-Packages in der Engine wechseln und dort npm start ausführen.
  5. Im Browser http://localhost:8080/dist/client/ öffnen

Client- und Server-Teil des Webclients

Um den Server- und Client-Teil des Webclients lokal zu entwickeln (leider ohne Hot-Reloading), kannst du wie folgt vorgehen:

  1. In der Root der Engine npm i && npm run bootstrap ausführen
  2. In die Root des Webclient-Packages in der Engine wechseln und dort npm link ausführen.
  3. Das Chatbot-Projekt offnen, welches die Chatbot-Engine verwendet und dort npm link @botfabrik/engine-webclient ausführen.
  4. Nun das Chatbot-Projekt starten mit npm start
  5. Bei Änderungen an der Engine muss jeweils im Ordner des Webclient-Packages npm run build ausgeführt werden und das Projekt neu gestartet werden mit npm start.

Embed

Um nur die Embed-Seite zu entwickeln, kann ein lokaler Server ohne Konfiguration gestartet werden:

  1. In das Verzeichnis des Webclient wechseln (packages/engine-webclient)
  2. npm run dev:embed
  3. localhost:3000/ im Browser öffnen
  4. ./src/views/index.ts bearbeiten
  5. Refresh im Browser (CMD-R)

Google Speech-to-Text API

Das Google-Speech-to-Text API muss für das entsprechende Projekt aktiviert werden. Zudem muss der Service Account über die entsprechenden Rollen verfügen. Siehe: https://cloud.google.com/speech-to-text/docs/quickstart-client-libraries?hl=de https://ctrlq.org/code/20550-cloud-speech-api-with-service-account

Javascript API

Der Webclient bietet ein API an, über welches der Chat gesteuert werden kann. Die API Funktionen stehen via Namespace chatbot zur Verfügung.

openChatWindow

Öffnet das Chat Fenster.

Beispiel:

chatbot.openChatWindow();

closeChatWindow

Schliesst das Chat Fenster.

Beispiel:

chatbot.closeChatWindow();

toggleChatWindow

Öffnet das Chatfenster wenn es geschlossen ist und schliesst es, wenn es offen ist.

Beispiel:

chatbot.toggleChatWindow();

enterGuestMessage

Sendet eine Nachricht im Namen des Gastes an den Chatbot.

Beispiel:

chatbot.enterGuestMessage("Hallo Welt");

triggerStory

Gibt den Befehl, eine Story (Intent) auszuführen.

Beispiel:

chatbot.triggerStory("GET_STARTED");

isChatbotLoaded

Gibt true zurück, wenn der Chatbot geladen und der FAB sichtbar ist.

Beispiel:

const isLoaded = chatbot.isChatbotLoaded();

subscribe

Erlaub das Registrieren von Event-Handlers.

ON_CHAT_WINDOW_STATE_CHANGE

chatbot.subscribe('ON_CHAT_WINDOW_STATE_CHANGE', function onChange(open) {
    console.log('chat window is ' + open ? 'open' : 'close')
})