Direkt zum Hauptinhalt

Aus einem Skript einen externen Dienst aufrufen

Ziel​

Ein serverseitiges Skript etwas außerhalb der Plattform aufrufen lassen – eine Zahlung einziehen, einem anderen System eine Datensatzänderung melden, jemandem eine E-Mail senden – und dabei die aufgerufene Adresse zu einer Einstellung machen, die ein Administrator steuert, statt zu einer Zeile in Ihrem Skript.

Die zwei Funktionen​

Beide stehen in einem Server-Plug-in-Schritt und in einer benutzerdefinierten API zur Verfügung.

var answer = callService('par_payment_service', '{"reference":"ORD-1","amount":25}');

var sent = sendEmail('par_mail_service', { to: 'buyer@example.test', subject: 'Your order is paid', body: 'Thank you.' });

Der Body kann Text sein, wie oben, oder ein Objekt bzw. eine Liste, die als JSON gesendet wird: callService('par_payment_service', { reference: 'ORD-1', amount: 25 }) sendet dasselbe.

callService antwortet mit einem Objekt:

EigenschaftWas sie ist
statusDer HTTP-Status, mit dem der Dienst geantwortet hat
oktrue für 200–299, sodass der häufige Fall eine Eigenschaft statt Rechnerei ist
bodyDie Antwort als Text
truncatedtrue, wenn die Antwort zu groß war, um vollständig gelesen zu werden

Das erste Argument ist ein Dienstname, keine Adresse​

Das überrascht viele, und es ist der ganze Entwurf.

'par_payment_service' ist der logische Name einer Umgebungsvariablen. Sie deklarieren sie in Ihrer Lösung; ein Administrator setzt ihren Wert – den Endpunkt – in jeder Umgebung. Daher gilt:

  • Ihr Skript sagt, was es aufruft, nie wo;
  • die Entwicklung zeigt auf eine Sandbox und die Produktion auf den echten Anbieter, ohne Änderung an der Lösung;
  • eine Umgebung, die nichts konfiguriert hat, erreicht nichts.

Es gibt bewusst keine Funktion, die eine URL entgegennimmt. Eine solche würde jedem Skript in jedem Mandanten erlauben, eine Verbindung irgendwohin zu öffnen, und keine noch so gründliche nachträgliche Prüfung von Lösungen könnte das rückgängig machen.

Einrichten​

  1. Deklarieren Sie den Dienst. Öffnen Sie im Admin Control Center Umgebungsvariablen und legen Sie eine an – par_payment_service, Typ Text. Geben Sie ihr eine Beschreibung, wofür sie da ist; die Person, die sie in der Produktion setzt, sind vielleicht nicht Sie.
  2. Fügen Sie sie Ihrer Lösung hinzu, damit sie mitreist. Die Deklaration einer Variablen reist mit; ihr Wert nicht – so bleiben die Einstellungen der Entwicklung aus der Produktion heraus.
  3. Setzen Sie den Wert in dieser Umgebung – den Endpunkt, eine absolute http://- oder https://-Adresse.
  4. Schreiben Sie den Schritt. Rufen Sie in Ihrem Plug-in-Schritt oder Ihrer benutzerdefinierten API callService mit diesem Namen auf.

Von welcher Seite des Speicherns aus aufrufen​

Ein Server-Plug-in-Schritt läuft entweder vor oder nach dem Schreiben des Datensatzes, und ausgehende Aufrufe gehören je nach Art auf unterschiedliche Seiten:

AufrufPhaseWarum
Eine Zahlung einziehen, Bestand in einem anderen System reservierenPreOperationDas geschieht innerhalb der Transaktion des Speicherns; scheitert danach das Speichern des Datensatzes, bleibt nichts zurück, das behauptet, Geld sei eingezogen worden
Eine Bestätigung senden, ein anderes System benachrichtigenPostOperationDer Datensatz existiert dann bereits; ein ausgefallener E-Mail-Dienst verzögert also eine Nachricht, statt den Datensatz rückgängig zu machen

