Integrieren · E3 · 7 Stufen

Funktionen & HTTP-Services mit ScriptEngine

Track E dockt AuxData an die Außenwelt an. In E4 baust du die ScriptEngine-Mechanik selbst: das Modell, die Sprache ES5.1, die Module mit ihren Signaturen, Umgebungsvariablen, den HTTP-Service-Editor und eine vollständige, robuste Funktion.

Was du in diesem Tutorial baust

Wir bauen die Preisabfrage-/E-Mail-Funktion aus C5 als eigenständiges, robustes Modul nach — eine ScriptEngine-Funktion, die einen Parameter validiert, per HTTP einen externen Dienst abfragt, das Ergebnis protokolliert und über einen sauberen Fehlerpfad immer einen definierten String zurückliefert. Dazu kommt der passende HTTP-Service im Editor.

Voraussetzung: Track B, gut ergänzt durch C5 (HTTP/Funktion/MCP im Workflow), und ein Grundverständnis von JavaScript. Keine echten Secrets, Tokens oder Endpunkte — alle Zugangsdaten liegen in Umgebungsvariablen (api_token, db_password) bzw. als ${env.NAME}-Platzhalter.

Abgrenzung zu C5: C5 zeigt die Nutzung von HTTP-Service und Funktion als Vor-/Nachverarbeitung im Workflow. E4 vertieft die Mechanismen selbst. Das Programmierhandbuch (ScriptEngine) ist Primärquelle für Syntax, Module und Signaturen; AH 9.1/9.2 ergänzt Editor und Sicherheit.

Quellen und Stand

Geprüft gegen das AuxData-Programmierhandbuch (ScriptEngine) v2.4.1 (Stand 07.09.2026), Abschnitte „ECMAScript 5.1 Referenz“, „Umgebungsvariablen in der ScriptEngine“, „Verfügbare Module in der ScriptEngine“, „Code-Beispiele für die ScriptEngine“, „Best Practices für die ScriptEngine“, „Tutorial: Erste Funktion erstellen“, „KI-Assistent im Funktions-Editor“, „Funktions-Testfälle“ und „Nachschlagen im Funktions-Editor“; ergänzend das AuxData-Administratorhandbuch v2.4.1 (Stand 07.09.2026), Kapitel 9.1, 9.2 und 20. Alle Tokens und Endpunkte in den Beispielen sind Platzhalter.

Stufe 1 von 7

ScriptEngine-Modell

Wie eine Funktion läuft — und warum jeder Parameter ein String ist.

1Otto-Engine und ES5.1-Sandbox

Die ScriptEngine basiert auf der Otto-JavaScript-Engine und unterstützt ECMAScript 5.1. Sie läuft als Sandbox ohne Dateisystem- oder Netz-IO außerhalb der eingebauten Module. (PH Einführung; AH 9.2)

Du schreibst keine vollständige Datei, sondern nur den Rumpf einer Funktion. Die Plattform legt einen künstlichen Funktionskopf um deinen Code und ruft ihn mit den übergebenen Parametern auf.

In Klartext: Dein Code läuft in einer abgeschotteten Mini-JavaScript-Umgebung — kein Internet- oder Dateizugriff außer über die freigegebenen Module. Du schreibst nur den Inhalt der Funktion; den Rahmen drumherum setzt AuxData automatisch.

2Funktionssignatur & String-Konvertierung

Die Plattform umschließt deinen Code etwa so — du lieferst nur den markierten Rumpf:

// Künstlicher Kopf der Plattform (nur zur Veranschaulichung):
function executorFunctionWrapper(parameter1, parameter2) {

  // ── ab hier schreibst du den Rumpf ──
  // Wichtig: ALLE Parameter kommen als String an!
  var summe = parseInt(parameter1) + parseInt(parameter2); // numerisch
  return String(summe); // Rückgabe wird als String erwartet

}
Achtung, String-Falle: Bei den Eingaben 5 und 8 liefert return parameter1 + parameter2 die Zeichenkette "58" statt 13 — weil Strings verkettet werden. Erst parseInt(...) bzw. parseFloat(...) rechnet numerisch.

Der Rückgabewert wird als String erwartet. Ohne return oder bei einem Abbruch im Fehlerfall ist der Rückgabewert undefined.

