Benutzerdefinierte Workflow-Aktionen

Verwenden Sie das Workflow-Tool von HubSpot, um Geschäftsprozesse zu automatisieren und es Ihrem Team zu ermöglichen, effizienter zu arbeiten. Sie können benutzerdefinierte Workflow-Aktionen erstellen, um Ihren Dienst mit den Workflows von HubSpot zu integrieren.

Nachdem Sie Ihre benutzerdefinierte Aktion eingerichtet haben, können Benutzer bei der Installation Ihrer Anwendung die benutzerdefinierte Aktion zu ihren Workflows hinzufügen.

Wenn diese Workflows ausgeführt werden, werden HTTPS-Anfragen an die konfigurierte URL mit der von Ihnen eingerichteten Payload gesendet. Anfragen für Ihre benutzerdefinierte Aktion verwenden die v2-Version der X-HubSpot-Signatur. Erfahren Sie mehr über die Validierung von Anfragen von HubSpot.

Sie können auch zu den folgenden Abschnitten springen:

Der letzte Abschnitt in diesem Artikel enthält mehrere Beispiele für benutzerdefinierte Aktionen.

Bevor Sie loslegen

https://api.hubspot.com/automation/v4/actions/{appId}?hapikey={developer_API_key}

Ihre benutzerdefinierte Aktion definieren

Um eine benutzerdefinierte Workflow-Aktion zu erstellen, müssen Sie die Aktion mithilfe der folgenden Felder definieren. Dadurch wird auch das Format für Anfragen von HubSpot sowie die Verarbeitung von Antworten Ihres Diensts angegeben.

  • actionUrl: Die URL, an die eine HTTPS-Anfrage gesendet wird, wenn die Aktion ausgeführt wird. Der Anfragetext enthält Informationen darüber, für welchen Benutzer die Aktion ausgeführt wird und welche Werte in die Eingabefelder eingegeben wurden.
  • objectTypes: Mit welchen CRM-Objekten diese Aktion verwendet werden kann.
  • published: Standardmäßig werden benutzerdefinierte Aktionen in einem unveröffentlichten Zustand erstellt. Unveröffentlichte Aktionen sind nur im Entwicklerportal Ihrer HubSpot-Anwendung sichtbar. Um eine benutzerdefinierte Aktion für Benutzer sichtbar zu machen, aktualisieren Sie das published-Flag in Ihrer Aktionsdefinition in true.
  • inputFields: Die Eingaben, die die Aktion erhält. Diese werden vom Benutzer ausgefüllt.
  • inputFieldDependencies: Mit diesen Regeln können Felder ausgegraut werden, bis andere Felder bestimmte Bedingungen erfüllen.
  • outputFields: Die Werte, die die Aktion ausgibt, die bei späteren Aktionen im Workflow verwendet werden können. Eine benutzerdefinierte Aktion kann null, eine oder mehrere Ausgaben haben.
  • objectRequestOptions: Eigenschaften des aufgenommenen Objekts, das in der Payload für die actionUrl enthalten ist.
  • labels: Bezeichnung, die dem Benutzer beschreibt, was die Felder der Aktion darstellen und was die Aktion macht. Englische Label sind erforderlich, aber Label können in einer der folgenden unterstützten Sprachen angegeben werden: Französisch (fr), Deutsch (de), Japanisch (ja), Spanisch (es), Portugiesisch (Brasilien) (pt-br) und Niederländisch (nl).
  • executionRules: Eine Liste der Definitionen, die Sie angeben können, damit dem Besucher, der den Workflow erstellt, Fehler von Ihrem Dienst angezeigt werden.
  • functions: Code-Snippets, die ausgeführt werden, um die an eine URL gesendete Payload und/oder die Antwort von dieser URL zu transformieren.

Beispieldefinition für benutzerdefinierte Aktionen

// { "actionUrl":"https://webhook.site/94d09471-6f4c-4a7f-bae2-c9a585dd41e0", "objectTypes":[ "CONTACT" ], "inputFields":[ { "typeDefinition":{ "name":"staticInput", "type":"string", "fieldType":"text" }, "supportedValueTypes":[ "STATIC_VALUE" ], "isRequired":true }, { "typeDefinition":{ "name":"objectInput", "type":"string", "fieldType":"text" }, "supportedValueTypes":[ "OBJECT_PROPERTY" ], "isRequired":true }, { "typeDefinition":{ "name":"optionsInput", "type":"enumeration", "fieldType":"select", "optionsUrl":"https://webhook.site/94d09471-6f4c-4a7f-bae2-c9a585dd41e0" }, "supportedValueTypes":[ "STATIC_VALUE" ] } ], "inputFieldDependencies":[ { "dependencyType":"SINGLE_FIELD", "dependentFieldNames":[ "objectInput" ], "controllingFieldName":"staticInput" } ], "outputFields":[ { "typeDefinition":{ "name":"myOutput", "type":"string", "fieldType":"text" }, "supportedValueTypes":[ "STATIC_VALUE" ] } ], "objectRequestOptions":{ "properties":[ "email" ] }, "labels":{ "en":{ "inputFieldLabels":{ "staticInput":"Static Input", "objectInput":"Object Property Input", "optionsInput":"External Options Input" }, "actionName":"My Extension", "actionDescription":"My Extension Description", "appDisplayName":"My App Display Name", "actionCardContent":"My Action Card Content" } }, "functions":[ { "functionType":"POST_ACTION_EXECUTION", "functionSource":"exports.main = (event, callback) => {\r\n callback({\r\n outputFields: {\r\n myOutput: \"example output value\"\r\n }\r\n });\r\n}" }, { "functionType":"POST_FETCH_OPTIONS", "functionSource":"exports.main = (event, callback) => {\r\n callback({\r\n \"options\": [{\r\n \"label\": \"Big Widget\",\r\n \"description\": \"Big Widget\",\r\n \"value\": \"10\"\r\n },\r\n {\r\n \"label\": \"Small Widget\",\r\n \"description\": \"Small Widget\",\r\n \"value\": \"1\"\r\n }\r\n ]\r\n });\r\n}" } ] }

