Der AI Connector bietet eine RESTful-API, die es Kunden ermöglicht, Inhalte und Metadaten aus ihrer Haiilo-SaaS-Intranet-Plattform abzurufen. Dieser Connector ist dafür ausgelegt, externe KI-Systeme, Unternehmenssuchlösungen oder andere Drittanbieteranwendungen mit strukturierten Daten von Haiilo zu versorgen.
Der primäre Endpunkt liefert verschiedene Entitätstypen (Benutzer, Inhalte, Dateien usw.) in einem paginierten Format, was es einfach macht, große Datensätze zu synchronisieren und externe Systeme mit deinen Haiilo-Inhalten auf dem neuesten Stand zu halten.
Authentifizierung
Der AI Connector verwendet den OAuth 2.0 Client Credentials Flow zur Authentifizierung.
Authentifizierungsfluss
1. Zugriffs-Token erhalten
POST {baseUrl}/api/oauth/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {base64(clientId:clientSecret)}
grant_type=client_credentials2. Antwort
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "events:read"
}3. Token in API-Anfragen verwenden
GET {baseUrl}/web/content-connector/events/{entityType}
Authorization: Bearer {access_token}Erforderlicher Scope
Alle Endpunkte des AI Connectors erfordern den Scope events:read, der API-Clients automatisch gewährt wird.
API-Anmeldeinformationen einrichten
API-Anmeldeinformationen können über die Haiilo Admin-Oberfläche erhalten werden:
- Gehe zu Administration > Integrationen > Enterprise Search.
- Erstelle einen neuen API-Client.
- Kopiere die clientId und clientSecret (das Secret wird nur einmal angezeigt).
- Speichere die Anmeldeinformationen sicher.
Kernendpunkt
Events abrufen
Ruft Entitäten eines bestimmten Typs von deiner Haiilo-Plattform ab.
GET /web/content-connector/events/{entityType}
Pfadparameter
Parameter |
Typ |
Erforderlich |
Beschreibung |
|---|---|---|---|
|
string |
Ja |
Typ der abzurufenden Entität. Siehe Unterstützte Entitätstypen |
Abfrageparameter
Parameter |
Typ |
Erforderlich |
Standard |
Beschreibung |
|---|---|---|---|---|
|
integer |
Nein |
0 |
Die Event-ID, von der aus gestartet werden soll (für die Paginierung) |
|
integer |
Nein |
100 |
Anzahl der zurückzugebenden Elemente (min: 1, max: 10000) |
Antwort
{
"amount": 100,
"lastEventId": 12345,
"content": [
{
"eventId": 12245,
"entityType": "user",
"entityId": "abc-123-def",
"eventType": "CREATE",
"tenantId": "your-tenant-id",
... // entitätsspezifische Felder
}
]
}
Antwortfelder
Feld |
Typ |
Beschreibung |
|---|---|---|
|
integer |
Anzahl der Elemente in dieser Antwort |
|
integer |
ID des letzten Events in diesem Batch (verwende für die nächste Seite) |
|
array |
Array von Event-Objekten |
Gemeinsame Event-Felder
Jedes Event-Objekt enthält diese Basisfelder:
Feld |
Typ |
Beschreibung |
|---|---|---|
|
integer (int64) |
Eindeutiger Identifikator für dieses Event |
|
string |
Typ der Entität (Benutzer, App, Blog-Artikel usw.) |
|
string |
Eindeutiger Identifikator der Entität |
|
string |
Typ des Events (CREATE, UPDATE, DELETE) |
|
string |
Dein Tenant-/Organisations-Identifikator |
Unterstützte Entitätstypen
Der AI Connector unterstützt 11 verschiedene Entitätstypen. Lies mehr in diesem Artikel: Unterstützte Entitätstypen für den AI Connector.
Seitenumbruch
Die API verwendet einen cursor-basierten Seitenumbruch mit dem lastEventId Feld.
Seitenumbruch-Strategie
Mache die erste Anfrage mit
startId=0(oder lasse den Parameter weg)Verarbeite das zurückgegebene
contentArrayVerwende die
lastEventIdaus der Antwort alsstartIdfür die nächste AnfrageFahre fort, bis
amount0 oder weniger alspageSizeist
Beispiel für den Seitenumbruch
let startId = 0;
let allItems = [];
const pageSize = 1000;
while (true) {
const response = await getEvents('user', startId, pageSize);
if (response.content.length === 0) {
break; // Keine weiteren Daten
}
allItems.push(...response.content);
if (response.content.length < pageSize) {
break; // Letzte Seite
}
startId = response.lastEventId;
}
Best-Practices
Verwende größere Seitenzahlen (1000-10000) für die initiale vollständige Synchronisierung, um API-Aufrufe zu reduzieren
Verwende kleinere Seitenzahlen (100-500) für inkrementelle Updates
Speichere
lastEventId, um unterbrochene Synchronisierungen fortzusetzenImplementiere exponentielles Backoff für die Ratenbegrenzung
Gelöschte Entitäten
Verfolge Entitäten, die gelöscht wurden, um dein externes System synchron zu halten.
GET /web/content-connector/events/{entityType}/deletes
Parameter
Gleich wie der Haupt-Events-Endpunkt: startId, pageSize
Antwort
{
"amount": 10,
"lastEventId": 12350,
"content": [
{
"eventId": 12346,
"entityId": "deleted-entity-id",
"entityType": "blog-article"
}
]
}
Anwendungsfall
Verwende diesen Endpunkt, um zu identifizieren, welche Entitäten seit deiner letzten Synchronisierung gelöscht wurden, damit du sie aus deinem externen System entfernen kannst.
Hilfs-Endpunkte
Sender-Bilder abrufen
Rufe Avatar- oder Coverbilder für Benutzer, Seiten oder Arbeitsbereiche ab.
GET /web/content-connector/api/senders/{senderId}/images/{imageType}
Parameter:
senderId(UUID) - ID aus demimageUrls-FeldimageType- Entwederavatarodercovermodified(optional) - Änderungszeitstempel für Caching
Antwort:
{
"imageUrl": "https://cdn.haiilo.com/..."
}
Blog-Teaser-Bilder abrufen
Rufe Teaserbilder für Blog-Beiträge ab.
GET /web/content-connector/api/blogs/{blogId}/teaser
Antwort:
{
"image": {
"contentType": "image/png",
"downloadUrl": "https://...",
"validityMinutes": 60
},
"imageWide": {
"contentType": "image/png",
"downloadUrl": "https://...",
"validityMinutes": 60
}
}
Download-URL für Datei abrufen
Rufe eine Download-URL für eine Datei ab.
GET /web/content-connector/api/files/{groupId}/{uid}
Parameter:
groupId- AuscurrentVersionBlobReference.groupIduid- AuscurrentVersionBlobReference.uid
Antwort:
{
"fileUrl": "https://cdn.haiilo.com/..."
}
Hinweis: Download-URLs sind zeitlich begrenzt und sollten umgehend verwendet oder bei Bedarf aktualisiert werden.
Theme-Icon abrufen
Rufe das Theme-Icon (Favicon) des Mandanten ab.
GET /web/content-connector/theme-icon
Antwort: PNG-Bild (binär)
Beispielanwendungen
Node.js Beispiel-Client
Siehe example-client/example-client.js für eine vollständige Referenzimplementierung.
const ContentConnectorClient = require('./example-client');
const client = new ContentConnectorClient(
'your-client-id',
'your-client-secret',
'https://your-tenant.haiilo.com'
);
// Authentifizieren
await client.connect();
// Alle Benutzer abrufen
const users = await client.getAllEntitiesWithPagination('user');
// Blog-Beiträge abrufen
const articles = await client.getAllEntitiesWithPagination('blog-article');
// Bestimmte Seite abrufen
const response = await client.getEvents('page', 0, 100);
Python Beispiel
import requests
import base64
class ContentConnectorClient:
def __init__(self, client_id, client_secret, base_url):
self.client_id = client_id
self.client_secret = client_secret
self.base_url = base_url
self.token = None
def connect(self):
credentials = base64.b64encode(
f"{self.client_id}:{self.client_secret}".encode()
).decode()
response = requests.post(
f"{self.base_url}/api/oauth/token",
data={"grant_type": "client_credentials"},
headers={"Authorization": f"Basic {credentials}"}
)
self.token = response.json()["Zugriffs-Token"]
def get_events(self, entity_type, start_id=0, page_size=100):
response = requests.get(
f"{self.base_url}/web/content-connector/events/{entity_type}",
params={"startId": start_id, "pageSize":
page_size},
headers={"Authorization": f"Bearer {self.token}"}
)
return response.json()
cURL Beispiel
# Zugriffs-Token abrufen TOKEN=$(curl -X POST "https://your-tenant.haiilo.com/api/oauth/token" \ -H "Authorization: Basic $(echo -n 'clientId:clientSecret' | base64)" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" | jq -r '.Zugriffs-Token') # Benutzer abrufen curl "https://your-tenant.haiilo.com/web/content-connector/events/user?startId=0&pageSize=100" \ -H "Authorization: Bearer $TOKEN"
Rate Limits und Best-Practices
Best-Practices
-
Erst-Synchronisation
Verwende große Seitenzahlen (5000-10000), um API-Aufrufe zu minimieren
Verarbeite Entitätstypen parallel, wenn möglich
Speichere die höchste
lastEventIdfür jeden Entitätstyp
-
Inkrementelle Updates
Frage regelmäßig nach neuen Events (z.B. alle 5-15 Minuten)
Verwende die gespeicherte
lastEventIdalsstartId, um nur neue/aktualisierte Entitäten zu erhaltenVerarbeite den Endpoint für Löschungen, um entfernte Inhalte zu behandeln
-
Fehlerbehandlung
Implementiere eine Wiederholungslogik mit exponentiellem Backoff
Behandle 401-Fehler, indem du das Zugriffs-Token erneuerst
Protokolliere fehlgeschlagene Entitäts-IDs zur manuellen Überprüfung
-
Leistung
Cache Bild-URLs und aktualisiere sie, wenn sich der
modified-Parameter ändertVerarbeite Entitäten in Batches für die Datenbankeinfügung
Verwende parallele Verarbeitung für verschiedene Entitätstypen
-
Datenqualität
Validiere Entitätsdaten vor der Indizierung
Behandle fehlende optionale Felder elegant
Respektiere die
status- undvisibility-Felder für die Inhaltsfilterung
-
Sicherheit
Speichere API-Anmeldeinformationen sicher (Umgebungsvariablen, Geheimnis-Manager)
Verwende HTTPS für alle API-Kommunikationen
Protokolliere keine Zugriffs-Token
Mehrsprachige Inhalte
Viele Entitäten unterstützen mehrsprachige Inhalte durch Kartenfelder (z.B. title, textContent).
Struktur
{
"title": {
"en": "Welcome to our company",
"de": "Willkommen in unserem Unternehmen",
"fr": "Bienvenue dans notre entreprise"
},
"defaultLanguage": "en"
}
Handhabungsstrategie
Verwende
defaultLanguage, um den primären Inhalt zu bestimmenIndiziere alle Sprachvarianten für die mehrsprachige Suche
Extrahiere die passende Sprachvariante basierend auf der Benutzersprache
Falle auf
defaultLanguagezurück, wenn die angeforderte Sprache nicht verfügbar ist
Gemeinsame Objekte
SenderReferenz
Referenzen auf Entitäten (Benutzer, Arbeitsbereiche, Seiten), die Inhalte "besitzen" oder damit verbunden sind.
{
"id": "entity-id",
"type": "user" // oder "workspace", "page", etc.
}
Ziel
Link-Zielinformationen für die Frontend-Navigation.
{
"name": "blog_article_detail",
"displayName": "Artikel Detail",
"params": {
"appId": "123",
"articleId": "456"
}
}
Verwende diese, um Deep Links in das Haiilo-Frontend zu erstellen.
Häufig Gestellte Fragen
F: Wie oft sollte ich nach Updates fragen?
A: Für die meisten Anwendungsfälle bietet das Abfragen alle 5-15 Minuten ein gutes Gleichgewicht zwischen Aktualität und API-Last. Bei Echtzeitanforderungen solltest du alle 1-2 Minuten abfragen, aber stelle sicher, dass du eine angemessene Ratenbegrenzung implementierst.
F: Kann ich Events nach Datum oder Status filtern?
A: Filtern wird derzeit auf API-Ebene nicht unterstützt. Rufe alle Events ab und filtere auf deiner Seite basierend auf createdDate, modifiedDate, status oder anderen Feldern.
F: Was passiert, wenn ich Events während einer Ausfallzeit verpasse?
A: Setze einfach die Verwendung deiner letzten gespeicherten lastEventId fort. Die API gibt alle Events nach dieser ID zurück, sodass du keine Updates verpasst.
F: Wie gehe ich mit gelöschten Inhalten um?
A: Verwende den /deletes Endpunkt für jeden Entitätstyp, um gelöschte Entitäts-IDs abzurufen, und entferne sie dann aus deinem externen System.
F: Sind Bild-URLs permanent?
A: Bild-URLs, die von Hilfsendpunkten zurückgegeben werden, sind zeitlich begrenzt (typischerweise 60 Minuten). Aktualisiere sie nach Bedarf, anstatt sie langfristig zu speichern.
F: Kann ich nur bestimmte Felder anfordern?
A: Nein, die API gibt vollständige Entitätsobjekte zurück. Filtere die Felder auf der Client-Seite nach Bedarf.
F: Was ist die maximale Seitengröße?
A: Die maximale pageSize beträgt 10.000 Elemente pro Anfrage.
Support und Ressourcen
- OpenAPI-Spezifikation
- Integrationssetup: Administration > Integrationen > Enterprise Search in deiner Haiilo-Plattform.
- Beispiel-Client: enterprise-search-example-client.zip (unten herunterladen)
- Swagger (ähnliches) Dokument: swagger-doc.html (unten herunterladen)