# JavaScript-SDK: das Chat-Widget von deiner Seite aus steuern

> Öffne und schließe die intoCHAT-Chat-Bubble aus deinem eigenen Code, identifiziere angemeldete Besucher, wechsle die Sprache des Widgets und reagiere mit window.IntoChat auf Chat-Ereignisse.

Das Embed-Script fügt deiner Seite `window.IntoChat` hinzu. Damit kann dein eigenes JavaScript die Chat-Bubble öffnen und schließen, dem Agenten mitteilen, wer der angemeldete Besucher ist, die Sprache des Widgets wechseln und auf das reagieren, was im Chat passiert.

## Bevor du loslegst

Das SDK kommt mit dem [Script-Tag](/de/docs/script-tag). Du musst nichts weiter installieren:

```html
<script src="https://www.intochat.ai/api/embed.js" data-chatbot-id="YOUR_AGENT_ID"></script>
<script>
  window.IntoChat.on("reply", function (event) {
    console.log("The agent replied:", event.text);
  });
</script>
```

`window.IntoChat` steht bereit, sobald das Script gelaufen ist, noch bevor das Chatfenster geladen hat. Frühe Aufrufe warten, bis Launcher und Chatfenster bereit sind. Du kannst also jede Methode direkt nach dem Snippet aufrufen.

Das SDK funktioniert nur mit der Chat-Bubble, die das Script einfügt. Bei einem [iframe oder einem Direktlink](/de/docs/iframe-and-link) gibt es kein Script auf der Seite, mit dem es sprechen könnte.

## Methoden

