Integrationen vs. Aktionen vs. Trigger

Integrationen sind standardisierte Verbindungen zwischen Langdock und Drittanbieter-Tools, die Authentifizierung und API-Kommunikation verwalten. Innerhalb jeder Integration kannst du Folgendes erstellen:
  • Aktionen: Funktionen, die Assistenten und Workflows aufrufen können, um mit APIs zu interagieren (z.B. “Ticket erstellen”, “E-Mail senden”, “Daten abrufen”)
  • Trigger: Event-Monitore, die Workflows starten, wenn bestimmte Ereignisse auftreten (z.B. “neue E-Mail erhalten”, “Datei hochgeladen”)

Eine Integration einrichten

Klicke im Integrationsmenü auf Integration erstellen, um zu beginnen. Gib als Nächstes einen Integrationsnamen an und lade ein Icon hoch (wird im Chat bei der Verwendung von Aktionen und in der Integrationsübersicht angezeigt). Füge eine Beschreibung hinzu, damit Assistenten wissen, wann sie diese Integration verwenden sollen. Klicke auf Speichern, um sie zu erstellen.

Authentifizierung

Beginne mit der Authentifizierung im Tab Erstellen. Wähle deinen Authentifizierungstyp und konfiguriere ihn gemäß den folgenden Schritten:

API-Schlüssel

Nach der Auswahl der API-Schlüssel-Authentifizierung füge in Schritt 2 benutzerdefinierte Eingabefelder hinzu (wie API-Schlüssel oder Client-ID). Diese Eingaben werden erfasst, wenn Nutzer Verbindungen einrichten und können als “erforderlich” markiert werden. In Schritt 3 kannst du einen Test-API-Endpunkt einrichten, um die Authentifizierung zu validieren. Ersetze den URL-Parameter und füge Verweise auf deine Eingabefelder mit data.auth.fieldId hinzu. Verwende die integrierten Funktionen ld.request und ld.log für Anfragen und Protokollierung. Teste deine Aktion und erstelle deine erste Verbindung.

OAuth 2.0

Nutzerdefinierte Integrationen unterstützen OAuth 2.0-Authentifizierung. Schritt 2 ermöglicht benutzerdefinierte Eingabefelder (die beim Einrichten der Verbindung erfasst werden). Client-ID und Client-Secret werden in Schritt 4 eingegeben, daher deckt dies nur zusätzliche Parameter ab. OAuth-Client erstellen Richte einen OAuth-Client/App/Projekt in deiner Zielanwendung ein und aktiviere die erforderlichen APIs. Dies ist anwendungsspezifisch, weshalb unsere Oberfläche benutzerdefinierten Code in Schritt 5 unterstützt. Für Google Calendar: Erstelle ein Google Service-Konto, generiere einen neuen Schlüssel, um die Client-ID und das Secret zu erhalten, füge sie in Schritt 4 zu Langdock hinzu, speichere die OAuth Redirect URL und aktiviere die Google Calendar API. Autorisierungs-URL ändern Überprüfe die OAuth-Dokumentation für deinen Service und extrahiere die Autorisierungs-URL. Normalerweise reicht es aus, die BASE_URL in unserer Vorlage zu ändern. Für Google Calendar:
return `https://accounts.google.com/o/oauth2/v2/auth?client_id=${env.CLIENT_ID}&response_type=code&scope=${data.input.scope}&access_type=offline&redirect_uri=${encodeURIComponent(data.input.redirectUrl)}&state=${data.input.state}&prompt=consent`;
Scopes definieren Definiere die OAuth-Scopes, die deine Aktionen benötigen. Liste sie komma- oder leerzeichengetrennt gemäß deiner API-Dokumentation auf. Für Google Calendar (leerzeichengetrennt):
https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile
Access Token & Refresh Token URL bereitstellen Überprüfe die OAuth-Dokumentation deiner API für die Access Token URL und Refresh Token URL. Normalerweise funktioniert es, die tokenUrl in unserer Vorlage zu aktualisieren. Für Google Calendar: const tokenUrl ='https://oauth2.googleapis.com/token'; Authentifizierungs-Setup testen Stelle einen Test-API-Endpunkt (wie /me) bereit, um die Authentifizierung zu verifizieren. Der Rückgabewert dieser Testanfrage kann innerhalb des OAuth Client Labels verwendet werden, um die Benennung der hergestellten Verbindungen zu beeinflussen. Du kannst auf den Rückgabewert über {{data.input}} zugreifen. Für Google Calendar: Google Sheets - {{data.input.useremail.value}} Teste, indem du eine Verbindung hinzufügst und verifizierst, dass der Autorisierungsablauf funktioniert. Für Google Calendar testen wir mit:
url: 'https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses'