Die obige Definition rendert Folgendes im Workflows-Tool:

 

Es gibt zwei Arten von Aufrufen für benutzerdefinierte Workflow-Aktionen:

  • Abrufe von Feldoptionen: Füllen Sie eine Liste gültige Optionen aus, wenn ein Benutzer ein Feld konfiguriert. Erfahren Sie mehr über die Verwendung von Feldoptionsabrufen zum Abrufen externer Datenfelder. 
  • Anfragen zur Ausführung einer Aktion: Werden vorgenommen, wenn eine Aktion von einem Workflow ausgeführt wird, der Ihre benutzerdefinierte Aktion enthält. 

Funktionen

Funktionen sind Code-Snippets, die zum Ändern von Payloads verwendet werden, bevor diese an eine API gesendet werden. Sie können Funktionen auch verwenden, um Ergebnisse von einer API zu analysieren. HubSpot-Funktionen werden von AWS Lambda unterstützt. Im folgenden Code:

  • event Enthält die Daten, die an die Funktion übergeben werden 
  • exports.main ist die Methode, die aufgerufen wird, wenn die Funktion ausgeführt wird. 
  • Die callback-Funktion kann verwendet werden, um ein Ergebnis zurückzugeben.

Der Code sollte wie folgt formatiert sein:

exports.main = (event, callback) => { callback({ "data": { "field": "email", "phone": "1234567890" } }); }

Wenn Sie eine Funktion einrichten, wird das functionSource-Format in der Zeichenfolge angezeigt. Stellen Sie sicher, dass die Zeichen im Code ausgeblendet wurden.

Generell folgt die Definition einer Funktion dem Format: 

// { "functionType":"PRE_ACTION_EXECUTION", "functionSource":"exports.main = (event, callback) => {\r\n callback({\r\n \"data\": {\r\n \"field\": \"email\",\r\n \"phone\": \"1234567890\" \r\n }\r\n });\r\n" }

Beispielfunktion

Untersuchen Sie im folgenden Beispiel den Eingabecode, die verwendete Funktion und die erzeugte Ausgabe.  

Funktionseingabe: 

// { "callbackId": "ap-102670506-56777914962-11-0", "origin": { "portalId": 102670506, "actionDefinitionId": 10860211, "actionDefinitionVersion": 1, "extensionDefinitionId": 10860211, "extensionDefinitionVersionId": 1 }, "context": { "source": "WORKFLOWS", "workflowId": 192814114 }, "object": { "objectId": 614, "objectType": "CONTACT" }, "inputFields": { "widgetOwner": "10887165", "widgetName": "My Widget Name" } }

Verwendete Funktion: 

// exports.main = (event, callback) => { callback({ "data": { "myObjectId": event["object"]["objectId"], "myField": event["inputFields"]["widgetName"] } }); }

Erwartete Ausgabe:

// { "data":{ "myObjectId":614, "myField":"My Widget Name" } }

Eingabefelder

Die Eingabefelddefinitionen entsprechen dem folgenden Format:

  • name: Der interne Name des Eingabefelds, getrennt von seinem Label. Das in der Benutzeroberfläche angezeigte Label muss über den labels-Abschnitt der benutzerdefinierten Aktionsdefinition definiert werden.
  • type: Der Typ des Werts, der für die Eingabe erforderlich ist.
  • fieldType: Gibt an, wie das Eingabefeld in der Benutzeroberfläche gerendert werden soll.  Eingabefelder imitieren CRM-Eigenschaften. Erfahren Sie in diesem Artikel mehr über gültige type- und fieldType-Kombinationen
  • supportedValueTypes haben zwei gültige Werte:
    • OBJECT_PROPERTY: Der Benutzer kann eine Eigenschaft vom aufgenommenen Objekt oder eine Ausgabe aus einer vorherigen Aktion auswählen, die als Wert für das Feld verwendet werden soll.
    • STATIC_VALUE: Dies sollte in allen anderen Fällen verwendet werden. Es bedeutet, dass der Benutzer selbst einen Wert eingeben muss. 
  • isRequired: Hiermit wird festgelegt, ob der Benutzer einen Wert für diese Eingabe angeben muss oder nicht

