Skip to content

Transforms

Transforms modify webhook payloads using JavaScript before delivery.

Overview

Transforms modify webhook payloads before delivery using one of four supported languages. Use them to:

  • Reshape data to match your application's format
  • Extract specific fields
  • Add computed values
  • Convert between data formats (JSON, XML, text)
  • Mask sensitive data

Transform Types

Hookbase supports four transform engines:

TypeLanguageBest For
jsonataJSONataDeclarative JSON-to-JSON mapping (default)
javascriptJavaScriptComplex logic, conditionals, string manipulation
liquidLiquidTemplate-based output, generating text/HTML
xsltXSLTXML-to-XML or XML-to-JSON transformations

Creating a Transform

Fields

FieldDescription
nameHuman-readable name
codeTransform code
typeTransform type: jsonata (default), javascript, liquid, xslt
inputFormatExpected input format: json (default), xml, text
outputFormatOutput format: json (default), xml, text

JSONata (Default)

JSONata is a lightweight query and transformation language for JSON. It's the recommended approach for straightforward mappings.

jsonata
{
  "eventType": action,
  "repository": repository.full_name,
  "sender": sender.login,
  "timestamp": $now()
}

See the JSONata documentation for the full expression reference.

JavaScript

JavaScript transforms receive the payload as an argument and return the transformed result.

javascript
function transform(payload) {
  return {
    // Your transformed data
  };
}

Liquid

Liquid templates are useful for generating formatted text or HTML output.

liquid
New event from {{ payload.repository.full_name }}
Action: {{ payload.action }}
By: {{ payload.sender.login }}

XSLT

XSLT transforms are designed for XML payloads. Set inputFormat: "xml" when using XSLT.

xml
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <event>
      <type><xsl:value-of select="/webhook/action"/></type>
      <source><xsl:value-of select="/webhook/repository/name"/></source>
    </event>
  </xsl:template>
</xsl:stylesheet>

Code Validation

When creating or updating a transform, Hookbase validates the code:

  • JSONata: Parses the expression and reports syntax errors
  • JavaScript: Checks for syntax errors and unsafe operations (no eval, Function, require)
  • Liquid: Validates template syntax
  • XSLT: Validates XML and stylesheet structure

Examples

Extract Specific Fields

javascript
function transform(payload) {
  return {
    eventType: payload.action,
    repository: payload.repository?.full_name,
    sender: payload.sender?.login,
    timestamp: new Date().toISOString()
  };
}

Format for Slack

javascript
function transform(payload) {
  return {
    text: `New event from ${payload.repository?.full_name}`,
    blocks: [
      {
        type: "section",
        text: {
          type: "mrkdwn",
          text: `*${payload.action}* by ${payload.sender?.login}`
        }
      }
    ]
  };
}

Add Metadata

javascript
function transform(payload) {
  return {
    ...payload,
    _meta: {
      processedAt: new Date().toISOString(),
      source: "hookbase",
      version: "1.0"
    }
  };
}

Filter and Reshape Array

javascript
function transform(payload) {
  const items = payload.items || [];

  return {
    count: items.length,
    items: items
      .filter(item => item.status === "active")
      .map(item => ({
        id: item.id,
        name: item.name
      }))
  };
}

Mask Sensitive Data

javascript
function transform(payload) {
  return {
    ...payload,
    email: payload.email?.replace(/(.{2}).*(@.*)/, "$1***$2"),
    creditCard: payload.creditCard ? "****" + payload.creditCard.slice(-4) : null
  };
}

Testing Transforms

Use the Testing page to verify your transform works correctly:

  1. Navigate to Testing in the sidebar
  2. Select your source and route
  3. Enter a sample payload
  4. Click Send Test
  5. View the transformed output

Or use the Transforms page directly:

  1. Navigate to Transforms in the sidebar
  2. Click on a transform to edit
  3. Enter a sample payload in the test section
  4. Click Test Transform
  5. View the result

API Usage

Create Transform

bash
# JavaScript transform
curl -X POST https://api.hookbase.app/api/transforms \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "GitHub to Slack",
    "type": "javascript",
    "code": "function transform(payload) { return { text: payload.action }; }"
  }'

# JSONata transform (default type)
curl -X POST https://api.hookbase.app/api/transforms \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Extract Fields",
    "type": "jsonata",
    "code": "{ \"event\": action, \"repo\": repository.full_name }"
  }'

List Transforms

bash
curl https://api.hookbase.app/api/transforms \
  -H "Authorization: Bearer whr_your_api_key"

Update Transform

bash
curl -X PATCH https://api.hookbase.app/api/transforms/{transformId} \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "function transform(payload) { return { text: payload.action, repo: payload.repository.name }; }"
  }'

Delete Transform

bash
curl -X DELETE https://api.hookbase.app/api/transforms/{transformId} \
  -H "Authorization: Bearer whr_your_api_key"

Best Practices

  1. Keep it simple: Transforms run on every webhook; keep code efficient

  2. Handle missing data: Use optional chaining (?.) and default values

  3. Test thoroughly: Test with various payload shapes before deploying

  4. Don't make external calls: Transforms should be pure functions; no HTTP requests

  5. Return valid JSON: Ensure your transform returns serializable data

  6. Version your transforms: Include version info in names or metadata

Limitations

  • Execution time: Transforms must complete within 50ms
  • Memory: Limited to 128KB of memory
  • No external access: Cannot make HTTP requests or access external resources
  • No persistent state: Each execution is independent

Error Handling

If a transform fails:

  • The original payload is used (no transformation)
  • An error is logged
  • Delivery continues to destinations

To debug transform errors:

  1. Check the Event Debugger for error messages
  2. Test with the exact payload that caused the error
  3. Add defensive coding (null checks, try/catch)
javascript
function transform(payload) {
  try {
    return {
      data: payload.nested?.deeply?.value || "default"
    };
  } catch (error) {
    // Return original on error
    return payload;
  }
}

Released under the MIT License.