Öffentliche APIs

Wähle Keine für öffentlich verfügbare APIs ohne Authentifizierung.

Aktionen erstellen

Aktionen ermöglichen es Assistenten, mit deinen API-Endpunkten zu interagieren. Es gibt zwei Arten von Aktionen:
  • Reguläre Aktionen: Standard-API-Interaktionen (Erstellen, Lesen, Aktualisieren, Löschen)
  • Native Aktionen: Spezielle Dateisuche- und Download-Aktionen, die in das Langdock-Dateisystem integriert sind

Reguläre Aktionen

Reguläre Aktionen sind der häufigste Typ und verarbeiten Standard-API-Operationen.

Wann du reguläre Aktionen erstellen solltest

  • CRUD-Operationen: Daten über API-Aufrufe erstellen, lesen, aktualisieren oder löschen
  • Datenverarbeitung: Daten zur Analyse, Transformation oder Validierung an APIs senden
  • Dateioperationen: Dateien zu Services hochladen, Dokumente verarbeiten, Anhänge senden
  • Benachrichtigungen: E-Mails, Nachrichten senden oder Tickets erstellen
  • Integrationen: Mehrere Services verbinden oder Daten zwischen Plattformen synchronisieren

Reguläre Aktionen einrichten

  1. Aktion hinzufügen: Klicke in deiner Integration auf “Aktion hinzufügen”
  2. Grundlegende Informationen konfigurieren: Name, Beschreibung und Slug festlegen
  3. Eingabefelder hinzufügen: Definiere, welche Daten die Aktion von Nutzern benötigt
  4. Aktionscode schreiben: Implementiere die API-Interaktionslogik
  5. Testen: Validiere, dass deine Aktion korrekt funktioniert

Eingabefeldtypen

TypZweckHinweise
TEXTKurze TexteingabeEinzeiliger Text
MULTI_LINE_TEXTLange TexteingabeMehrere Zeilen, gut für Beschreibungen
NUMBERNumerische EingabeGanze Zahlen oder Dezimalzahlen
BOOLEANWahr/Falsch-ToggleCheckbox-Eingabe
SELECTDropdown-OptionenVordefinierte Auswahlmöglichkeiten
FILEDatei-UploadEinzelne oder mehrere Dateien (siehe Dateiunterstützungs-Guide)
OBJECTKomplexe DatenJSON-Objekte mit benutzerdefiniertem Schema
PASSWORDSensibler TextVersteckte Eingabe für Geheimnisse

Beispiel: Ticket-Erstellungsaktion

// Erforderliche Eingaben validieren
if (!data.input.title) {
  return { error: 'Titel ist erforderlich' };
}

// Anfrage erstellen
const options = {
  method: 'POST',
  url: 'https://api.ticketing-service.com/tickets',
  headers: {
    'Authorization': `Bearer ${data.auth.api_key}`,
    'Content-Type': 'application/json',
  },
  body: {
    title: data.input.title,
    description: data.input.description || '',
    priority: data.input.priority || 'medium',
    assignee: data.input.assignee
  }
};

try {
  const response = await ld.request(options);

  if (response.status === 201) {
    return {
      success: true,
      ticketId: response.json.id,
      url: response.json.url,
      message: `Ticket #${response.json.id} erstellt: ${data.input.title}`
    };
  } else {
    throw new Error(`API hat Status ${response.status} zurückgegeben`);
  }
} catch (error) {
  ld.log('Fehler beim Erstellen des Tickets:', error.message);
  return {
    success: false,
    error: `Ticket konnte nicht erstellt werden: ${error.message}`
  };
}

Datei-Upload-Beispiel

// Datei-Uploads verarbeiten (erfordert FILE-Eingabefeld)
const document = data.input.document; // FileData-Objekt

if (!document) {
  return { error: 'Bitte hänge ein Dokument an' };
}

// Dateityp validieren
const allowedTypes = ['application/pdf', 'image/jpeg', 'image/png'];
if (!allowedTypes.includes(document.mimeType)) {
  return {
    error: `Nicht unterstützter Dateityp: ${document.mimeType}. Erlaubt: ${allowedTypes.join(', ')}`
  };
}

const options = {
  method: 'POST',
  url: 'https://api.example.com/documents',
  headers: {
    'Authorization': `Bearer ${data.auth.api_key}`,
    'Content-Type': 'application/json'
  },
  body: {
    filename: document.fileName,
    content: document.base64,
    mimeType: document.mimeType
  }
};

