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
headersdans leChatProvider - 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é