Skip to content

Build an Integration

Building an integration involves two key components: an Integration Manifest and a Handler Endpoint.

1. Create your integration manifest

The IntegrationManifest is a JSON file that tells Pixelstack everything it needs to know about your integration. You will provide this manifest when adding your integration in your Pixelstack settings.

{
"name": "My Awesome Integration",
"description": "A brief description of what this integration does.",
"iconUrl": "https://example.com/icon.png",
"handlerUrl": "https://api.example.com/pixelstack-handler",
"supportedEvents": ["loadImages", "nodeCalled"],
"settings": [
{
"id": "apiKey",
"name": "API Key",
"description": "Your API Key for My Awesome Service.",
"type": "string",
"isSecret": true
}
],
"imageLoader": {
"formInputs": [
{
"id": "query",
"name": "Search term",
"type": "string",
"required": true
}
],
"formSubmitLabel": "Search"
},
"nodeTypes": [
{
"id": "my-node",
"name": "My Custom Node",
"description": "This node does something awesome.",
"inputs": [{ "id": "input-data", "name": "Input Data", "type": "string" }],
"outputs": [{ "id": "output-data", "name": "Output Data", "type": "string" }]
}
]
}

Key Manifest Fields:

  • name (string): The display name of your integration.
  • handlerUrl (string): The URL of your handler endpoint. Pixelstack will send POST requests here.
  • supportedEvents (IntegrationEvent[]): Events your integration wants to listen to (loadImages and/or nodeCalled).
  • settings (IntegrationSetting[]): Configuration settings users will provide, like API keys.
  • imageLoader (IntegrationImageLoader): Defines the UI for your image loader.
  • nodeTypes (IntegrationNodeType[]): An array of custom workflow nodes your integration provides.

2. Build a handler endpoint

Your handler is a web service that receives POST requests from Pixelstack. The request body is a JSON payload containing event details. Your service needs to handle different event types and return the expected response.

To get type definitions for the integration events, you’ll need to install the @pixelstack/integration package:

Terminal window
npm install @pixelstack/integration

Here’s a basic handler using Hono, a popular web framework that can run on any JavaScript runtime:

import { Hono } from 'hono';
import type { IntegrationEventData } from '@pixelstack/integration';
const app = new Hono();
app.post('/', async (c) => {
const body = await c.req.json<IntegrationEventData>();
if (body.eventType === 'loadImages') {
// Handle image loading. See below for details.
}
if (body.eventType === 'nodeCalled') {
// Handle a workflow node invocation. See below for details.
}
return c.json({ success: true });
});
export default app;

Building an image loader

To create an image loader:

  1. In your manifest, include "loadImages" in supportedEvents.
  2. Define the imageLoader object with the formInputs your integration needs.
  3. Implement the logic for the loadImages event in your handler.

When a user uses your image loader, your handler will receive a request with eventType: 'loadImages'.

Example loadImages request body:

{
"teamId": "team_123",
"eventType": "loadImages",
"settingValues": [{ "id": "apiKey", "value": "secret-user-api-key" }],
"eventData": {
"query": "landscapes"
}
}

Your handler should process this request, fetch images, and return an array of images.

Example loadImages response body:

{
"images": [
{
"imageUrl": "https://images.example.com/1.jpg",
"thumbnailUrl": "https://images.example.com/1-thumb.jpg",
"title": "A Beautiful Landscape",
"subtitle": "By Jane Doe"
}
]
}

This response should conform to the IntegrationImageLoaderResponse type.

Building workflow nodes

To add custom workflow nodes:

  1. In your manifest, include "nodeCalled" in supportedEvents.
  2. Define your custom nodes in the nodeTypes array.
  3. Implement the logic for the nodeCalled event in your handler.

When a workflow containing your node is run, your handler will receive an event with eventType: 'nodeCalled'.

Example nodeCalled request body:

{
"teamId": "team_123",
"eventType": "nodeCalled",
"settingValues": [{ "id": "apiKey", "value": "secret-user-api-key" }],
"eventData": {
"nodeTypeId": "my-node",
"inputValues": [{ "id": "input-data", "value": "Some data" }],
"controlValues": []
}
}

Your handler must perform the node’s logic and return the values for its outputs.

Example nodeCalled response body:

{
"outputs": [{ "id": "output-data", "value": "The result" }]
}

We are excited to see what you will build! If you have any questions, please reach out to contact@pixelstack.io.