Eingabefelddefinitionen sollten wie folgt formatiert sein: 

// { "typeDefinition":{ "name":"staticInput", "type":"string", "fieldType":"text" }, "supportedValueTypes":[ "STATIC_VALUE" ], "isRequired":true }

Sie können auch Hartcodierungsoptionen für den Benutzer auswählen: 

// { "typeDefinition":{ "name":"widgetColor", "type":"enumeration", "fieldType":"select", "options":[ { "value":"red", "label":"Red" }, { "value":"blue", "label":"Blue" }, { "value":"green", "label":"Green" } ] }, "supportedValueTypes":[ "STATIC_VALUE" ] }

Verwenden externer Daten

Anstelle von Optionen für Hartcodierungsfelder können Sie auch externe Daten mit externen Datenfeldern abrufen. Sie können beispielsweise eine Liste mit Meetingprojekten oder eine Liste mit Produkten als Eingaben abrufen. Das Eingabefeld sollte wie folgt formatiert sein: 

// { "typeDefinition":{ "name":"optionsInput", "type":"enumeration", "fieldType":"select", "optionsUrl":"https://your-url-here.com" }, "supportedValueTypes":[ "STATIC_VALUE" ] }

Die an die optionsURL gesendete Payload wird wie folgt formatiert:

// { "origin": { // The customer's portal ID "portalId": 1, // Your custom action definition ID "actionDefinitionId": 2, // Your custom action definition version "actionDefinitionVersion": 3 }, // The workflow object type the action is being used in "objectTypeId" : "0-1" // The input field you are fetching options for "inputFieldName": "optionsInput", // The values for the fields that have already been filled out by the workflow user "inputFields": { "widgetName": { "type": "OBJECT_PROPERTY", "propertyName": "widget_name" }, "widgetColor": { "type": "STATIC_VALUE", "value": "blue" } }, "fetchOptions": { // The search query provided by the user. This should be used to filter the returned // options. This will only be included if the previous option fetch returned // `searchable: true` and the user has entered a search query. "q": "option label", // The pagination cursor. This will be the same pagination cursor that was returned by // the previous option fetch; it can be used to keep track of which options have already // been fetched. "after": "1234=" } }

Die erwartete Antwort sollte wie folgt formatiert sein: 

// { "options": [ { "label": "Big Widget", "description": "Big Widget", "value": "10" }, { "label": "Small Widget", "description": "Small Widget", "value": "1" } ], // Optional. The pagination cursor. If this is provided, the Workflows app will render // a button to load more results at the bottom of the list of options when a user is // selecting an option, and when the next page is loaded this value will be included in // the request payload under `fetchOptions.after`. "after": "1234=", // Optional. Default is false. If this is true, the Workflows app will render a search // field to allow a user to filter the available options by a search query, and when // a search query is entered by the user, options will be re-fetched with that search // term in the request payload under `fetchOptions.q`. "searchable": true }

Beachten Sie im obigen Code, dass eine Seitennummerierung festgelegt ist, um die Anzahl der zurückgegebenen Optionen zu begrenzen. Dies weist den Workflow an, dass weitere Optionen geladen werden können.

Darüber hinaus wird die Liste der Optionen durchsuchbar gemacht, indem searchable:true eingeschlossen wird.

Externe Daten ändern

Um externe Daten zu verwalten, können Sie zwei Hooks hinzufügen, um den Lebenszyklus eines Abrufs von Feldoptionen anzupassen:

  • PRE_FETCH_OPTIONS: Eine Funktion, die die von HubSpot gesendete Payload konfiguriert.
  • POST_FETCH_OPTIONS: Eine Funktion, die die Antwort Ihres Dienstes in ein Format umwandelt, das von HubSpot verstanden wird.

 

PRE_FETCH_OPTIONS

Wenn diese Funktion berücksichtigt wird, gilt sie für jedes Eingabefeld. Sie können es auf ein bestimmtes Eingabefeld anwenden, indem Sie eine id in der Funktionsdefinition angeben.

// { "functionType":"PRE_FETCH_OPTIONS", "functionSource":"...", id: "inputField" }

Die von HubSpot gesendete Payload ist wie folgt formatiert:

// { "origin": { // The customer's portal ID "portalId": 1, // Your custom action definition ID "actionDefinitionId": 2, // Your custom action definition version "actionDefinitionVersion": 3 }, // The input field you are fetching options for "inputFieldName": "optionsInput", // Your configured external data field webhook URL "webhookUrl": "https://myapi.com/hubspot/widget-sizes", // The values for the fields that have already been filled out by the workflow user "inputFields": { "widgetName": { "type": "OBJECT_PROPERTY", "propertyName": "widget_name" }, "widgetColor": { "type": "STATIC_VALUE", "value": "blue" }, "fetchOptions": { // The search query provided by the user. This should be used to filter the returned // options. This will only be included if the previous option fetch returned // `searchable: true` and the user has entered a search query. "q": "option label", // The pagination cursor. This will be the same pagination cursor that was returned by // the previous option fetch; it can be used to keep track of which options have already // been fetched. "after": "1234=" } } }