✎ Übung: Warum liefert return zahl1 + zahl2 bei den Eingaben 5 und 8 das Ergebnis „58" — und wie behebst du es?

✓ Das hast du jetzt verstanden

Stufe 2 von 7

Sprache & Muster (ECMAScript 5.1)

Was Otto kann — und welche ES6-Annahmen scheitern.

1Was ES5.1 unterstützt

Unterstützt sind var (kein let/const), die Typen String/Number/Boolean/Array/Object/null/undefined, die üblichen Operatoren, if/else, for, while, JSON.stringify/JSON.parse sowie eingebaute String-/Array-/Math-/Date-Funktionen. (PH ECMAScript-5.1-Referenz)

var namen = ["Anna", "Ben"];   // Array mit []
namen.push("Carla");           // mit push füllen

var antwort = "";
for (var i = 0; i < namen.length; i++) {
  if (namen[i] === "Ben") {    // strenge Gleichheit
    antwort = "gefunden";
  }
}

var daten = JSON.parse('{"ok": true}'); // String -> Objekt
var text  = JSON.stringify(daten);      // Objekt -> String

2Nicht unterstützt (ES6+)

Diese Konstrukte laufen in Otto nicht: let/const, Arrow-Funktionen, Template-Strings, Destructuring, Spread, class, Promise, async/await.

Keine ES6-Annahmen: Template-Strings (`Hallo ${name}`) und Arrow-Funktionen (var f = () => x) scheitern. Nutze "Hallo " + name und klassische function-Ausdrücke.

Häufige Fehler: var nicht vergessen (sonst entsteht eine globale Variable); konsequent strenge Gleichheit (===) verwenden; Arrays als [] anlegen und mit push füllen.

✎ Übung: Welche zwei der folgenden sind in ES5.1 verboten: let x = 1, var x = 1, var f = () => x, function f() {}?

✓ Das hast du jetzt verstanden

Stufe 3 von 7

Module & Signaturen

Erst getModule, dann die Funktionen — mit exakten Signaturen.

1Module initialisieren

Jedes Modul wird zuerst mit getModule("modulname") initialisiert; danach stehen seine Funktionen als globale Namen bereit. (PH Module; AH 9.2)

getModule("log");
getModule("http");

log_info("Modul http bereit");
var antwort = http_get("https://api.example.com/v1/data", {});
🧠 Für Profis: Schrittergebnisse ohne getModule — aiserviceresults
Läuft die Funktion als Schritt eines AI-Workflows, stellt die Plattform die Ergebnisse aller vorherigen Schritte als globale Variable aiserviceresults bereit — anders als Module braucht sie kein getModule(). Die Reihenfolge ist chronologisch: aiserviceresults[0] ist der älteste, aiserviceresults[aiserviceresults.length - 1] der unmittelbar vorhergehende Schritt. Außerhalb eines Workflows (Einzelaufruf) ist sie null — vor dem Zugriff prüfen: if (aiserviceresults === null) { … }. (Programmierhandbuch)

2Wichtige Module & exakte Signaturen