const response = await ld.request(options);
return {
  success: true,
  documentId: response.json.id,
  message: `${document.fileName} erfolgreich hochgeladen`
};

Dateien von Aktionen zurückgeben

Aktionen können auch Dateien generieren und zurückgeben:
// CSV-Export generieren
const data = await fetchCustomerData();

const csvHeader = 'Name,Email,Erstellt';
const csvRows = data.map(customer =>
  `"${customer.name}","${customer.email}","${customer.created}"`
);
const csvContent = [csvHeader, ...csvRows].join('\n');

return {
  files: {
    fileName: `kunden-${new Date().toISOString().slice(0,10)}.csv`,
    mimeType: 'text/csv',
    text: csvContent  // Verwende 'text' für UTF-8-Inhalt, 'base64' für binär
  },
  success: true,
  exported: data.length
};

Trigger erstellen

Trigger überwachen externe Systeme auf Ereignisse und können Workflows automatisch starten.

Wann du Trigger erstellen solltest

  • Event-Überwachung: Neue E-Mails, Dateien, Datensätze oder Änderungen erkennen
  • Workflow-Automatisierung: Prozesse starten, wenn bestimmte Ereignisse auftreten
  • Datensynchronisierung: Systeme durch Erkennung von Änderungen synchron halten
  • Benachrichtigungen: Auf externe Ereignisse reagieren und Nutzer benachrichtigen

Trigger-Typen

  • Polling-Trigger: APIs regelmäßig auf neue Ereignisse überprüfen
  • Webhook-Trigger: Echtzeit-Benachrichtigungen von externen Systemen empfangen

Polling-Trigger einrichten

  1. Trigger hinzufügen: Klicke in deiner Integration auf “Trigger hinzufügen”
  2. Typ auswählen: Wähle “Polling”
  3. Einstellungen konfigurieren: Name, Beschreibung und Polling-Intervall festlegen
  4. Eingabefelder hinzufügen: Konfigurationsparameter definieren (optional)
  5. Trigger-Code schreiben: Die Polling-Logik implementieren
  6. Testen: Validiere, dass dein Trigger Ereignisse korrekt erkennt

Erforderliches Rückgabeformat

Trigger müssen ein Array von Ereignissen mit dieser Struktur zurückgeben:
return [
  {
    id: "unique_event_id",        // Required: Unique identifier
    timestamp: "2024-01-15T...",  // Required: Event timestamp (ISO string)
    data: {
      // Your event data here
      eventType: "new_email",
      subject: "Important message",
      from: "sender@example.com",
      // ... other event properties
    }
  }
];

Beispiel: Neue E-Mail-Trigger

// Fetch recent emails
const options = {
  method: 'GET',
  url: 'https://api.email-service.com/messages',
  headers: {
    'Authorization': `Bearer ${data.auth.access_token}`,
  },
  params: {
    since: new Date(Date.now() - 60 * 60 * 1000).toISOString(), // Last hour
    limit: 10
  }
};

try {
  const response = await ld.request(options);
  const emails = response.json.messages || [];

  // Transform to required format
  const results = emails.map(email => ({
    id: email.id,
    timestamp: email.receivedAt,
    data: {
      messageId: email.id,
      subject: email.subject,
      from: email.from,
      to: email.to,
      body: email.body,
      isRead: email.isRead
    }
  }));

  return results;
} catch (error) {
  ld.log('Error fetching emails:', error.message);
  return [];
}

Trigger mit Dateianhängen

Wenn Trigger Ereignisse mit Dateien erkennen, füge sie in das Datenobjekt ein:
const results = [];

for (const email of emails) {
  const attachments = [];

  // Process email attachments
  if (email.attachments && email.attachments.length > 0) {
    for (const attachment of email.attachments) {
      const content = await downloadAttachment(attachment.id);

      attachments.push({
        fileName: attachment.filename,
        mimeType: attachment.mimeType,
        base64: content.toString('base64')
      });
    }
  }

  results.push({
    id: email.id,
    timestamp: email.receivedAt,
    data: {
      subject: email.subject,
      from: email.from,
      body: email.body,
      files: attachments  // Files go inside data object
    }
  });
}

return results;

Webhook-Trigger einrichten

  1. Trigger hinzufügen: Wähle den Typ “Webhook”
  2. Endpunkt konfigurieren: Notiere dir die bereitgestellte Webhook-URL
  3. Externes System einrichten: Konfiguriere deinen Service, um Ereignisse an die Webhook-URL zu senden
  4. Verarbeitungscode schreiben: Eingehende Webhook-Daten transformieren (optional)
  5. Testen: Sende Testereignisse, um die Funktionalität zu verifizieren