Die Antwort sollte dann wie folgt formatiert sein:

// { // The webhook URL for HubSpot to call "webhookUrl": "https://myapi.com/hubspot", // Optional. The request body. "body": "{\"widgetName\": \"My new widget\", \"widgetColor\": \"blue\"}", // Optional. A map of custom request headers to add. "httpHeaders": { "My-Custom-Header": "header value" }, // Optional. The Content-Type of the request. Default is application/json. "contentType": "application/json", // Optional. The Accept type of the request. Default is application/json. "accept": "application/json", // Optional. The HTTP method with which to make the request. // Valid values are GET, POST, PUT, PATCH, and DELETE. // Default is POST. "httpMethod": "POST" }

POST_FETCH_OPTIONS

Um die Antwort in ein erwartetes Format zu analysieren, verwenden Sie gemäß den externen Datenfeldern eine POST_FETCH_OPTIONS-Funktion. Die Definition einer POST_FETCH_OPTIONS-Funktion entspricht der einer PRE_FETCH_OPTIONS-Funktion.  Wenn externe Datenabrufoptionen definiert sind, wird ein Dropdown-Menü in den Eingabeoptionen für die Aktion gerendert. 

// { "functionType":"POST_FETCH_OPTIONS", "functionSource":"...", id: "inputField" }

Die Funktionseingabe ist folgendermaßen formatiert:

// { // The requested field key "fieldKey": "widgetSize", // The webhook response body from your service "responseBody": "{\"widgetSizes\": [10, 1]}" }

Die Funktionsausgabe ist folgendermaßen formatiert:

// { "options": [ { "label": "Big Widget", "description": "Big Widget", "value": "10" }, { "label": "Small Widget", "description": "Small Widget", "value": "1" } ] }

Ausgabefelder

Verwenden Sie Ausgabefelder, um Werte von Ihrer benutzerdefinierten Aktion für andere Aktionen auszugeben. Die Definition für Ausgabefelder ähnelt der Definition für Eingabefelder: 

  • name: Wie dieses Feld in anderen Teilen der benutzerdefinierten Aktion referenziert wird. Das in der Benutzeroberfläche angezeigte Label muss über den labels-Abschnitt der benutzerdefinierten Aktion definiert werden. 
  • type: Der Typ des Werts, der für die Eingabe erforderlich ist.
  • fieldType: Gibt an, wie das Eingabefeld in der Benutzeroberfläche gerendert werden soll. Eingabefelder imitieren CRM-Eigenschaften. Erfahren Sie in diesem Artikel mehr über gültige type- und fieldType-Kombinationen

Das Ausgabefeld sollte wie folgt formatiert sein: 

// { "outputFields":[ { "typeDefinition":{ "name":"myOutput", "type":"string", "fieldType":"text" } } ] }

Bei Verwendung eines Ausgabefelds werden Werte von der Antwort von der actionURL analysiert. Beispielsweise können Sie Ausgabefelder in eine vorhandene Eigenschaft in HubSpot kopieren.  

Labels

Verwenden Sie Labels, um Ihren Ausgaben oder Eingaben im Workflow-Editor Text hinzuzufügen. Es kann einige Minuten dauern, bis Labels im Sprachdienst von HubSpot angezeigt werden. Portale, die auf verschiedene Regionen oder Sprachen festgelegt sind, zeigen die Bezeichnung in der entsprechenden Sprache an, falls verfügbar. 

  • labels: Text, der beschreibt, was die Felder der Aktion darstellen und was die Aktion macht. Englische Label sind erforderlich, aber Label können in jeder der folgenden unterstützten Sprachen angegeben werden: Französisch (fr), Deutsch (de), Japanisch (ja), Spanisch (es), Portugiesisch (Brasilien) (pt-br) und Niederländisch (nl).
  • actionName: Der im Bereich „Aktion auswählen“ im Workflow-Editor angezeigte Name der Aktion.
  • actionDescription: Eine detaillierte Beschreibung für die Aktion, die beim Konfigurieren der benutzerdefinierten Aktion angezeigt wird.
  • actionCardContent: Eine zusammengefasste Beschreibung, die auf der Karte der Aktion angezeigt wird.
  • appDisplayName: Der Name des Abschnitts im Bereich „Aktion auswählen“, in dem alle Aktionen für die App angezeigt werden. Wenn appDisplayName für mehrere Aktionen definiert ist, wird die erste gefundene Aktion verwendet.  
  • inputFieldLabels: Ein Objekt, das die Definitionen von inputFields den entsprechenden Label zuordnet, die der Benutzer beim Konfigurieren der Aktion sieht.
  • outputFieldLabels: Ein Objekt, das die Definitionen von outputFields den entsprechenden Label zuordnet, die im Workflows-Tool angezeigt werden.
  • inputFieldDescriptions: Ein Objekt, das die Definitionen von inputFields den Beschreibungen unterhalb der entsprechenden Label zuordnet.
  • executionRules: Ein Objekt, das die Definitionen von Ihren executionRules den Nachrichten zuordnet, die für die Ergebnisse der Aktionsausführung im Workflow-Verlauf angezeigt werden. In diesen Dokumenten gibt es einen separaten Abschnitt für Ausführungsregeln. 