Ein Aufruf vor dem Speichern hat zehn Sekunden. Er hält das Speichern offen, während er wartet, und ein Mensch schaut auf einen Ladekreisel. Braucht der aufgerufene Dienst länger, machen Sie den Schritt asynchron – dann läuft er nach dem Speichern, eigenständig, und kann so lange brauchen, wie er muss.

Was als Fehler zählt​

Diese Unterscheidung lohnt sich, einmal zu lernen, weil sie bestimmt, wie viel von Ihrem Skript Sie schreiben müssen:

  • Ein Status, den der Dienst gewählt hat, ist eine Antwort. Ein 402 eines Zahlungsanbieters bedeutet, dass die Karte abgelehnt wurde – ein gewöhnliches Ergebnis, über das Sie entscheiden. Ihr Skript erhält es in answer.status und läuft weiter.
  • Gar keine Antwort ist ein Fehler und hält den Schritt von selbst an: kein solcher Dienst, kein Endpunkt in dieser Umgebung gesetzt, ein Endpunkt, der keine Webadresse ist, oder der Dienst hat nie geantwortet. Gegen nichts davon kann ein Skript etwas tun, und weiterzumachen hieße, so zu tun, als hätten Sie mit etwas integriert.

Die meisten Schritte sehen daher so aus:

var answer = callService('par_payment_service', body);
if (answer.ok) {
setValue('par_payment_reference', answer.body);
} else {
throwValidationError(`The payment service refused this order (${answer.status}).`);
}

E-Mails senden​

sendEmail nimmt den Namen des Dienstes und eine Nachricht entgegen und sendet sie per POST an diesen Dienst. Das Nachrichtenformat gehört der Plattform, daher konfiguriert eine Bereitstellung einen E-Mail-Adapter statt einen pro Skript, das je eine Nachricht sendet.

In der NachrichtWas es ist
toAn wen sie geht. Eine Adresse, mehrere durch Kommas oder Semikolons getrennt, oder eine Liste
ccWer eine Kopie erhält, auf dieselbe Weise. Optional
replyToWohin eine Antwort geht, damit ein Kunde der Person antwortet, die geschrieben hat, statt einer No-Reply-Adresse. Optional
subjectDie Betreffzeile
bodyDer Inhalt
htmltrue, wenn der Inhalt HTML ist. Optional; sonst reiner Text

sendEmail hält Ihr Skript nie an. Es antwortet mit { ok, error }. Ist die E-Mail nicht rausgegangen – weil hier niemand einen E-Mail-Dienst eingerichtet hat, die Adresse abgelehnt wurde oder der E-Mail-Dienst ausgefallen war –, ist ok gleich false, und error sagt, warum, in Worten, die nennen, wer es beheben kann. So kann ein Skript den Fehler vermerken und es später erneut versuchen; auf diese Weise markiert Parsware Sales eine E-Mail als Fehlgeschlagen. Soll stattdessen das Speichern anhalten, sagen Sie es:

if (!sent.ok) { throwValidationError(sent.error); }

Ein Skript, das vorher geschrieben wurde, übergab vier Argumente (sendEmail(service, to, subject, body)). Es braucht die oben gezeigte Nachrichtenform.

Die Plattform spricht kein SMTP. Sie sendet per POST an das, was die Umgebung benennt, und das bietet jeder E-Mail-Anbieter an; eine Bereitstellung, deren einziger Weg ein SMTP-Relay ist, stellt einen kleinen HTTP-Endpunkt davor.

Ausprobieren​

Importieren Sie die Beispiellösung business-rules-outbound-calls. Sie hat eine Tabelle „Orders“, zwei als Umgebungsvariablen deklarierte Dienste ohne gesetzten Wert und zwei Schritte – einen, der vor dem Speichern die Zahlung einzieht, und einen, der danach die Bestätigung per E-Mail sendet. Ihre README führt Sie durch das Zeigen der Dienste auf einen Endpunkt, der mit 200 antwortet, dann auf einen, der mit 402 antwortet, und Sie sehen, wie das Speichern abgewiesen wird, ohne dass etwas gespeichert ist.

Siehe auch​