http
http_get(url, header), http_post(url, contentType, header, body), http_put(url, contentType, header, body), http_delete(url, header), http_queryEscape(value), http_search(search, exactMatch).
graphapi
graphapi_getResource(graphApiConfig, url), graphapi_postResource(graphApiConfig, url, body), graphapi_putResource(graphApiConfig, url, body), graphapi_deleteResource(graphApiConfig, url), graphapi_send(graphApiConfig, mail), graphapi_getNewFromInbox(graphApiConfig, maxCount).
aiservice
aiservice_run(agentId, serviceId, params), aiservice_runAsync(agentId, serviceId, params), aiservice_runWithToken(token, agentId, serviceId, params); Ergebnis über resultObj.MultiResults.Results[0].Result.
knowledgedb
saveText(agentId, containerId, name, content, documentId), saveBinary(agentId, containerId, name, content, documentId), find(searchText, agentId, containerId, qualityGate, resultLimit), findByKeyword(searchText, agentId, containerId, resultLimit).
personalknowledgedb
Lese-/Schreibzugriff auf die persönliche Wissens-DB des ausführenden Users — ohne Agent-/Container-Parameter.
sql
sql_execute(connectionConfig, sqlCommand), sql_query(connectionConfig, sqlCommand).
email
send(mail, smtpConfig), getNewFromInbox(imapConfig), getByCriteria(imapConfig, criteria), move(mailId, originFolder, destinationFolder, imapConfig).
document
document_readText(agentId, filename, filecontent, readImages).
user
user_getUser().
organisation
organisation_getOrganisation() — liefert u. a. ADConfig (MsGraphTenantId/ClientId/ClientSecret) und TeamsBotConfig; ideal, um graphApiConfig direkt aus der Org zu bauen statt aus Umgebungsvariablen.
log
log_info(message), log_warn(message), log_error(message), log_fatal(message), log_logs().
weitere
webcrawler_crawlWeb(url), webcrawler_crawlWebEnhanced(url, depth, pageCount) (max. Tiefe 3, 10 Seiten), webcrawler_liveSearch(prompt, maxPages, searchMode); docdb_load(documentId), docdb_save(documentId, document), docdb_delete(documentId).
Sicherheit & Voraussetzungen: SQL-Zugriff nur für Admins (AH 9.2). Die Module sql, graphapi und email brauchen ein Connection- bzw. Config-Objekt als ersten Parameter.
Mehrere Teilergebnisse: Liefert ein AI-Service mehrere Schritte, iterierst du über MultiResults.Results und filterst versteckte mit results[i].ServiceStepCommand.Displaytype != "Hidden"; aiservice_runWithToken(token, …) erlaubt Aufrufe ohne User-Auth (API-/Integrationskontext). (Programmierhandbuch)
Versionen: Jedes Speichern einer Funktion legt automatisch eine Version an — bis zu 50 unbenannte, benannte unbegrenzt; anschauen (Read-only), wiederherstellen (sichert vorher den aktuellen Stand) und löschen sind möglich (die aktive Version nicht). (AH 9.6)
✎ Übung: Welches Modul und welche Funktion liest ein hochgeladenes PDF als Text aus?

✓ Das hast du jetzt verstanden

Stufe 4 von 7

Umgebungsvariablen & Secrets

Werte aus dem Code heraushalten — und api_token sauber von ${env.NAME} trennen.

1Org- vs. Funktions-Variablen

Umgebungsvariablen halten Werte aus dem Code heraus, die keine Funktionsparameter sind (typisch: API-Tokens). Du setzt sie an der Organisation (gelten für jeden Funktionsaufruf) oder an der Funktion. (PH Umgebungsvariablen; AH 9.1/9.2)

Bei Namensgleichheit überschreibt die Organisation die Funktion. Beim Export einer Funktion wandern die Variablen-Deklarationen, aber nicht die Werte mit — so geraten keine Secrets in eine fremde Organisation. Vordefiniert ist timeout (Sekunden; nur an der Funktion wirksam, an der Organisation ignoriert; Default 600 s).

2Zugriff in der Funktion vs. im HTTP-Service

In der Funktion steht eine Umgebungsvariable als globaler Name bereit:

// Umgebungsvariable "api_token" steht als globaler Name bereit:
var apiKey = api_token;

// niemals hart codieren, niemals ins Log schreiben!
log_info("API-Aufruf vorbereitet"); // ok
// log_info("Token: " + api_token);  // FALSCH: Secret im Log
Kern-Abgrenzung: Die ScriptEngine-Funktion sieht die Variable direkt als globalen Namen (api_token, db_password). Der HTTP-Service-Editor referenziert dieselbe Idee dagegen in der Anfrage über die Template-Syntax ${env.NAME} (AH 9.1).
Secrets gehören in Umgebungsvariablen — nicht hart codiert in den Funktions-Body, nicht in Prompts und nicht ins Log.
HTTP-Service-Editor (offizielle Abbildung aus dem Admin-Handbuch)
Offizielle Abbildung aus dem Admin-Handbuch (Kap. 7) — der HTTP-Service-Editor.

3Key Value Store: Werte außerhalb des Skripts

Den organisationsweiten Schlüssel-Wert-Speicher kannte die ScriptEngine schon über docdb_load, docdb_save und docdb_delete. Seit v2.4.1 gibt es dafür eine Oberfläche: Einstellungen → Key Value Store, nur für Organisations-Administratoren (AH 20).

