Functions
Describes Optimizely Connect Platform (OCP) functions, which are stored in the src unctions
directory for your app.
Functions are small, executable blocks of code typically triggered off of a real-time event. An app can have any number of functions stored in the src/functions
directory. Common examples of functions include:
- Subscription to a list
- Order purchase/refund/cancellation
- Marketing consent update survey submission
- Product review/rating
Typically, functions are triggered by an HTTP request (a webhook), although you can also use functions to populate app settings form fields. This document covers functions for handling webhooks. For more information about how to use functions as a data source in app settings forms, see Remote select options.
Define functions
Define functions in your application's app.yaml
file, for example:
functions:
event_handler: #<-- name used for form sources and reference within the app
entry_point: Event #<-- File and Class name from src/functions folder
description: Processes incoming events
Below are the requirements for any functions you define in your app.yaml
file:
- Add the function's code in the
src/functions
directory. For more information, seesrc/functions
. - The file and class name must match the
entry_point
defined in theapp.yaml
file. - The class must extend the
Function
class from the@zaiusinc/app-sdk
package and implement theperform
method.
Example function:
import * as App from '@zaiusinc/app-sdk';
export class Event extends App.Function {
public async perform(): Promise<App.Response> {
// processing logic here
return new App.Response(200);
}
}
Webhook URLs for functions
Functions that you define in the app.yaml
file are provided a public URL in the following format: https://[REGIONAL_DOMAIN]/[APP_ID]/[FUNCTION]/[UUIDv4]
For development and testing purposes, you can get the exact URL of an app's functions using the ocp directory list-functions
command. For example:
$ ocp directory list-functions ocp_shakedown vdl
https://function.zaius.app/ocp_shakedown/shakedown/e8533888-b63e-4270-9c52-************
In the app code, you can get the URL using the App-SDK getEndpoints
method. For example:
import { functions } from '@zaiusinc/app-sdk';
let webhookURL = (await functions.getEndpoints())['event_handler']
You should then register the URL with the source of the event. The process for registering the URL depends on the third-party service that sends events.
Important
You must define any publicly available functions (for example, webhooks) in the
app.yml
file.
Functions have access to the HTTP request path, query parameters, headers, and body. For example, the base URL for a function may look like the following: https://function.staging.zaius.app/my_app/cart/5f57ecbb-ef28-4a25-9056-3ea98994e2a5/
You can support additional paths and query parameters added to your URL. For example: https://function.staging.zaius.app/my_app/cart/5f57ecbb-ef28-4a25-9056-3ea98994e2a5/update?cart-id=12345
The path and query parameters are accessible to your function as well as the body and headers of the HTTP request. For example:
import * as OCP from '@zaiusinc/app-sdk';
export class Event extends OCP.Function {
public async perform(): Promise<App.Response> {
const path = this.request.path; // "/update"
const cartId = this.request.params['cart-id']; // "12345"
const body = this.request.bodyJSON || {}; // '{"request_id":"12345","products":[...], ...}'
const headers = this.request.headers; // { "Content-Type": "application/json", ... }
// processing logic here
return new App.Response(200);
}
}
Function example
import * as App from '@zaiusinc/app-sdk';
import {logger} from '@zaiusinc/app-sdk';
import {z} from '@zaiusinc/node-sdk';
import {IncomingEvent} from '../data/IncomingEvents';
import {transformToCustomer} from '../lib/transformToCustomer';
/**
* Example event handler.
* Expects a request in the form:
* url: https://[webhook-url]/?email=<email>
* with a JSON body.
* Fires an ODP event and updates the customer's name in ODP
*/
export class HandleEvent extends App.Function {
/**
* Handle a request to the handle_event function URL
* this.request contains the request information
* @returns App.Response as the HTTP response
*/
public async perform(): Promise<App.Response> {
const email = this.request.params['email'] as string;
if (!email) {
return new App.Response(400, 'Missing required email parameter');
} else {
try {
const event = this.request.bodyJSON as IncomingEvent;
// TODO: transform your event data into ODP API calls
if (event.customer) {
await z.customer(transformToCustomer(event.customer));
}
await z.event({
type: event.type,
identifiers: {
email
},
data: {
action: event.action
}
});
// return the appropriate status/response
return new App.Response(200);
} catch (e) {
logger.error(e);
return new App.Response(500, `An unexpected error occurred: ${e}`);
}
}
}
}
Updated 18 days ago