Webhook-Verarbeitungsbeispiel

// Transform incoming webhook data
const webhookData = data.input.webhookPayload;

return [
  {
    id: webhookData.event_id || crypto.randomUUID(),
    timestamp: webhookData.timestamp || new Date().toISOString(),
    data: {
      eventType: webhookData.type,
      resourceId: webhookData.resource_id,
      action: webhookData.action,
      changes: webhookData.changes,
      // Transform webhook format to your preferred structure
    }
  }
];

Native Aktionen

Native Aktionen ermöglichen es dir, Dateien nativ zu suchen und herunterzuladen, die nicht lokal auf dem Gerät eines Nutzers gespeichert sind. Wir haben bereits native Aktionen für SharePoint, OneDrive, Google Drive und Confluence erstellt. Du kannst über den Button Dateien auswählen darauf zugreifen, um Dateien direkt im Chat oder im Assistenten-Wissen zu suchen und anzuhängen. Native Actions Chat Dateien mit nativen Integrationen an den Chat anhängen. Native Actions Knowledge Dateien mit einer nativen Integration an das Assistenten-Wissen anhängen. Das Erstellen nativer Aktionen für andere Tools ermöglicht es dir, Dateien von diesen Plattformen auf die gleiche Weise zu suchen und herunterzuladen.

Eine native Aktion einrichten

Um eine native Aktion einzurichten, beginne wie gewohnt mit dem Erstellen deiner Integration. Füge eine weitere Aktion hinzu und wähle in Schritt 1 unter Erweitert entweder “Dateien suchen” oder “Datei herunterladen” als Aktionstyp. Danach erstellst du die Aktion wie jede andere Aktion, aber deine Funktion muss eine spezifische Objektstruktur zurückgeben. Dies gewährleistet Kompatibilität und ermöglicht es Assistenten, Dateien und Suchergebnisse korrekt zu verarbeiten.

Erforderliches Ausgabeformat

Abhängig von der ausgewählten Aktion muss deine Funktion eine spezifische Objektstruktur zurückgeben. Dies gewährleistet Kompatibilität und ermöglicht es Assistenten, Dateien und Suchergebnisse korrekt zu verarbeiten. Dateien suchen: Beim Erstellen einer nativen Suchintegration muss deine Funktion ein Array von Objekten zurückgeben, die dem folgenden Schema entsprechen:
{
  url: string,
  documentId: string,
  title: string,
  author?: {
    id: string,
    name: string,
    imgUrl?: string,
  },
  mimeType: string,
  lastSeenByUser: Date,
  createdDate: Date,
  lastModifiedByAnyone: Date,
  lastModifiedByUserId?: {
    id?: string,
    name?: string,
    lastModifiedByUserIdDate: Date,
  },
  parent?: {
    id: string,
    title?: string,
    url?: string,
    type?: string,
    driveId?: string,
    siteId?: string,
    listId?: string,
    listItemId?: string,
  }
}
Der title und mimeType werden in der Nutzeroberfläche für alle Suchergebnisse angezeigt. Bitte sieh dir auch eine detaillierte Beschreibung für jeden Parameter an: Below you can find an example implementation for the native SharePoint Search files action. Download file
For native download actions, return an object in the following format:
{
  data: response.data,
  fileName: string,
  mimeType: string,
  buffer: response.buffer, // Conditional
  url: string,
  lastModified: Date,
  text: string // Conditional
}
The fileName and mimeType will be displayed in the UI for all search results. Please also check out a detailed description for each parameter: Below you can find an example implementation for the native SharePoint Download file action.

Auf Eingabefelder zugreifen

Verwende data.input.{inputFieldId} für Eingabefeldwerte und data.auth.{authenticationFieldId} für Authentifizierungsfeldwerte aus der aktuellen Verbindung des Nutzers.

Integrierte Funktionen für benutzerdefinierte Code-Abschnitte

Verwende unseren Integrations-Assistenten, um dir beim Einrichten deiner Integrationsfunktionen zu helfen.

Grundlegende Funktionen