Damit lassen sich Werte einsehen, anlegen, bearbeiten, umbenennen und löschen, ohne ein Skript zu schreiben. Typisch sind Konfigurationswerte, die Skripte zur Laufzeit lesen (Endpunkte, Schwellwerte, Feature-Flags), Zwischenergebnisse mehrerer Workflows und Vorbelegungen, bevor ein Skript zum ersten Mal läuft.

Es ist derselbe Speicher. Was du hier änderst, sehen alle Skripte der Organisation sofort — und umgekehrt. Ein Schlüssel ist höchstens 64 Zeichen lang; die Liste zeigt Schlüssel und Bytegröße, der Wert wird erst beim Anklicken nachgeladen.
Abgrenzung zu Umgebungsvariablen: Umgebungsvariablen sind für Geheimnisse und werden vertraulich behandelt. Der Key Value Store ist für Werte, die sich zur Laufzeit ändern und die auch mal jemand von Hand korrigieren soll. Zugangsdaten gehören weiterhin in die Umgebungsvariablen, nicht hierher.
✎ Übung: Eine Variable heißt an Organisation und Funktion gleich — welcher Wert greift?

✓ Das hast du jetzt verstanden

Stufe 5 von 7

HTTP-Service-Editor

Ein vordefinierter REST-Aufruf — gepflegt auf Organisationsebene.

1Der Editor und seine Reiter

Der HTTP-Service ist ein vordefinierter REST-Aufruf, gepflegt auf Organisationsebene (Org-Admin+). Editor httpserviceeditor.html mit den Reitern Stammdaten, Anfrage, Parameter und Umgebungsvariablen. (AH 9.1)