| Methode | Was sie tut |
| --- | --- |
| `IntoChat.open()` | Öffnet das Chatfenster |
| `IntoChat.close()` | Schließt es |
| `IntoChat.toggle()` | Öffnet es, wenn es geschlossen ist, und schließt es, wenn es offen ist |
| `IntoChat.identify(user)` | Teilt dem Agenten mit, wer der angemeldete Besucher ist; siehe [identify](#identify) |
| `IntoChat.reset()` | Vergisst die Identität des Besuchers und startet einen neuen Chat |
| `IntoChat.setLanguage(code)` | Wechselt die Sprache des Widgets |
| `IntoChat.on(event, callback)` | Ruft `callback` auf, wenn `event` eintritt |
| `IntoChat.off(event, callback)` | Hört damit auf |

### open, close und toggle

```html
<button type="button" onclick="IntoChat.open()">Chat with us</button>
```

Öffnet sich der Chat auf diese Weise, zählt das so, als hätte der Besucher den Chat benutzt. Das Begrüßungs-Pop-up und das automatische Öffnen erscheinen danach während dieses Besuchs nicht mehr.

`IntoChat.open()` funktioniert auch für Besucher, die den Launcher wegen [Den Chat nur einem Teil der Besucher zeigen](/de/docs/appearance#den-chat-nur-einem-teil-der-besucher-zeigen) nicht sehen. Der Rollout blendet nur den Launcher und seine Einladungen aus, ein Button „Chat mit uns“ auf deiner Seite öffnet den Chat also weiterhin für alle. Für diese Besucher wird das Chatfenster beim ersten Öffnen geladen. Mit [Center Stage](/de/docs/appearance#wie-sich-der-chat-offnet) öffnet `open()` das zentrierte Fenster, und `close()` schließt es wie Esc.

### identify

```js
IntoChat.identify({
  userId: "4711",                  // Pflicht: die ID des Nutzers auf deiner Website
  userHash: "9f2c…",               // Pflicht: auf deinem Server berechnet
  name: "Ada Lovelace",            // optional
  email: "ada@example.com",        // optional
  metadata: { plan: "pro", seats: 3 } // optional
});
```

Über `identify` funktioniert die [Identitätsprüfung](/de/docs/identity-verification). `userHash` ist das HMAC-SHA256 von `userId` mit dem Identitäts-Secret deines Agenten als Schlüssel, berechnet auf deinem Server, damit sich niemand als ein anderer Nutzer ausgeben kann. Ohne gültigen `userHash` bleibt der Besucher einfach unverifiziert.

| Feld | Regeln |
| --- | --- |
| `userId` | Pflicht. Text (eine Zahl wird in Text umgewandelt), bis zu 200 Zeichen. Signiere genau diesen Wert. |
| `userHash` | Pflicht. 64 hexadezimale Zeichen. |
| `name` | Optional. Bis zu 100 Zeichen. |
| `email` | Optional. Eine gültige E-Mail-Adresse, bis zu 254 Zeichen. |
| `metadata` | Optional. Ein flaches Objekt mit bis zu 20 Schlüsseln. Schlüssel bestehen aus Buchstaben, Ziffern und Unterstrichen (bis zu 40 Zeichen); Werte sind Text (bis zu 500 Zeichen), Zahlen oder `true`/`false`. Insgesamt höchstens 2 KB. |

`identify` gibt `true` zurück, wenn die Eingabe diese Regeln erfüllt, und `false` (mit einer Warnung in der Browserkonsole), wenn nicht. Ob die Signatur gültig ist, prüft erst der Server von intoCHAT, wenn der Besucher eine Nachricht sendet.

Rufe `identify` bei jedem Seitenaufruf auf, solange der Besucher angemeldet ist. Identifizierst du in diesem Browser einen anderen Nutzer als zuletzt, startet automatisch ein neuer Chat, damit niemand das Gespräch einer anderen Person sieht. Ein Besucher, der schon vor der Anmeldung gechattet hat, behält diesen Chat.

### reset

```js
IntoChat.reset();
```

Rufe es auf, wenn sich der Besucher abmeldet. Es vergisst die Identität und startet einen neuen, leeren Chat. Auch die Liste früherer Chats in diesem Browser wird geleert; die Gespräche selbst bleiben in deinem Dashboard.

### setLanguage

```js
IntoChat.setLanguage("de");
```

Wechselt die Texte des Widgets selbst (Buttons, Beschriftungen, Hinweise) auf Englisch (`en`), Deutsch (`de`), Französisch (`fr`), Italienisch (`it`) oder Spanisch (`es`). Ein Regionalcode wie `de-CH` zählt als `de`. Jeder andere Code gibt `false` zurück. Die Methode ersetzt das Attribut `lang` deiner Seite und hat daher keine Wirkung, wenn du im Tab [Appearance](/de/docs/appearance) eine feste Sprache für das Widget gewählt hast. Deine Begrüßungen und die Sprache, in der der Agent antwortet, ändert sie nicht.

### on und off

```js
function onReply(event) {
  analytics.track("chat_reply", { agent: event.chatbotId });
}

IntoChat.on("reply", onReply);
// später
IntoChat.off("reply", onReply);
```

`on` gibt außerdem eine Funktion zurück, die den Listener entfernt. Ein Listener, der einen Fehler wirft, hält die anderen nicht auf; der Fehler landet in der Konsole.

## Events

Jeder Callback bekommt ein Objekt. Es enthält immer `chatbotId`, den Agenten, von dem das Event kommt.

| Event | Wann | Weitere Felder |
| --- | --- | --- |
| `open` | Das Chatfenster wurde geöffnet: vom Besucher, von deinem Code oder durch das automatische Öffnen | keine |
| `close` | Das Chatfenster wurde geschlossen | keine |
| `message` | Der Besucher hat eine Nachricht gesendet | `text` |
| `reply` | Der Agent hat eine Antwort fertig geschrieben | `text`: die Antwort ohne die Produktkarten, Buttons, Formulare oder Quellen darunter |
| `lead` | Der Besucher hat das [Kontaktformular](/de/docs/lead-collection) abgeschickt | keine |
| `booking` | Der Besucher hat über die [Terminbuchung](/de/docs/booking) einen Termin gebucht | keine |
| `live_chat` | Der Status des [Live-Chats](/de/docs/live-chat) hat sich geändert, während die Seite offen war | `status`: `requested`, `active`, `ended` oder `null` |

```js
IntoChat.on("live_chat", function (event) {
  if (event.status === "active") document.title = "A team member is chatting with you";
});
```

In einem temporären Chat werden `lead` und `booking` nicht ausgelöst, weil beides dort nicht angeboten wird. Kontaktdaten, die ein Besucher in den Chat tippt, statt das Formular zu nutzen, lösen kein `lead` aus.

## Aufrufe, bevor das Script lädt

Kann dein Code vor dem Snippet laufen, leg Aufrufe in `window.IntoChatQueue` ab. Jeder Eintrag ist der Name der Methode, gefolgt von ihren Argumenten:

```html
<script>
  window.IntoChatQueue = window.IntoChatQueue || [];
  window.IntoChatQueue.push(["identify", { userId: "4711", userHash: "9f2c…" }]);
  window.IntoChatQueue.push(["on", "lead", function () { console.log("New lead"); }]);
</script>
<script src="https://www.intochat.ai/api/embed.js" data-chatbot-id="YOUR_AGENT_ID"></script>
```

Das Script arbeitet die Warteschlange beim Laden ab. Spätere Einträge laufen sofort.

## Mehrere Agenten auf einer Seite

Hast du Snippets für mehrere Agenten auf einer Seite, gilt jeder Aufruf für alle ihre Launcher, und die `chatbotId` jedes Events sagt, von welchem Agenten es kommt. Jeder Agent hat sein eigenes Identitäts-Secret, ein `userHash` verifiziert den Besucher also nur für den Agenten, dessen Secret ihn signiert hat.

## Zusammenspiel mit IntoChatActions

`window.IntoChatActions` ist davon getrennt und funktioniert genau wie bisher: Es führt [client-seitige Aktionen](/de/docs/client-actions) aus, wenn der Agent sie aufruft. `IntoChat` ist dafür da, dass dein eigener Code das Widget steuert. Beides lässt sich zusammen nutzen. Ist der Besucher verifiziert, bekommt auch ein Handler für eine client-seitige Aktion ihn als `context.user`:

```js
IntoChatActions.register("Get_cart", async function (args, context) {
  // context.user: { id, name, email, metadata }, nur bei einem verifizierten Besucher
  return { items: window.myStore.cart.items };
});
```

## Sicherheit

Das Chatfenster läuft auf der Domain von intoCHAT. Das Script auf deiner Seite tauscht Nachrichten nur mit seinem eigenen Chatfenster aus, und nur solange dieses Fenster intoCHAT zeigt: Andere Frames auf deiner Seite können weder die Identität des Besuchers empfangen noch gefälschte Events senden oder Aktionen auslösen. Events enthalten, was der Besucher getippt hat, und die Antworten des Agenten. Behandle sie also wie alle anderen Besucherdaten auf deiner Seite.
