Cloud Hooks

What’s on this page?

As highlighted in the Extensibility Overview, this page provides an update on some out-of-the-box extensibility hooks (which are feature extensions from the Cloud Platform) that are available to be integrated by a partner. Tulip can provide assistance in enabling an environment where the extensibility code can be hosted and run.

Available Hooks

The following hooks are available as of November 2019:

EventBefore HookAfter HookInstead Hook
Customer Createyesyesyes
Customer Updateyesyesyes
Customer Note Createyesyesyes
Customer Note Deleteyesyesyes
Send Emailyesyesyes
Send SMSyesyesyes
Customer Association Createyesyesyes
Customer Association Updateyesyesyes
Customer Association Deleteyesyesyes
Address Prediction Getyesyesyes
Address External ID Getyesyesyes
Product Inventory Getyesyesyes
External Cart Getyesyesyes
External Cart Createyesyesyes
External Cart Item Createyesyesyes
External Cart Item Updateyesyesyes
External Cart Item Deleteyesyesyes
External Order Createyesyesyes
Calculate Taxnonoyes

Model for Extensibility

Tulip provides the ability to override several core functions that it performs. The model for extensibility is based:

  1. Before Hooks
  2. After Hooks
  3. Instead Hooks

When extensibility is added to a function, a developer can ask that Tulip runs, in JavaScript or TypeScript, provided code in the cloud (called a “hook”).

SDK

Once a hook is run, the hook is provided, as an object, context information needed to understand the current data and context that can be modified or interpreted.

The JavaScript or TypeScript code has full access to the Tulip Direct API and Bulk API and Config API. This is the core way in which to fetch and modify data when inside a hook.

They are presented as:

  • sdk.epiClient
  • sdk.dalClient
  • sdk.configApiClient

To help ensure that the hooks are isolated, portable, and secure, they are run inside the context of a sandbox. This sandbox overwrites the global namespace so that hooks are only able to do things that have been explicitly allowed. This also means that hooks can’t “require” external libraries or other files on the container’s file system.

The hooks do have access to an SDK which provides tools for connecting to external and internal services.

Write a Hook

Structure of a Hook

The basic structure of a hook looks like this:

 module.exports = async function(some_input_value) { // ... your logic here return some_output_value; }

Additional functions can be added at the writer of the hook’s discretion, but only one (the main function) should be exported.

Hook Sandbox

To help ensure that the hooks are isolated, portable, and secure, they are run inside the context of a sandbox. This sandbox overwrites the global namespace so that hooks are only able to do things that have been explicitly allowed. This also means that hooks can’t “require” external libraries or other files on the container’s file system. The hooks do have access to an SDK which provides tools for connecting to external and internal services.

SDK

The SDK is available inside the hooks as the global variable sdk. The SDK is written in TypeScript, and its source code can be provided to the partner team (through access to Tulip’s git repository).

SDK Key Value Store Manager

The key value store manager allows hooks to store and key-value pairs. This allows hooks to persist simple data across multiple calls. Behind the scenes, this uses redis and prefixes the keys with hooks-{CLUSTER_ID}.. Unlike data stored in Config API, these values aren’t accessible to the outside world/the app.

sdk.keyValueStoreManager.get(key: string): Promise<string>
sdk.keyValueStoreManager.set(key: string, value: string): Promise<string>

SDK Secret Manager

The secret manager allows hooks to access secrets which are securely encrypted and decrypted in the Tulip Cloud Secret Manager.

sdk.secretManager.get(key: string): Promise<string>

Additionally, hooks can encrypt and decrypt strings. This can be used in conjunction with the keyValueStoreManager to encrypt and decrypt dynamic secrets.

sdk.secretManager.encrypt(value: string): Promise<string>
sdk.secretManager.decrypt(encryptedValue: string): Promise<string>

SDK HTTP Clients

The HTTP clients available in the SDK provide a simple interface on top of the axios http client library.

.get(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<any>>
.delete(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<any>>
.post(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<any>>
.put(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<any>>
.patch(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<any>>

The SDK provides several of these http clients which have been configured according to their purpose.

ModulePurposeExample
sdk.httpClientAccessing External Servicesawait sdk.httpClient.get("https://example.com/something")
sdk.dalClientAccessing DALawait sdk.dalClient.get("/dataAccess/v1/crm/customers/1")
sdk.epiClientAccess EPIawait sdk.epiClient.get("/v2/crm/customers/1")
sdk.configApiClientAccess Config APIawait sdk.configApiClient.get("/config/v2/domains/d1/resources/r1/settings/s1")

Detailed Hook Documentation

Hook documentation is available for each hook that includes the custom payload it provides.