Aller au contenu principal

Intégration avancée dans votre app

Intégration avancée dans votre app

ChatKit ne se limite pas à un widget de chat isolé. Dans cette leçon, vous apprendrez à intégrer profondément l’agent dans votre application : authentification, contexte applicatif, événements bidirectionnels, et modes d’affichage avancés.

Authentification et sessions

En production, chaque utilisateur a sa propre session avec l’agent :

import { ChatProvider, ChatWindow, MessageInput } from "@openai/chatkit/react";

function ChatAuthentifie({ user }) {
  return (
    <ChatProvider
      endpoint="/api/chat"
      headers={{
        Authorization: `Bearer ${user.token}`,
      }}
      metadata={{
        userId: user.id,
        plan: user.plan,
        langue: "fr",
      }}
    >
      <ChatWindow />
      <MessageInput />
    </ChatProvider>
  );
}

Côté backend, récupérez les informations de l’utilisateur :

from fastapi import FastAPI, Request, Depends
from agents import Agent, Runner

app = FastAPI()

async def get_current_user(request: Request):
    token = request.headers.get("Authorization", "").replace("Bearer ", "")
    # Vérifier le token et récupérer l'utilisateur
    return {"id": "usr_123", "nom": "Marie Dupont", "plan": "Pro"}

@app.post("/api/chat")
async def chat(request: Request, user=Depends(get_current_user)):
    body = await request.json()

    contexte = SessionUtilisateur(
        user_id=user["id"],
        nom=user["nom"],
        plan=user["plan"],
    )

    agent = Agent(
        name="Assistant",
        instructions=f"Vous assistez {user['nom']} (plan {user['plan']}).",
        model="gpt-5.3",
    )

    result = await Runner.run(agent, body["message"], context=contexte)
    return {"response": result.final_output}

Injecter le contexte applicatif

Votre agent peut accéder au contexte de la page où se trouve l’utilisateur :

import { useEffect, useState } from "react";
import { ChatProvider, ChatWindow, MessageInput } from "@openai/chatkit/react";

function ChatContextuel() {
  const [pageContext, setPageContext] = useState({});

  useEffect(() => {
    // Capturer le contexte de la page courante
    setPageContext({
      page: window.location.pathname,
      produitConsulte: document.querySelector("[data-product-id]")?.dataset.productId,
      categorieActive: document.querySelector("[data-category]")?.dataset.category,
    });
  }, []);

  return (
    <ChatProvider
      endpoint="/api/chat"
      metadata={{ context: pageContext }}
    >
      <ChatWindow />
      <MessageInput
        placeholder={
          pageContext.produitConsulte
            ? "Une question sur ce produit ?"
            : "Comment puis-je vous aider ?"
        }
      />
    </ChatProvider>
  );
}

Événements bidirectionnels

ChatKit peut émettre et recevoir des événements pour synchroniser le chat avec votre app :

import { useRef } from "react";
import { ChatProvider, ChatWindow, MessageInput } from "@openai/chatkit/react";

function ChatInteractif() {
  const chatRef = useRef(null);

  // Envoyer un message programmatiquement
  const envoyerMessage = (message) => {
    chatRef.current?.sendMessage(message);
  };

  // Écouter les événements du chat
  const handleEvent = (event) => {
    if (event.type === "tool_call" && event.tool === "naviguer_vers") {
      // L'agent demande de naviguer vers une page
      window.location.href = event.args.url;
    }
    if (event.type === "action" && event.action === "ouvrir_panier") {
      // Ouvrir le panneau panier
      document.dispatchEvent(new CustomEvent("ouvrir-panier"));
    }
  };

  return (
    <ChatProvider endpoint="/api/chat" onEvent={handleEvent} ref={chatRef}>
      {/* Bouton externe qui déclenche le chat */}
      <button onClick={() => envoyerMessage("Aide-moi à choisir un produit")}>
        Besoin d'aide ?
      </button>
      <ChatWindow />
      <MessageInput />
    </ChatProvider>
  );
}

Mode panneau latéral

Affichez le chat dans un panneau latéral rétractable :

import { useState } from "react";
import { ChatProvider, ChatWindow, MessageInput } from "@openai/chatkit/react";

function ChatPanneauLateral() {
  const [ouvert, setOuvert] = useState(false);

  return (
    <>
      {/* Bouton flottant */}
      <button
        onClick={() => setOuvert(!ouvert)}
        style={{
          position: "fixed",
          bottom: "24px",
          right: "24px",
          width: "56px",
          height: "56px",
          borderRadius: "50%",
          background: "#2563EB",
          color: "white",
          border: "none",
          cursor: "pointer",
          fontSize: "24px",
          zIndex: 1000,
          boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
        }}
      >
        {ouvert ? "×" : "?"}
      </button>

      {/* Panneau latéral */}
      <div style={{
        position: "fixed",
        top: 0,
        right: ouvert ? 0 : "-400px",
        width: "400px",
        height: "100vh",
        background: "#0F172A",
        transition: "right 0.3s ease",
        zIndex: 999,
        display: "flex",
        flexDirection: "column",
        boxShadow: ouvert ? "-4px 0 24px rgba(0,0,0,0.3)" : "none",
      }}>
        <div style={{ padding: "16px", borderBottom: "1px solid #1E293B" }}>
          <h3 style={{ margin: 0, color: "#F8FAFC" }}>Assistant</h3>
        </div>
        <ChatProvider endpoint="/api/chat">
          <ChatWindow style={{ flex: 1 }} />
          <MessageInput />
        </ChatProvider>
      </div>
    </>
  );
}

Persistance des conversations

Sauvegardez et restaurez les conversations :

function ChatPersistant({ userId }) {
  return (
    <ChatProvider
      endpoint="/api/chat"
      conversationId={`conv_${userId}_latest`}
      onConversationLoad={async (convId) => {
        // Charger l'historique depuis votre API
        const response = await fetch(`/api/conversations/${convId}`);
        return response.json();
      }}
      onConversationSave={async (convId, messages) => {
        // Sauvegarder l'historique
        await fetch(`/api/conversations/${convId}`, {
          method: "PUT",
          body: JSON.stringify({ messages }),
        });
      }}
    >
      <ChatWindow />
      <MessageInput />
    </ChatProvider>
  );
}

Points clés à retenir

  • Passez le token d’authentification via headers dans le ChatProvider
  • Le contexte applicatif (page, produit consulté) enrichit les réponses de l’agent
  • Les événements bidirectionnels synchronisent le chat avec votre application
  • Le mode panneau latéral est le pattern d’intégration le plus courant
  • La persistance des conversations permet de reprendre où l’utilisateur s’est arrêté