HelpStackDocs

Integrationen

Widget-Einbettung

Binden Sie das HelpStack-Web-Chat-Widget mit einem einzigen Script-Tag auf jeder beliebigen Website ein.

Kurzüberblick#

Loaderhttps://helpstack.eu/widget.js
AuthentifizierungKeine — Widget-Endpunkte sind öffentlich
TransportSocket.IO (primär) + REST-Fallback
KanaltypWEBSITE_CHAT
Rate-Limit~30 Anfragen/Min./IP für config/FAQ/status; ~20 Nachrichten/Min./Besucher für den HTTP-Nachrichten-Fallback
UrsprungskontrolleOptionale kanalspezifische Domain-Allowlist (403 bei nicht erlaubtem Ursprung)

Der Loader leitet seine baseUrl vom Ursprung seines eigenen <script src> ab, sodass das von helpstack.eu ausgelieferte widget.js automatisch mit HelpStack kommuniziert — es ist keine weitere Konfiguration erforderlich.

Einbettungs-Snippet#

<script src="https://helpstack.eu/widget.js?id=CHANNEL_ID" async></script>

CHANNEL_ID ist die ID Ihres WEBSITE_CHAT-Kanals. Der Loader wird automatisch über den ?id=-Query-Parameter initialisiert — es ist kein zusätzliches JavaScript erforderlich.

Wo Sie die CHANNEL_ID finden#

Gehen Sie im Dashboard zu Einstellungen → Kanäle, öffnen (oder erstellen) Sie einen Website-Chat-Kanal und kopieren Sie dessen ID über die Schaltfläche zum Kopieren neben dem Kanal. Diese ID übergeben Sie als ?id=CHANNEL_ID.

