Aller au contenu principal

Joindre un fichier à un enregistrement depuis un script

Objectif​

Permettre à un appelant extérieur — un portail, le système d’un partenaire — de joindre un fichier à un enregistrement par l’intermédiaire d’une API personnalisée, afin que ce soit votre script qui décide de l’enregistrement où il aboutit et de l’autorisation de l’appelant.

Pourquoi cela existe​

Les colonnes Fichier et Image d’un enregistrement ont déjà leurs propres points de terminaison, et un formulaire les utilise. Un portail ne le peut pas : un portail dialogue avec la plateforme par les API personnalisées et rien d’autre, car le contrôle qui tient un client à l’écart des enregistrements d’un autre doit se trouver dans un script, à côté de portalCustomerId(), et non dans le générateur de requêtes d’un site web.

Un script peut donc désormais placer un fichier dans le champ d’un enregistrement et le relire. Les octets voyagent sous forme de texte base64, car un script n’a pas d’autre moyen de les conserver — l’appelant encode, la plateforme décode, et le script ne fait que transmettre la chaîne.

Ce qu’un script peut faire​

putRecordFile(table, id, field, fileName, contentType, contentBase64)Stocke le fichier dans le champ de l’enregistrement. Répond true, ou false s’il n’a pas pu
getRecordFile(table, id, field)Le fichier sous forme d’objet — fileName, contentType, sizeBytes, contentBase64 — ou rien si le champ est vide

Les deux agissent au nom de l’appelant : stocker exige l’autorisation Mise à jour sur l’enregistrement et lire exige Lecture, exactement comme les points de terminaison de fichiers de l’enregistrement. La taille maximale du champ et la règle « images uniquement » relèvent de la plateforme, pas du script.

Étapes​

  1. Donnez à la table une colonne Fichier — par_attachment — et, si une liste doit afficher le nom sans récupérer le fichier, une colonne Texte à côté pour le nom.

  2. Dans le schéma de requête de l’API personnalisée, recevez le fichier sous forme de trois propriétés :

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

    Ou, depuis la série 10 des portails, sous forme d’un seul objet — c’est ce qu’envoie le sélecteur de fichier d’un écran dessiné, et la forme que renvoie 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') remet alors l’objet entier au script, et file.fileName en lit un membre. Si l’appelant est un écran de portail Parsware, utilisez cette forme — voir Permettre aux visiteurs de joindre un fichier.

  3. Dans le script, créez d’abord l’enregistrement, puis le fichier — un fichier d’enregistrement appartient à un enregistrement :

    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. Pour renvoyer un fichier, vérifiez d’abord que l’enregistrement appartient à l’appelant, puis lisez-le :

    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);
    }

Trois pièges fréquents​

  • Vérifiez la propriété avant de lire. getRecordFile s’exécute au nom de l’application appelante, qui peut très bien avoir le droit de lire tous les enregistrements de la table. La question « cet enregistrement appartient-il à cet appelant ? » revient à votre script, et elle se pose en lisant l’enregistrement et en comparant.
  • Le nom sur la ligne est un instantané. La ligne du fichier conserve le vrai nom ; une colonne Texte à côté permet à une liste d’afficher « 📎 report.pdf » sans un appel de fichier par ligne. Écrivez-le au moment où vous stockez le fichier, et il reste juste jusqu’à ce que quelqu’un remplace le fichier par une autre voie.
  • Les gros fichiers ne passent pas par un script. Un fichier qui dépasse la taille maximale du champ est stocké dans le stockage d’objets et diffusé en flux par le point de terminaison de l’enregistrement ; getRecordFile le refuse au lieu de matérialiser des centaines de mégaoctets dans un interpréteur.

Vérifier que cela a fonctionné​

Ouvrez l’enregistrement dans son application : la colonne Fichier affiche le fichier, et le télécharger restitue ce que l’appelant a envoyé. L’historique d’audit enregistre la modification avec le nom et l’empreinte du fichier.

Dépannage​

« expects the file's content as base64 text; what was passed does not decode. » L’appelant a envoyé les octets bruts, ou une URL de données avec son préfixe data:…;base64, encore présent. Envoyez uniquement le base64.

« The file is N bytes; the limit for this field is M bytes. » La taille maximale est dépassée et aucun stockage d’objets n’est configuré pour recevoir le débordement. Demandez à l’appelant un fichier plus petit, ou configurez un compartiment de débordement.

« cannot carry a N-byte file; a script reads files up to M bytes. » Le fichier a débordé vers le stockage d’objets. Servez-le par le point de terminaison de fichiers de l’enregistrement, qui le diffuse en flux.