How Process Hooks Work

Learn how externally hosted Process Hooks interact with the Directscale system with example REST API calls

With a basic understanding About Process Hooks let's see exactly how they work. When a Process Hook event occurs an HTTP POST payload will be sent to an external system URL configured for the Hook. This POST call gives an external system the ability to add logic before/after calling to the Extension Hook Callback API to execute the default Directscale system logic. Hooks that are implemented in this way are commonly referred to as Before Hooks & After Hooks. An external system may alternatively override Directscale logic by implementing logic that suits the needs of the client and does not make a call to the Directscale Hook Callback API. This type of hook implementation is referred to as Override Hook.

👍

Best Practice for Functionality and Performance

Process Hook implementations should only make changes to Directscale logic and not additions. This is for two reasons. The first is that Hooks are executed in-process (Synchronously) and any logic implemented in a Process Hook adds overhead to the Directscale process that called it. The second reason is that any logic that is not critical to execute in-process can break processes if it fails and is not properly handled.

If a client wishes to add custom logic after a certain system event occurs it is recommended that they use Events & Webhooks The DirectScale Event and WebHooks System makes out-of-process (Asynchronoabout-events)_us) calls to external API’s that can implement the desired custom logic without adding latency to Directscale processes.

See the Hook Sequence Diagram below for a visual representation of the interaction between Directscale and an External System for the CreateAutoship Process Hook.

Hook Sequence Diagram

1640

This Sequence Diagram shows the logical order of interactions between Directscale and an external system during the CreateAutoship System Event.

Example of an HTTP POST payload to an External System

📘

The HTTP POST payload to an External System will include

  • URL
    • the URL of the External Server that will receive the Process Hook and implement custom logic
  • Headers
    • ContentType | application/json
    • X-DirectScale-User | username (This will not be sent if there is no user context) ex: from an API Call
    • X-DirectScale-RequestName | the hook id (ex: Autoships.CreateAutoship)
    • X-DirectScale-CallbackToken | one-time use token for authorizing with the Hook Callback API. Learn more About the Callback Token
    • Authorization | bearer token used by the external system to authorize the call. See Securing Client Web Applications for more details
  • Body
    • Relevant data to the hook's context in a JSON format

Below is an example of an HTTP POST call to an external system for the Autoship.CreateAutoship Process Hook Event

curl --location --request POST 'https://acme.clientextension.directscale.com/api/recievingendpoint' \
--header 'X-DirectScale-User: jsmith' \
--header 'X-DirectScale-RequestName: Autoships.CreateAutoship' \
--header 'X-DirectScale-CallbackToken: 011420320705c882aa382c46115587ec70238c11b82c16ee504a7ef5a71796d57787e12cc25a' \
--header 'Authorization: Bearer mcwod!j9xn2fylqo%2692kd09$jdi1l' \
--header 'Content-Type: application/json' \
--data-raw '{
    "AutoshipInfo": {
        "AutoshipId": 0,
        "AssociateId": 2,
        "ShipAddress": {
            "Id": 0,
            "AddressLine1": "350 S. 400 W.",
            "AddressLine2": null,
            "AddressLine3": null,
            "City": "Lindon",
            "State": "UT",
            "PostalCode": "84042",
            "CountryCode": "us"
        },
        "StartDate": "2022-03-04T00:00:00",
        "Frequency": 2,
        "LastProcessDate": "0001-01-01T00:00:00",
        "NextProcessDate": "0001-01-01T00:00:00",
        "LastChargeAmount": 0,
        "Status": null,
        "ShipMethodId": 1,
        "PaymentMethodId": "_TESTCARD_f16134da-b965-e819-78fd-227865f388aa",
        "PaymentMerchantId": 99,
        "Custom": {
            "Field1": null,
            "Field2": null,
            "Field3": null,
            "Field4": null,
            "Field5": null
        },
        "AutoshipType": 0,
        "LineItems": [
            {
                "ItemId": 1,
                "Quantity": 1,
                "Cost": 0,
                "Disabled": false,
                "ProductName": null,
                "Description": null,
                "Specifications": null,
                "LanguageCode": null,
                "SKU": null,
                "Category": null,
                "ChargeShipping": false,
                "Height": 0,
                "Image": null,
                "Length": 0,
                "LengthUOM": null,
                "MPN": null,
                "PackCount": 0,
                "PackageGroupId": 0,
                "TaxClassId": 0,
                "UnitOfMeasure": null,
                "UPC": null,
                "Weight": 0,
                "WeightUOM": null,
                "Width": 0,
                "FlagBirthDefects": false,
                "HasKitGroups": false,
                "FlagCancer": false,
                "PriceGroup": 0,
                "Custom": null,
                "Images": null,
                "Prices": [
                    {
                        "GroupId": 0,
                        "Price": 10,
                        "PriceCurrency": null,
                        "OriginalPrice": 0,
                        "Bonus": 0,
                        "CV": 0,
                        "QV": 0,
                        "RewardPoints": 0
                    }
                ],
                "Options": null,
                "ItemOptions": null,
                "Languages": null,
                "OptionsMap": null,
                "CouponsBeingUsed": 0,
                "OutOfStockStatus": 0
            }
        ],
        "FrequencyString": null,
        "CurrencyCode": null
    }
}'