Label-Definitionen sollten wie folgt formatiert sein:

// { "labels":{ "en":{ "actionName":"Create Widget", "actionDescription":"This action will create a new widget in our system. So cool!", "actionCardContent":"Create widget {{widgetName}}", "appDisplayName":"My App Display Name", "inputFieldLabels":{ "widgetName":"Widget Name", "widgetOwner":"Widget Owner" }, "outputFieldLabels":{ "outputOne":"First Output" }, "inputFieldDescriptions":{ "widgetName":"Enter the full widget name. I support <a href=\"https://hubspot.com\">links</a> too." }, "executionRules":{ "alreadyExists":"The widget with name {{ widgetName }} already exists" } } } }

Ausführung

Wenn eine Ausführung ausgeführt wird, wird eine https-Anfrage an die actionUrl gesendet.

  • callbackId: Eine eindeutige ID für die spezifische Ausführung. Wenn die Ausführung der benutzerdefinierten Aktion blockiert wird, verwenden Sie diese ID. 
  • object: Die Werte der in objectRequestOptions angefragten Eigenschaften.
  • InputFields: Die Werte für die Eingaben, die der Benutzer ausgefüllt hat. 

Die Payload der Ausführung ist folgendermaßen formatiert: 

// { "callbackId": "ap-102670506-56776413549-7-0", "origin": { "portalId": 102670506, "actionDefinitionId": 10646377, "actionDefinitionVersion": 1 }, "context": { "source": "WORKFLOWS", "workflowId": 192814114 }, "object": { "objectId": 904, "properties": { "email": "ajenkenbb@gnu.org" }, "objectType": "CONTACT" }, "inputFields": { "staticInput": "My Static Input", "objectInput": "995", "optionsInput": "1" } }

Die erwartete Antwort sollte wie folgt formatiert sein: 

// { "outputFields":{ "myOutput":"Some value", "hs_execution_state": "SUCCESS" } }

Für die Ausführungsantwort gilt: 

  • outputFields: Die Werte der zuvor definierten Ausgabefelder. Diese Werte können in späteren Aktionen verwendet werden. 
  • hs_execution_state: Ein optionaler spezieller Wert, der zu outputFields hinzugefügt werden kann.  Es ist nicht möglich, einen neuen Versuch anzugeben, es können nur die folgenden Werte hinzugefügt werden:
    • SUCCESS
    • FAIL_CONTINUE
    • BLOCK
    • ASYNC

SUCCESS und FAIL_CONTINUE zeigen an, dass die Aktion abgeschlossen ist und der Workflow mit der nächsten auszuführenden Aktion fortfahren sollte. Wenn kein Ausführungszustand angegeben ist, werden Statuscodes verwendet, um das Ergebnis einer Aktion zu bestimmen: 

  • 2xx-Statuscodes: Die Aktion wurde erfolgreich abgeschlossen.
  • 4xx-Statuscodes: Die Aktion ist fehlgeschlagen. Die Ausnahme sind 429-Statuscodes vom Typ „Rate beschränkt“. Diese werden als erneute Versuche behandelt, und der „Erneut versuchen nach“-Header wird befolgt.
  • 5xx-Statuscodes: Es ist ein vorübergehendes Problem mit Ihrem Dienst aufgetreten und die Aktion wird später erneut versucht. Ein exponentielles Backoff-System wird für erneute Versuche verwendet. Erneute Versuche werden bis zu drei Tage lang fortgesetzt, bevor sie fehlschlagen. 

Ausführungsfunktionen

Verwenden Sie Ausführungsfunktionen, um Daten vor dem Senden an die actionURL zu formatieren und Daten von der actionURL zu analysieren. Es gibt zwei Typen von Ausführungsfunktionen:

  • PRE_ACTION_EXECUTION
  • POST_ACTION_EXECUTION

PRE_ACTION_EXECUTION-Funktion

Verwenden Sie PRE_ACTION_EXECUTION-Funktionen zum Formatieren von Daten, bevor Sie diese an die actionURL senden.

Die Funktionsdefinition ist folgendermaßen formatiert:

// { "functionType":"PRE_ACTION_EXECUTION", "functionSource":"..." }

Die Funktionseingabe sollte wie folgt formatiert sein:

// { "webhookUrl": "https://actionurl.com/", "callbackId": "ap-102670506-56776413549-7-0", "origin": { "portalId": 102670506, "actionDefinitionId": 10646377, "actionDefinitionVersion": 1 }, "context": { "source": "WORKFLOWS", "workflowId": 192814114 }, "object": { "objectId": 904, "properties": { "email": "ajenkenbb@gnu.org" }, "objectType": "CONTACT" }, "inputFields": { "staticInput": "My Static Input", "objectInput": "995", "optionsInput": "1" } }

Die Funktionsausgabe sollte wie folgt formatiert sein:

// { // The webhook URL for HubSpot to call "webhookUrl": "https://myapi.com/hubspot", // Optional. The request body. "body": "{\"widgetName\": \"My new widget\", \"widgetColor\": \"blue\"}", // Optional. A map of custom request headers to add. "httpHeaders": { "My-Custom-Header": "header value" }, // Optional. The Content-Type of the request. Default is application/json. "contentType": "application/json", // Optional. The Accept type of the request. Default is application/json. "accept": "application/json", // Optional. The HTTP method with which to make the request. // Valid values are GET, POST, PUT, PATCH, and DELETE. // Default is POST. "httpMethod": "POST" }

POST_ACTION_EXECUTION-Funktion 

Nachdem Sie eine Antwort von der actionURL erhalten haben, verwenden Sie eine POST_ACTION_EXECUTION-Funktion, um Daten für HubSpot zu formatieren.

Die Funktionsdefinition ist folgendermaßen formatiert:

// { "functionType":"POST_ACTION_EXECUTION", "functionSource":"..." }

Die Funktionseingabe sollte wie folgt formatiert sein:

// { "responseBody": "{\r\n \"returnValue\":\"Hello World!\"\r\n}" }

The function output should be formatted as follows:

// { "outputFields":{ "myOutput":"Some value", "hs_execution_state": "SUCCESS" } }

Asynchrone Ausführung

Führen Sie benutzerdefinierte Workflow-Aktionen asynchron aus, indem Sie die Aktion blockieren und später abschließen.

Blockieren der Ausführung einer Aktion

Verwenden Sie benutzerdefinierte Aktionen, um die Ausführung von Workflows zu blockieren. Anstatt nach dem Empfang einer Antwort vom Typ completed (2xx or 4xx status code) von Ihrem Dienst die nächste Aktion im Workflow nach Ihrer benutzerdefinierten Aktion auszuführen, hört der Workflow so lange mit dem Ausführen („blockieren“) dieser Aufnahme auf, bis Sie den Workflow zum Fortfahren anweisen.

Wenn blockiert werden soll, können Sie einen Wert für das hs_default_expiration-Feld festlegen, nach dem Ihre benutzerdefinierte Aktion als abgelaufen gilt. Die Ausführung des Workflows wird dann wieder aufgenommen, und die Aktion im Anschluss an Ihre benutzerdefinierte Aktion wird ausgeführt, auch wenn die Aktion nicht abgeschlossen ist. 

Um eine benutzerdefinierte Aktion zu blockieren, muss Ihre Aktionsausführungsantwort folgendes Format haben:

// { "outputFields": { // Required. Must be BLOCK for your custom action to block execution. "hs_execution_state": "BLOCK", // Optional. If not provided, a default expiration of 1 week is used. // Must be specified in ISO 8601 Duration format. // See https://en.wikipedia.org/wiki/ISO_8601#Durations "hs_expiration_duration": "P1WT1H" } }

Ausführung einer blockierten Aktion abschließen

Um die Ausführung einer blockierten benutzerdefinierten Aktion abzuschließen, verwenden Sie den folgenden Endpunkt: /callbacks/{appId}/{callbackId}/complete.

Formatieren Sie den Anfragetext wie folgt:

// { "outputFields": { // Required. The final execution state. Valid values are SUCCESS // (to indicate that your custom action completed successfully) or // FAIL_CONTINUE (to indicate that there was a problem with your // custom action execution) "hs_execution_state": "SUCCESS" } }

Benutzerdefinierte Ausführungsnachrichten mit Regeln hinzufügen

Geben Sie Regeln für Ihre Aktion an, um festzulegen, welche Nachricht auf der Verlaufsseite des Workflows angezeigt wird, wenn die Aktion ausgeführt wird.

Die Regeln werden mit den Ausgangswerten von Ihrer Aktion abgeglichen.  Diese Ausgabewerte sollten im Antworttext der actionURL im folgenden Format angegeben werden:

// { "outputFields": { "errorCode": "ALREADY_EXISTS", "widgetName": "Test widget" } }

Die tatsächlichen Nachrichten können im labels-Abschnitt der benutzerdefinierten Aktion angegeben werden:

// { "labels": { "executionRules": { "alreadyExists": "The widget with name {{ widgetName }} already exists", "widgetWrongSize": "Wrong widget size", "widgetInvalidSize": "Invalid widget size" } } } }

Die executionRules werden in der angegebenen Reihenfolge getestet. Wenn mehrere Treffer vorhanden sind, wird dem Benutzer nur die Nachricht von der ersten Regel, die übereinstimmt, angezeigt.

Die Regel stimmt überein, wenn die Ausführungsausgabe einem bestimmten Wert in der Regel entspricht. Nehmen Sie beispielsweise diesen Satz an executionRules:

// [ { // This matches the key of a label on the action's `labels.LANGUAGE.executionRules` map "labelName": "alreadyExists", "conditions": { "errorCode": "ALREADY_EXISTS" } }, { "labelName": "widgetWrongSize", "conditions": { "errorCode": "WIDGET_SIZE", "sizeError": ["TOO_SMALL", "TOO_BIG"] } }, { "labelName": "widgetInvalidSize", "conditions": { "errorCode": "WIDGET_SIZE" } } ]