Die benutzerdefinierte Client-Bibliothek ld enthält die Kernfunktionalität, die für die Implementierung von Authentifizierungsabläufen benötigt wird. ld.request() erstellt eine Webanfrage im Format des übergebenen Objekts und gibt die Antwort zurück. Die Parameter müssen gültige JSON-Objekte sein, da intern JSON.stringify() aufgerufen wird. Für komplexe JSON-Objekte musst du zuerst JSON.parse() anwenden. ld.log() gibt die übergebenen Werte im Logs-Feld aus, das nach dem Ausführen einer Aktion unter dem Button Aktion testen erscheint. Beispielverwendung aus der Google Calendar-Integration:
const options = {
  method: 'GET',
  url: `https://www.googleapis.com/calendar/v3/calendars/${data.input.calendarId}/events/${data.input.eventId}`,
  headers: {
    'Authorization': 'Bearer ' + data.auth.access_token,
    'Accept': 'application/json',
  },
};

const response = await ld.request(options);

return response.json;

JSON

Sowohl JSON.stringify() (Konvertierung eines JavaScript-JSON-Objekts in einen String) als auch JSON.parse() (Konvertierung eines Strings in ein JavaScript-JSON-Objekt) sind in benutzerdefinierten Code-Blöcken verfügbar. Die an die Funktion ld.request() übergebenen Parameter müssen gültige JSON-Objekte sein, da intern JSON.stringify() aufgerufen wird. Für komplexe JSON-Strukturen musst du vorher JSON.parse() anwenden, um eine korrekte Formatierung sicherzustellen. Beispielverwendung aus der HubSpot-Integration:
const properties = data.input.properties
  ? JSON.parse(data.input.properties)
  : {};

const options = {
  method: "PATCH",
  url: `https://api.hubapi.com/crm/v3/objects/companies/${data.input.companyId}`,
  headers: {
    Authorization: "Bearer " + data.auth.access_token,
    "Content-Type": "application/json",
  },
  body: {
    properties: properties,
  },
};

Base 64

Da einige OAuth-Clients Base64-codierte Client-Anmeldedaten für die Basic-Authentifizierung benötigen, haben wir eine Hilfsfunktion dafür erstellt. btoa() codiert einen String in Base64, während atob() einen Base64-String zurück in Klartext decodiert. Beispielverwendung:
const auth = btoa(`${env.CLIENT_ID}:${env.CLIENT_SECRET}`);

Sandbox-Bibliotheksbeschränkungen

Nutzerdefinierter Integrationscode läuft in einer sicheren Sandbox-Umgebung.
Du kannst keine externen Bibliotheken installieren oder importieren (npm, pip usw.) – nur eine begrenzte Anzahl integrierter JavaScript/Node.js-APIs ist verfügbar.
Für erweiterte Verarbeitung (z.B. PDF-Parsing, Bildbearbeitung) verwende externe APIs oder Services und rufe sie aus deinem Integrationscode auf.

Best Practices

Aktionsdesign

  • Einzelne Verantwortlichkeit: Jede Aktion sollte eine Sache gut machen
  • Klare Benennung: Verwende beschreibende Aktionsnamen, die den Zweck erklären
  • Eingabevalidierung: Validiere immer erforderliche Eingaben und gib hilfreiche Fehlermeldungen aus
  • Fehlerbehandlung: Fange API-Fehler ab und behandle sie angemessen
  • Protokollierung: Verwende ld.log() zur Unterstützung beim Debugging

ID-Verwaltung

Die meisten API-Aufrufe erfordern spezifische interne IDs. Die Herausforderung besteht darin, dass Assistenten diese IDs nicht erraten können, was zu einer schlechten Nutzererfahrung führt, wenn Aktionen wie “spezifischen Kontakt in HubSpot abrufen” oder “Ereignis zu spezifischem Kalender in Google Calendar hinzufügen” aufgerufen werden. Die Lösung: Erstelle Hilfsaktionen, die diese IDs zuerst abrufen und an den Assistenten zurückgeben. Beispielsweise verwendet unsere Funktion Deal-Kontext abrufen für HubSpot GET-Endpunkte, um interne IDs für verfügbare Pipelines und Phasen zu sammeln. Dies ermöglicht es Assistenten, Aktionen wie Deal erstellen oder Deal aktualisieren viel effektiver zu nutzen, da sie nun den erforderlichen Kontext haben.

Performance

  • API-Aufrufe minimieren: Batch-Operationen verwenden, wenn möglich
  • Paginierung verwenden: Große Datensätze angemessen verarbeiten
  • Timeout-Behandlung: Angemessene Timeouts für externe API-Aufrufe setzen

Sicherheit

  • Eingaben validieren: Vertraue niemals Nutzereingaben ohne Validierung
  • Daten bereinigen: Bereinige Daten, bevor du sie an externe APIs sendest
  • Geheimnisse verwalten: Verwende Authentifizierungsfelder für sensible Daten, niemals hartcodieren
  • Rate Limiting: Respektiere API-Rate-Limits und implementiere Backoff-Strategien