Example of an HTTP POST payload to the Directscale Hook Callback API

📘

The HTTP POST call to the Directscale Hook Callback API should include

  • URL
  • Headers
    • ContentType | application/json
    • X-DirectScale-CallbackToken | one-time use token passed to the external system for authorizing with the Hook Callback API. Learn more About the Callback Token
    • Authorization | bearer token used by the Directscale system to authorize the call. See Securing Client Web Applications for more details
  • Body
    • JSON data that was passed to the external system

Here is an example of an HTTP POST call to the Directscale Hook Callback API for the Autoship.CreateAutoship Hook. This example is a continuation of the example displayed above. You can see that the Field1 property of the Custom object was changed by the external system BEFORE the call to the Hook Callback API executes the default Directscale Logic.

curl --location --request POST 'https://acme.corpadmin.directscale.com/api/extension/hooks/Autoship.CreateAutoship' \
--header 'X-DirectScale-CallbackToken: 3830XW910d3%23ji1A0pem9v' \
--header 'Authorization: Bearer lsinm1@jai$fj0sj!alkvnmiowkwoazzoi' \
--header 'Content-Type: application/json' \
--data-raw '{
    "AutoshipInfo": {
        "AutoshipId": 0,
        "AssociateId": 2,
        "ShipAddress": {
            "Id": 0,
            "AddressLine1": "350 S. 400 W.",
            "AddressLine2": null,
            "AddressLine3": null,
            "City": "Lindon",
            "State": "UT",
            "PostalCode": "84042",
            "CountryCode": "us"
        },
        "StartDate": "2022-03-04T00:00:00",
        "Frequency": 2,
        "LastProcessDate": "0001-01-01T00:00:00",
        "NextProcessDate": "0001-01-01T00:00:00",
        "LastChargeAmount": 0,
        "Status": null,
        "ShipMethodId": 1,
        "PaymentMethodId": "_TESTCARD_f16134da-b965-e819-78fd-227865f388aa",
        "PaymentMerchantId": 99,
        "Custom": {
            "Field1": "This message was added from the CreateAutoshipHook",
            "Field2": null,
            "Field3": null,
            "Field4": null,
            "Field5": null
        },
        "AutoshipType": 0,
        "LineItems": [
            {
                "ItemId": 1,
                "Quantity": 1,
                "Cost": 0,
                "Disabled": false,
                "ProductName": null,
                "Description": null,
                "Specifications": null,
                "LanguageCode": null,
                "SKU": null,
                "Category": null,
                "ChargeShipping": false,
                "Height": 0,
                "Image": null,
                "Length": 0,
                "LengthUOM": null,
                "MPN": null,
                "PackCount": 0,
                "PackageGroupId": 0,
                "TaxClassId": 0,
                "UnitOfMeasure": null,
                "UPC": null,
                "Weight": 0,
                "WeightUOM": null,
                "Width": 0,
                "FlagBirthDefects": false,
                "HasKitGroups": false,
                "FlagCancer": false,
                "PriceGroup": 0,
                "Custom": null,
                "Images": null,
                "Prices": [
                    {
                        "GroupId": 0,
                        "Price": 10,
                        "PriceCurrency": null,
                        "OriginalPrice": 0,
                        "Bonus": 0,
                        "CV": 0,
                        "QV": 0,
                        "RewardPoints": 0
                    }
                ],
                "Options": null,
                "ItemOptions": null,
                "Languages": null,
                "OptionsMap": null,
                "CouponsBeingUsed": 0,
                "OutOfStockStatus": 0
            }
        ],
        "FrequencyString": null,
        "CurrencyCode": null
    }
}'