Die folgenden Treffer würden in diesem Fall auftreten:

  • {"errorCode": "ALREADY_EXISTS", "widgetName": "Test widget"}: Dies würde mit der ersten Regel übereinstimmen, da errorCode gleich ALREADY_EXISTS ist. In diesem Fall wird, auch wenn eine widgetName-Ausgabe vorliegt, diese nicht in der Regel verwendet, sodass jeder Wert zulässig ist.
  • {"errorCode": "WIDGET_SIZE", "sizeError": "TOO_SMALL"}: Dies würde mit der zweiten Regel übereinstimmen, da TOO_SMALL einer der übereinstimmenden Fehler vom Typ sizeError ist und errorCode WIDGET_SIZE ist.
  • {"errorCode": "WIDGET_SIZE", "sizeError": "NOT_A_NUMBER"}: Dies würde mit der dritten Regel übereinstimmen, da auch wenn der errorCode WIDGET_SIZE ist, der sizeError keinem der von der zweiten Regel angegebenen Werte entspricht (TOO_SMALL oder TOO_BIG).

Mit diesem Übereinstimmungsmechanismus können Sie Fallback-Fehler festlegen, damit Sie spezifische Fehler für wichtige Fehlerereignisse haben können, aber auf etwas generischere Fehlermeldungen für weniger häufige Fehler zurückgreifen können. Hier ist ein Beispiel dafür, wie die benutzerdefinierte Nachricht angezeigt wird:

Ihre benutzerdefinierte Aktion testen und veröffentlichen

Nachdem Sie Ihre neue benutzerdefinierte Aktion erstellt haben, können Sie sie testen und veröffentlichen. 

Testen von benutzerdefinierten Aktionen vor dem Veröffentlichen 

Vor der Veröffentlichung Ihrer benutzerdefinierten Aktion können Sie die Ausführung von Aktionen und das Abrufen von Optionen testen, indem Sie die URL auf webhook.site verweisen. Dadurch können Sie die Payload überprüfen und eine bestimmte Antwort zurückgeben. 

Sie können die Aktion auch in Ihrem Entwicklerportal testen, indem Sie einen Workflow im Workflow-Tool erstellen. Fügen Sie dann Ihre neue Aktion hinzu.

Wenn Sie Ihre Tests abgeschlossen haben, wird empfohlen, Ihre Testaktionen zu archivieren. Weitere Informationen zum Archivieren von Aktionen finden Sie oben im Artikel im Abschnitt zum Archivieren einer benutzerdefinierten Aktion auf der Registerkarte Endpunkte.

Veröffentlichen von benutzerdefinierten Aktionen 

Standardmäßig werden benutzerdefinierte Aktionen in einem unveröffentlichten Zustand erstellt. Unveröffentlichte benutzerdefinierte Aktionen sind nur im Entwicklerportal sichtbar, das der entsprechenden HubSpot-Anwendung zugeordnet ist. Um eine benutzerdefinierte Aktion für Kunden sichtbar zu machen, aktualisieren Sie das published-Flag in Ihrer Aktionsdefinition in true. Wenn eine Aktion unveröffentlicht ist, können Portale, die die Aktion bereits zu ihrem Workflow hinzugefügt haben, bereits hinzugefügte Aktionen weiterhin bearbeiten und ausführen. Aber sie können die Aktion nicht wieder hinzuzufügen. 

Beispiele für eine benutzerdefinierte Aktion

Die folgenden Codeausschnitte enthalten Beispiele für mehrere häufige Anwendungsfälle für benutzerdefinierte Aktionen, z. B. das Definieren eines Widgets oder das Aufrufen einer serverlosen Funktion.

Beispiel Nr. 1

Dieses Beispiel enthält die folgenden Eingabefelder, die für Kontakt- und Deal-Workflows erstellt wurden:

  • widgetName: ein statisches Eingabefeld
  • widgetColor: ein Dropdown-Feld mit Optionen
  • widgetOwner: ein Feld, das einen zuständigen HubSpot-Mitarbeiter darstellt.
  • widgetQuantity: ein Feld, das von einer Eigenschaft (die der Benutzer, der den Workflow erstellt, auswählt) im aufgenommenen Objekt abgeleitet wird.