Wie der Loader funktioniert#

  1. Das Script liest seinen eigenen <script src>, um Folgendes zu ermitteln:
    • baseUrl — den Ursprung des Scripts (z. B. https://helpstack.eu)
    • channelId — den ?id=-Query-Parameter
  2. Es fügt eine schwebende Chat-Blase und ein <iframe> ein, das auf Folgendes verweist:
    {baseUrl}/widget/{channelId}?visitorId={visitorId}
    
  3. Das iframe öffnet eine Socket.IO-Verbindung für Echtzeit-Messaging, mit einem HTTP-Fallback, wenn WebSocket nicht verfügbar ist.

Besucheridentität#

Der Loader generiert eine persistente Besucher-ID, die in localStorage gespeichert wird:

SchlüsselWertformat
chat_widget_visitor_idvisitor_<uuid>

Dieselbe visitorId wird über Seitenladevorgänge und Sitzungen in diesem Browser hinweg wiederverwendet, sodass ein wiederkehrender Besucher wieder mit seinem bestehenden Gespräch verbunden wird. Das Leeren von localStorage (oder ein anderer Browser/ein anderes Gerät) erzeugt einen neuen Besucher und einen neuen Gesprächs-Thread.

Programmatische API#

Der Loader stellt ein globales window.ChatWidget-Objekt bereit:

window.ChatWidget.init('CHANNEL_ID'); // manuell initialisieren (wenn nicht ?id= verwendet wird)
window.ChatWidget.open();             // Chat-Panel öffnen
window.ChatWidget.close();            // Chat-Panel schließen
window.ChatWidget.toggle();           // zwischen geöffnet/geschlossen umschalten

Für die verzögerte Form im Snippet-Kommentar steht auch ein Befehls-Queue-Helfer zur Verfügung:

window.chat('init', 'CHANNEL_ID');

Identifizieren Sie jederzeit, mit wem Sie sprechen, damit die KI nicht danach fragen muss:

window.ChatWidget.identify({ name: 'Ana Novak', email: 'ana@example.com' },
                           { plan: 'pro', account_id: '1234' });

Registrieren Sie ein clientseitiges Agent-Tool, damit die KI Code auf Ihrer Seite aufrufen kann:

window.HelpStack('registerTool', 'highlight', async ({ section }) => {
  document.querySelector(`#${section}`)?.scrollIntoView({ behavior: 'smooth' });
  return { highlighted: section };
});

Was der Handler zurückgibt, ist das, was die KI liest. Intern sendet das Widget-iframe TOOL_EXECUTE per postMessage an das übergeordnete Fenster und wartet auf ein TOOL_RESULT oder TOOL_ERROR mit derselben callId; registerTool beantwortet das für Sie. Für einen Tool-Namen ohne Handler bleibt das Widget stumm, sodass ein eigener bestehender message-Listener weiterhin funktioniert. Siehe Benutzerdefinierte Agent-Tools.

Erscheinungsbild-Konfiguration#

Das Erscheinungsbild wird im Dashboard oder über MCP konfiguriert (get_widget_config / update_widget_config, siehe MCP), nicht über den Einbettungs-Snippet. Das Widget ruft die Konfiguration vom Server ab (GET /api/widget/[channelId]/config) und wendet sie über CSS-Variablen an. Verifizierte konfigurierbare Felder:

FeldHinweise
primaryColorHex-Farbe. Standard #247f7c (das Marken-Türkis)
positionbottom-right | bottom-left | top-right | top-left
mobilePositionGleiche Aufzählung wie position, wird auf mobilen Viewports angewendet
bubbleIconTypecustom oder ein voreingestellter Typ
bubbleIconNameEines von: message, help, smile, headphone, zap, heart
bubbleOffsetXHorizontaler Versatz der Blase
bubbleOffsetYVertikaler Versatz der Blase
greetingMessageBegrüßungstext, der beim Öffnen des Panels angezeigt wird
avatarUrlMitarbeiter-/Marken-Avatar
showOnlineStatusOb der Online-/Offline-Status angezeigt werden soll
offlineMessageNachricht, die angezeigt wird, wenn der Kanal offline ist
productCardsProduktlinks in Antworten als Karten anzeigen. Standard true. Siehe Produktkarten

Öffentliche Widget-Endpunkte#

Alle Endpunkte sind öffentlich (keine Authentifizierung) und per IP/Besucher rate-limitiert.

MethodePfadZweck
GET/api/widget/[channelId]/configWidget-Konfiguration (Farben, Position, Begrüßung, Avatar, Status). ~30 Anfragen/Min./IP
GET/api/widget/[channelId]/faqsBis zu 5 FAQ-Chips für die Begrüßung. ~30 Anfragen/Min./IP
GET/api/widget/[channelId]/statusOb der Kanal aktuell online ist
POST/api/widget/[channelId]/uploadmultipart/form-data-Datei-Upload
POST/api/widget/messageHTTP-Fallback zum Senden einer Nachricht, wenn WebSocket nicht verfügbar ist. ~20 Nachrichten/Min./Besucher

Upload-Antwort (POST /api/widget/[channelId]/upload):

{
  "storagePath": "...",
  "publicUrl": "...",
  "fileName": "...",
  "fileSize": 12345,
  "contentType": "image/png",
  "width": 800,
  "height": 600
}

width und height sind nur bei Bildern vorhanden.

Nachrichten-Fallback (POST /api/widget/message) — Anfrage-Body:

{
  "channelId": "CHANNEL_ID",
  "visitorId": "visitor_<uuid>",
  "content": "Hello, I need help",
  "visitorInfo": {
    "userAgent": "...",
    "currentUrl": "https://example.com/pricing",
    "referrer": "https://google.com"
  }
}

visitorInfo ist optional, ebenso metadata (dasselbe optionale Envelope, das auch das Socket-Event join akzeptiert). Der Kanal muss vom Typ WEBSITE_CHAT sein, sonst wird die Anfrage abgelehnt. Bei Erfolg enthält das data-Feld des Antwort-Envelopes { messageId, conversationId, createdAt }. Die Konversation eines Besuchers wird mit seiner ersten Nachricht angelegt; der erste erfolgreiche Aufruf ist also der Moment, in dem conversationId entsteht, spätere Aufrufe desselben Besuchers verwenden sie wieder.

Echtzeit-Ereignisse (Socket.IO)#

Das iframe kommuniziert mit dem Server über Socket.IO.

Widget → Server

EreignisPayload
joinchannelId, visitorId, visitorInfo { userAgent, currentUrl, referrer }
messageAusgehende Besucher-Nachricht
typingBesucher-Tippindikator
heartbeatPräsenz-Keep-Alive
tool:resultErgebnis einer clientseitigen Tool-Ausführung
tool:errorFehler einer clientseitigen Tool-Ausführung

Server → Widget

EreignisPayload
joinedconversationId, erste messages, Widget-config, faqs. Eine Konversation wird erst angelegt, wenn der Besucher seine erste Nachricht sendet; bei einem neuen Besucher ist conversationId daher null und messages leer, ein wiederkehrender Besucher mit offener Konversation erhält deren Id und Verlauf. Verlassen Sie sich vor der ersten Nachricht nicht auf die Id.
messageNeue Mitarbeiter-Nachricht
agent_typingMitarbeiter-Tippindikator
tool:executeAnforderung zur Ausführung eines clientseitigen Tools im Browser

Produktkarten#

Wenn eine Antwort auf eine Produktseite Ihres Shops verlinkt, zeigt das Widget den Link als Karte an: Bild, Name, Preis, Lagerbestand und eine Schaltfläche In den Warenkorb. Das funktioniert wie eine Linkvorschau und braucht keine Einrichtung. KI-Antworten, freigegebene Entwürfe und Antworten Ihres Teams bekommen alle Karten.

Produktkarten unter einer Chat-Antwort und dieselbe Karte nach dem Tippen auf In den Warenkorb
Produktkarten unter einer Chat-Antwort und dieselbe Karte nach dem Tippen auf In den Warenkorb

Woher die Daten kommen. Wenn die Antwort zugestellt wird, öffnet HelpStack die verlinkte Seite und liest die Produktdaten, die Ihr Shop bereits für Suchmaschinen veröffentlicht: strukturierte Daten nach schema.org Product (JSON-LD oder Microdata), ersatzweise die Open-Graph-Tags (og:title, og:image, product:price:amount). WooCommerce gibt sie standardmäßig aus, die meisten Shopify-Themes ebenfalls. Die Karte entsteht nie aus dem Antworttext, die KI kann also keinen Preis erfinden: Ein Link, der nicht lädt, oder eine Seite, die kein Produkt ist (eine Versandseite, ein Blogartikel), bleibt ein normaler Link.

Verbundene Shopify-Shops werden über die Shopify Admin API statt über die Seite gelesen: Preis, Bestand und Varianten kommen direkt von Shopify, und das funktioniert auch bei einem passwortgeschützten Entwicklungsshop.

Welche Links geöffnet werden. Nur Links auf Ihren eigenen Websites: die Domain-Allowlist des Widgets, die Seite, auf der der Besucher ist, und ein verbundener Shopify- oder WooCommerce-Shop. Jede Anfrage läuft durch denselben Schutz vor privaten Adressen wie benutzerdefinierte Tools, auch bei Weiterleitungen. Seiten werden eine Stunde zwischengespeichert, ein beliebtes Produkt kostet also eine Anfrage pro Stunde.

Grenzen. Höchstens 3 Karten pro Antwort. Antwortet Ihr Shop nicht innerhalb weniger Sekunden, wird die Antwort ohne Karten gesendet statt verspätet.

Die Schaltflächen

Eine Karte hat bis zu zwei Schaltflächen. Die erste ist:

SituationHauptschaltfläche
Nicht vorrätigNicht vorrätig (deaktiviert)
Der Besucher muss zuerst eine Größe oder Farbe wählenOptionen wählen: öffnet die Produktseite
Ihre Seite kann es in den Warenkorb legenIn den Warenkorb
SonstProdukt ansehen

Die zweite Schaltfläche ist eine eigene (siehe unten) oder Produkt ansehen. Nach erfolgreichem In den Warenkorb wird daraus Hinzugefügt · Zum Warenkorb. Links zu Ihrem Shop öffnen sich im selben Tab, wie jeder Link in Ihrem Shop; der Chat bleibt nach dem Seitenwechsel im Gespräch.

Shopify und WooCommerce funktionieren sofort. In einem Shopify-Shop fügt das Widget die Variante über das shopeigene /cart/add.js hinzu, in WooCommerce nutzt es die WooCommerce Store API, die Block- und klassische Themes haben (ersatzweise den klassischen Warenkorb-Endpunkt), damit sich der Mini-Warenkorb aktualisiert. Ein Shopify-Produkt mit mehreren Varianten zeigt Optionen wählen, außer der Link verweist auf eine Variante (?variant=123). Der eingebaute Warenkorb legt nur Produkte des Shops ab, auf dem der Besucher ist.

Eigene Schaltflächen

Registrieren Sie einen Handler mit forProducts: true, dann erscheint er auf jeder Karte. Er erhält das Produkt:

<script>
  window.HelpStack = window.HelpStack || function () {
    (window.HelpStack.q = window.HelpStack.q || []).push(arguments);
  };

  window.HelpStack('registerAction', 'wishlist', async (product) => {
    // product: { url, title, productId, variantId, price, currency, platform, quantity }
    await myWishlist.add(product.productId);
    return { ok: true };
  }, { forProducts: true, label: { en: 'Save for later', de: 'Merken' } });
</script>
Option
forProductstrue macht daraus eine Kartenschaltfläche statt einer „Zeig es mir“-Schaltfläche
labelBeschriftung: ein Text oder einer pro Sprache ({ en, sl, de, ... }), gewählt nach der Browsersprache des Besuchers. Höchstens 40 Zeichen
primarytrue stellt Ihre Schaltfläche an die erste Stelle, vor In den Warenkorb

Der Name add_to_cart ist besonders: Er wird zur Schaltfläche In den Warenkorb der Karte und ersetzt die eingebaute für Shopify/WooCommerce. Verwenden Sie ihn mit jedem anderen Shopsystem. Geben Sie { ok: true, cartUrl: '/cart' } zurück, damit Zum Warenkorb auf Ihre Warenkorbseite führt, oder { ok: false, message }, um unter der Karte einen Fehler anzuzeigen.

Für Handler gelten dieselben Regeln wie für Aktionsschaltflächen: 10 Sekunden pro Tippen, ein geworfener Fehler zählt als Fehlschlag.

Was die KI erfährt

Im Webchat wird die KI gebeten, zu jedem empfohlenen Produkt den Link anzugeben, nur Links aus einem Tool oder der Wissensdatenbank und höchstens 3 pro Antwort. Tippt der Besucher auf eine Kartenschaltfläche, liest die KI das in ihrem nächsten Schritt („hat auf der Karte für Trail-Bike 29" In den Warenkorb getippt, und es hat funktioniert“) und kann darauf eingehen. Jedes Tippen wird als CLIENT_ACTION-Zeile in den Tool-Logs gespeichert, benannt nach der Schaltfläche (add_to_cart, view_product, choose_options, view_cart oder Ihre eigene).

Karten ausschalten

Kanäle → Erscheinungsbild → Produktkarten oder update_widget_config mit productCards: false. Links bleiben dann normale Links.

Domain-Allowlist#

Ein Kanal kann einschränken, welche Ursprünge das Widget laden dürfen. Wenn eine Allowlist konfiguriert ist und der anfragende Ursprung nicht darauf steht, antwortet der Server mit 403. Konfigurieren Sie die Allowlist in den Kanaleinstellungen im Dashboard. Lassen Sie sie leer, um jeden Ursprung zuzulassen.

Minimale Beispielseite#

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>HelpStack Widget Demo</title>
  </head>
  <body>
    <h1>My website</h1>
    <button onclick="window.ChatWidget.open()">Need help?</button>

    <!-- HelpStack widget -->
    <script
      src="https://helpstack.eu/widget.js?id=CHANNEL_ID"
      async
    ></script>
  </body>
</html>

Verwandte Themen#