Direkt zum Hauptinhalt

Einem Datensatz aus einem Skript eine Datei anhängen

Ziel​

Einen externen Aufrufer – ein Portal, das System eines Partners – über eine benutzerdefinierte API eine Datei an einen Datensatz anhängen lassen, sodass Ihr Skript entscheidet, an welchem Datensatz sie landet und ob der Aufrufer das darf.

Warum es das gibt​

Die Datei- und Bildspalten eines Datensatzes haben bereits eigene Endpunkte, und ein Formular verwendet sie. Ein Portal kann das nicht: Ein Portal spricht mit der Plattform nur über benutzerdefinierte APIs, weil die Prüfung, die einen Kunden von den Datensätzen eines anderen fernhält, in einem Skript neben portalCustomerId() stehen muss, nicht im Anfrage-Builder einer Website.

Deshalb kann ein Skript jetzt eine Datei in das Feld eines Datensatzes legen und wieder auslesen. Die Bytes reisen als Base64-Text, weil ein Skript sie anders nicht halten kann – der Aufrufer kodiert, die Plattform dekodiert, und das Skript reicht die Zeichenfolge nur durch.

Was ein Skript tun kann​

putRecordFile(table, id, field, fileName, contentType, contentBase64)Speichert die Datei im Feld des Datensatzes. Antwortet true, oder false, wenn es nicht möglich war
getRecordFile(table, id, field)Die Datei als Objekt – fileName, contentType, sizeBytes, contentBase64 – oder nichts, wenn das Feld leer ist

Beide handeln als der Aufrufer: Speichern erfordert Aktualisieren-Rechte für den Datensatz, Lesen erfordert Lese-Rechte, genau wie bei den eigenen Datei-Endpunkten des Datensatzes. Die Größenbegrenzung des Felds und die Nur-Bilder-Regel gehören der Plattform, nicht dem Skript.

Schritte​

  1. Geben Sie der Tabelle eine Dateispalte – par_attachment – und, falls eine Liste den Namen anzeigen soll, ohne die Datei abzurufen, daneben eine Textspalte für den Namen.

  2. Nehmen Sie die Datei im Anfrageschema der benutzerdefinierten API als drei Eigenschaften entgegen:

    "attachmentName": { "type": "string", "maxLength": 260 },
    "attachmentType": { "type": "string", "maxLength": 200 },
    "attachmentBase64": { "type": "string", "maxLength": 5600000 }

    Oder, seit Portal-Runde 10, als ein Objekt – das sendet die Dateiauswahl eines gezeichneten Bildschirms, und in dieser Form antwortet getRecordFile:

    "par_document": {
    "type": "object",
    "additionalProperties": false,
    "required": ["fileName", "contentType", "contentBase64"],
    "properties": {
    "fileName": { "type": "string", "maxLength": 260 },
    "contentType": { "type": "string", "maxLength": 200 },
    "sizeBytes": { "type": "integer" },
    "contentBase64": { "type": "string", "maxLength": 5600000 }
    }
    }

    getInput('par_document') übergibt dem Skript dann das ganze Objekt, und file.fileName liest eines seiner Elemente. Ist der Aufrufer ein Bildschirm eines Parsware-Portals, verwenden Sie diese Form – siehe Besucher eine Datei anhängen lassen.

  3. Erstellen Sie im Skript zuerst den Datensatz, dann die Datei – eine Datensatzdatei gehört zu einem Datensatz:

    var id = createRecord('par_request', {
    par_name: getInput('subject'),
    par_attachment_name: getInput('attachmentName')
    });
    if (!isEmpty(getInput('attachmentBase64'))) {
    putRecordFile('par_request', id, 'par_attachment',
    getInput('attachmentName'), getInput('attachmentType'), getInput('attachmentBase64'));
    }
  4. Um eine Datei zurückzugeben, prüfen Sie zuerst, ob der Datensatz dem Aufrufer gehört, und lesen Sie sie dann:

    var file = getRecordFile('par_request', id, 'par_attachment');
    if (isEmpty(file)) {
    setStatus(404);
    } else {
    setOutput('fileName', file.fileName);
    setOutput('contentType', file.contentType);
    setOutput('contentBase64', file.contentBase64);
    }

Drei typische Stolperfallen​

  • Prüfen Sie die Zugehörigkeit, bevor Sie lesen. getRecordFile läuft als die aufrufende Anwendung, die durchaus jeden Datensatz der Tabelle lesen darf. Die Frage „Gehört dieser Datensatz diesem Aufrufer?“ muss Ihr Skript stellen, und zwar, indem es den Datensatz liest und vergleicht.
  • Der Name in der Zeile ist eine Momentaufnahme. Die Dateizeile behält den echten Namen; eine Textspalte daneben lässt eine Liste „📎 report.pdf“ anzeigen, ohne pro Zeile einen Dateiaufruf zu brauchen. Schreiben Sie ihn beim Speichern der Datei, und er bleibt korrekt, bis jemand die Datei über einen anderen Weg ersetzt.
  • Große Dateien kommen nicht durch ein Skript. Eine Datei über der Begrenzung des Felds wird im Objektspeicher abgelegt und vom Endpunkt des Datensatzes gestreamt; getRecordFile lehnt sie ab, statt Hunderte Megabyte in einem Interpreter zu materialisieren.

Prüfen, ob es funktioniert hat​

Öffnen Sie den Datensatz in seiner App: Die Dateispalte zeigt die Datei, und ihr Herunterladen liefert zurück, was der Aufrufer gesendet hat. Der Überwachungsverlauf vermerkt die Änderung mit dem Namen und dem Hash der Datei.

Fehlerbehebung​

„erwartet den Inhalt der Datei als Base64-Text; das Übergebene lässt sich nicht dekodieren.“ Der Aufrufer hat die rohen Bytes gesendet oder eine Data-URL, an der noch das Präfix data:…;base64, hängt. Senden Sie nur den Base64-Text.

„Die Datei ist N Byte groß; die Grenze für dieses Feld liegt bei M Byte.“ Über der Begrenzung, und es ist kein Objektspeicher für die Auslagerung konfiguriert. Bitten Sie den Aufrufer um etwas Kleineres oder konfigurieren Sie einen Bucket für die Auslagerung.

„kann keine Datei mit N Byte transportieren; ein Skript liest Dateien bis M Byte.“ Die Datei wurde in den Objektspeicher ausgelagert. Liefern Sie sie über den Datei-Endpunkt des Datensatzes aus, der streamt.