StammdatenAnfrageParameterUmgebungsvariablen
Anfrage
URL
https://api.example.com/v1/data
Methode
GETPOSTPUTDELETE
Content-Type
application/json
HeaderKey-Value-Paare
Authorization: Bearer ${env.AUX_TOKEN}
Request-BodyTemplate im ACE-Editor
{ "name": "${parameter}" }
Echter HTTP-Service-Editor (Demo-Instanz), Reiter Anfrage: Endpunkt mit URL, Methode GET, Content-Type und Body-Editor
Echter HTTP-Service-Editor an der Demo-Instanz (Reiter „Anfrage"): URL, Methode, Content-Type, Body — Demo-Platzhalter
Testdurchführung eines HTTP-Services (offizielle Abbildung aus dem Admin-Handbuch)
Offizielle Abbildung aus dem Admin-Handbuch (Kap. 7) — die Testdurchführung eines HTTP-Services.

Parameter (Name, Beschreibung, Default, Pflichtfeld) werden vom Aufrufer bzw. Workflow-Schritt gefüllt und im Body als ${parameter} referenziert. Umgebungsvariablen sind ein separater Schlüssel-Wert-Speicher für Secrets und produktionsabhängige URLs; sie lassen sich über ${env.NAME} in der Anfrage referenzieren und werden verschlüsselt in http_request.env gespeichert. Die eigene Testseite führt einen Probe-Aufruf aus und zeigt Request, Response, Status und Parsing-Ergebnis.

Sicherheit: Lege Tokens als Umgebungsvariablen ab und übergib sie bevorzugt im Header. Packe Secrets nicht als fachliches Body-Feld mit; Body-Auth wäre eine bewusst zu prüfende Ausnahme. HTTP-Calls werden gegen die URL-Whitelist geprüft (AH 9.2).
✎ Übung: Wo trägst du den API-Key ein — bei „Header" direkt oder bei „Umgebungsvariablen"?

✓ Das hast du jetzt verstanden

Stufe 6 von 7

Code-Beispiele — eine vollständige Funktion

Validierung → Logging → HTTP-Aufruf → Fehlerpfad.

1Die Demo-Funktion zusammengesetzt

Wir setzen die Demo-Funktion vollständig zusammen, nach dem Muster aus dem PH-Tutorial „Erste Funktion erstellen". (PH Code-Beispiele; AH 9.2)

// Module einmal am Anfang initialisieren
getModule("log");
getModule("http");

// Aufruf protokollieren (keine Rohdaten, keine Secrets)
log_info("Funktion aufgerufen; Parameter name erhalten");

// 1) Parameter validieren
if (!name || typeof name !== "string" || name.trim() === "") {
  log_warn("Ungültiger Parameter: name fehlt oder ist leer");
  return "FEHLER: Parameter 'name' fehlt oder ist leer.";
}

var cleanName = name.trim();

// 2) Pflicht-Secret prüfen, ohne den Wert zu loggen
if (!api_token || typeof api_token !== "string" || api_token.trim() === "") {
  log_error("Umgebungsvariable api_token fehlt");
  return "FEHLER: API-Konfiguration fehlt.";
}

var cleanApiToken = api_token.trim();

// 3) HTTP-Aufruf im try-Block
try {
  var header = {};
  header["Authorization"] = "Bearer " + cleanApiToken; // aus Umgebungsvariable
  header["Content-Type"]  = "application/json";

  // URL-Bestandteile mit dem HTTP-Modul absichern
  var sicher = http_queryEscape(cleanName);
  var url = "https://api.example.com/v1/greeting?name=" + sicher;

  var response = http_get(url, header);
  log_info("HTTP-Antwort erhalten");
  return "Hallo " + cleanName + "! Antwort: " + response;

} catch (error) {
  // 4) Fehlerpfad: immer ein definierter String
  log_error("HTTP-Anfrage fehlgeschlagen: " + error);
  return "Hallo " + cleanName + "! Willkommen in der ScriptEngine.";
}
Caveat: URL, Token-Name, Header und Endpunkt sind Demo-Platzhalter und gegen die konkrete Instanz bzw. das PH zu prüfen. Das ist ein Muster, kein blindes Copy-Paste-Skript.

Die Funktion gibt über jeden Pfad — Eingabevalidierung, Secret-Prüfung, Erfolg, Fehler — immer einen definierten String zurück. Sie loggt keinen Token-Wert, nutzt den getrimmten Namen nur einmal und escaped URL-Bestandteile mit der vom HTTP-Modul bereitgestellten Funktion.

2Der KI-Assistent im Funktions-Editor

Im Reiter Code sitzt rechts neben dem Editor ein KI-Assistent. Du beschreibst die Anforderung in normaler Sprache, er erzeugt Otto-ES5-Code, prüft ihn und legt das Ergebnis als Diff gegen deinen aktuellen Stand vor. Voraussetzung ist ein konfigurierter Coder-Agent mit aktiver modellbasierter Antwortgenerierung — fehlt der, kommt statt Code eine Absage.

Jede Code-Antwort beginnt mit einer Zeile Verstanden: …, also der Interpretation deiner Anforderung. Danach folgen eine kurze Erklärung, vier Prüf-Badges und der Diff. Geprüft wird vor der Anzeige:

Syntax
Kompilierung mit der echten Otto-Engine, einschließlich der nicht unterstützten RegExp-Operatoren.
API
Abgleich der genutzten Module gegen die Funktionsreferenz.
Logik
KI-Review gegen die eingangs formulierte Absicht.
Parameter
Abgleich der Parameterliste mit dem erzeugten Code.
Die Parameterliste wird aus dem Code abgeleitet, nicht umgekehrt. Ein deklarierter Parameter, den der Code nicht liest, wird entfernt; eine gelesene Variable, die noch kein Parameter ist, wird ergänzt. Werte, die über eine Umgebungsvariable kommen, werden nicht zu Parametern — der Assistent kennt die hinterlegten Variablen und nutzt sie direkt. Beim Übernehmen wandert die abgeglichene Liste in den Reiter Parameter.
Er kostet Token. Der Verbrauch wird deiner Organisation berechnet. Unter den Antworten steht der Sitzungsverbrauch als Tanksäule; die Aufschlüsselung listet die Einzelposten (Codier-Modell, Logikprüfung, Wissens-Einbettung). Finden Syntax-, API- oder Logikprüfung Probleme, korrigiert sich der Assistent automatisch — jede Runde kostet zusätzlich.

Übernehmen ersetzt den Editor-Inhalt, Verwerfen lässt deinen Code unangetastet. Der Verlauf wird wie ein Chat gespeichert, der Assistent erinnert sich an etwa zehn Gesprächsrunden. Über Frühere Sessions (Uhr-Symbol) erreichst du die letzten zehn Gespräche dieser Funktion.

3Funktions-Testfälle

Auch einzelne Funktionen lassen sich jetzt automatisiert prüfen. Ein Testfall speichert eine Parameterbelegung samt erwartetem Ergebnis; spätere Läufe werden dagegen verglichen.

  1. Funktion öffnen und Speichern & Testen klicken (oder direkt die Testseite aufrufen).
  2. Im Eingabe-Schritt die Parameterwerte setzen und Ausführen.
  3. In der Ergebnisansicht Als Testfall speichern wählen und benennen.
  4. Der Testfall erscheint im Reiter Tests des Funktions-Editors, wo auch der Prüfmodus eingestellt wird.
Das gespeicherte Ergebnis ist die Referenz für alle künftigen Läufe. Ändert sich die Ausgabe der Funktion, schlägt der Test fehl oder erreicht einen niedrigeren Score. Also nur Läufe speichern, die fachlich abgenommen sind.
Nicht dasselbe wie AI-Service-Testfälle: Die prüfen einen ganzen Service samt Workflow-Schritten und bewerten per Sprachmodell (siehe C10). Funktions-Testfälle prüfen eine einzelne Funktion. Beides ergänzt sich: erst die Funktion absichern, dann den Service, der sie benutzt.

Dazu kommt Nachschlagen im Funktions-Editor: die Funktionsreferenz ist direkt aus dem Editor erreichbar, statt sie im Handbuch zu suchen.

✎ Übung: Welche Fehlermeldung würdest du bei fehlendem api_token zurückgeben, damit Nutzende genug Kontext bekommen, aber keinen internen Token-Namen oder Endpunkt sehen?

✓ Das hast du jetzt gebaut

Stufe 7 von 7

Best Practices & Sicherheit

Robust, validiert und sicher — die Regeln aus dem Handbuch.

1Best Practices

Sieben Regeln aus dem Programmierhandbuch, die jede Funktion produktionsreif machen. (PH Best Practices)

Fehlerbehandlung
immer try/catch + log_error.
Logging
großzügig log_info, aber keine Passwörter/Tokens loggen.
Module
nur einmal am Anfang initialisieren.
Validierung
Parameter prüfen mit typeof, isNaN, trim.
Struktur
Funktionen klein halten und in Teilfunktionen zerlegen.
Secrets
sensible Daten in Umgebungsvariablen statt Hartkodierung.
AI-Ergebnisse
vor dem Zugriff prüfen: if (result && result.MultiResults && result.MultiResults.Results.length > 0).

2Sicherheit (AH 9.2)

HTTP-Calls werden gegen die URL-Whitelist geprüft; SQL nur für Admins; die Otto-Sandbox erlaubt kein Dateisystem-/Netz-IO außerhalb der Module. SQL- und HTML-Injection entschärfst du durch Escapen:

// einfache SQL-Escape-Hilfe (Demo): einfache Quotes verdoppeln
var sicher = eingabe.replace(/'/g, "''");

// Logging-Disziplin: Benutzer ja, Passwort niemals
log_info("Login-Versuch für Benutzer: " + benutzername); // erlaubt
// log_info("Passwort: " + passwort);                      // VERBOTEN
Niemals Secrets ins Log: log_info("Login-Versuch für Benutzer: " + benutzername) ist erlaubt — das Passwort darf nicht geloggt werden.

Deine Funktion ist robust, validiert und sicher.

Die Preisabfrage-/E-Mail-Funktion steht als eigenständiges Modul: ES5.1-konform, mit den korrekten Modul-Signaturen, sauberer Trennung von Umgebungsvariablen und ${env.NAME}, einem getesteten HTTP-Service und einem Fehlerpfad, der immer einen definierten String liefert. Weiter mit E5 — Teams-Bot einrichten.

✎ Übung: Nenne zwei Regeln, die verhindern, dass ein API-Token nach außen sichtbar wird.

✓ Das hast du jetzt verinnerlicht

Kurz-Quiz

Sitzt die ScriptEngine?

7 Fragen aus den Stufen 1–7. Kein Zertifikat — zur Selbstkontrolle. Beliebig oft wiederholbar.

Frage 1 von 7
Lade Frage…