// { "actionUrl": "https://example.com/hubspot", "inputFields": [ { "typeDefinition": { "name": "widgetName", "type": "string", "fieldType": "text" }, "supportedValueTypes": ["STATIC_VALUE"], "isRequired": true }, { "typeDefinition": { "name": "widgetColor", "type": "enumeration", "fieldType": "select", "options": [ { "value": "red", "label": "Red" }, { "value": "blue", "label": "Blue" }, { "value": "green", "label": "Green" } ] }, "supportedValueTypes": ["STATIC_VALUE"] }, { "typeDefinition": { "name": "widgetOwner", "type": "enumeration", "referencedObjectType": "OWNER" }, "supportedValueTypes": ["STATIC_VALUE"] }, { "typeDefinition": { "name": "widgetQuantity", "type": "number" }, "supportedValueTypes": ["OBJECT_PROPERTY"] } ], "labels": { "en": { "actionName": "Create Widget - Example 1", "actionDescription": "This action will create a new widget in our system. So cool!", "actionCardContent": "Create widget {{widgetName}}", "inputFieldLabels": { "widgetName": "Widget Name", "widgetColor": "Widget Color", "widgetOwner": "Widget Owner", "widgetQuantity": "Widget Quantity" }, "inputFieldDescriptions": { "widgetName": "Enter the full widget name. I support <a href=\"https://hubspot.com\">links</a> too.", "widgetColor": "This is the color that will be used to paint the widget." } } }, "objectTypes": ["CONTACT", "DEAL"] }

Beispiel Nr. 2

Die folgende benutzerdefinierte Aktion verwendet eine serverlose Funktion, um die an die konfigurierte actionUrl gesendete Payload umzuwandeln. Da das objectTypes-Feld in der Definition der benutzerdefinierten Aktion nicht angegeben ist, steht diese Aktion in allen Workflows zur Verfügung.

// { "actionUrl": "https://example.com", "inputFields": [ { "typeDefinition": { "name": "widgetName", "type": "string", "fieldType": "text" }, "supportedValueTypes": ["STATIC_VALUE"], "isRequired": true } ], "labels": { "en": { "actionName": "Create Widget - Example 2", "actionCardContent": "Create widget {{widgetName}}", "inputFieldLabels": { "widgetName": "Widget Name" } } }, "functions": [ { "functionType": "PRE_ACTION_EXECUTION", "functionSource": "exports.main = function(event, callback) { return callback(transformRequest(event)); }\nfunction transformRequest(request) { return { webhookUrl: request.webhookUrl, body: JSON.stringify(request.fields), contentType: 'application/x-www-form-urlencoded', accept: 'application/json', httpMethod: 'POST' }; }" } ] }

Beispiel Nr. 3

Die folgende benutzerdefinierte Aktion verfügt über Feldabhängigkeiten und -optionen, die von einer externen API abgerufen werden. Da die Widget-Größe von der Widget-Farbe abhängig ist, kann der Benutzer so lange keinen Wert für die Widget-Größe eingeben, bis eine Widget-Farbe ausgewählt wurde.

Die Widget-Kosten hängen ebenfalls von der Widget-Farbe ab, sie werden jedoch durch den Wert bedingt, den der Benutzer für die Widget-Farbe auswählt. Der Benutzer kann keinen Wert für die Widget-Kosten eingeben, es sei denn, Rot ist als Widget-Farbe ausgewählt.

// { "actionUrl": "https://example.com/hubspot", "inputFields": [ { "typeDefinition": { "name": "widgetName", "type": "string", "fieldType": "text" }, "supportedValueTypes": ["STATIC_VALUE"], "isRequired": true }, { "typeDefinition": { "name": "widgetColor", "type": "enumeration", "fieldType": "select", "options": [ { "value": "red", "description": "red", "label": "Red" }, { "value": "blue", "description": "blue", "label": "Blue" }, { "value": "green", "description": "green", "label": "Green" } ] }, "supportedValueTypes": ["STATIC_VALUE"], }, { "typeDefinition": { "name": "widgetSize", "type": "enumeration", "fieldType": "select", "optionsUrl": "https://api.example.com/v1/widget-sizes" }, "supportedValueTypes": ["STATIC_VALUE"] }, { "typeDefinition": { "name": "widgetCost", "type": "number", "fieldType": "number" }, "supportedValueTypes": ["OBJECT_PROPERTY"] } ], "inputFieldDependencies": [ { "dependencyType": "SINGLE_FIELD", "controllingFieldName": "widgetColor", "dependentFieldNames": ["widgetSize"] }, { "dependencyType": "CONDITIONAL_SINGLE_FIELD", "controllingFieldName": "widgetColor", "controllingFieldValue": "red", "dependentFieldNames": ["widgetCost"] } ], "labels": { "en": { "actionName": "Create Widget - Example 3", "actionCardContent": "Create widget {{widgetName}}", "inputFieldLabels": { "widgetName": "Widget Name", "widgetColor": "Widget Color", "widgetSize": "Widget Size", "widgetCost": "Widget Cost" } } }, "objectTypes": ["CONTACT", "DEAL"], "functions": [ { "functionType": "PRE_FETCH_OPTIONS", "id": "widgetSize", "functionSource": "exports.main = function(event, callback) { return callback(transformRequest(event)); }\nfunction transformRequest(request) { return { webhookUrl: request.webhookUrl + '?color=' + request.fields.widgetColor.value, body: JSON.stringify(request.fields), httpMethod: 'GET' }; }" } ] }

War dieser Artikel hilfreich?
Dieses Formular dient dazu, Feedback zu unserer Entwicklerdokumentation zu sammeln. Wenn Sie uns Ihre Meinung zu HubSpot-Produkten mitteilen möchten, teilen Sie diese bitte im Ideenforum der Community.