FlowLens Documentation

FlowLens is a workflow debugger for HubSpot. It helps you understand why your workflows didn't behave as expected by capturing checkpoint data and providing intelligent explanations.

How it works

  1. Deploy the FlowLens backend (API + database)
  2. Add custom code actions to your HubSpot workflow at key checkpoints
  3. These actions send execution data to the FlowLens API
  4. Install the HubSpot sidebar extension to view debugging from Deal records
  5. Click "Explain" to get a plain-English explanation with evidence and fix suggestions

Quick Start

1. Deploy FlowLens

Clone and deploy the FlowLens backend to your hosting provider.

git clone https://github.com/umara25/FlowLens.git
cd FlowLens/my-app
npm install
npm run build
npm start

2. Configure Environment

Set up your environment variables.

FLOWLENS_HMAC_SECRET=your-secure-secret
HUBSPOT_ACCESS_TOKEN=your-hubspot-private-app-token

3. Instrument Your Workflow

Add custom code actions to your HubSpot workflow (see Instrumentation section below).

4. Install HubSpot Extension

Deploy the sidebar card to HubSpot (see HubSpot Sidebar Extension section).

cd hubspot-extension
hs auth
hs project upload

5. Debug

Open a Deal in HubSpot, find the FlowLens card in the sidebar, and click "Explain" to analyze the workflow.

Installation

Prerequisites

  • Node.js 18+ installed
  • A HubSpot account with workflow access
  • A HubSpot Private App with CRM deals read scope

Local Development

# Clone the repository
git clone https://github.com/umara25/FlowLens.git
cd FlowLens/my-app

# Install dependencies
npm install

# Copy environment template
cp .env.example .env.local

# Edit .env.local with your values
# Then start the dev server
npm run dev

Production Deployment

FlowLens can be deployed to any Node.js hosting platform. We recommend Vercel for the easiest setup.

# Deploy to Vercel
npx vercel

# Or build for other platforms
npm run build
npm start

Configuration

Environment Variables

FLOWLENS_HMAC_SECRET

A secret key used to validate incoming webhook requests from your HubSpot workflow custom code. Generate a strong random string for production.

HUBSPOT_ACCESS_TOKEN

Your HubSpot Private App access token. Required for fetching deal data from the HubSpot CRM API.

FLOWLENS_WORKFLOW_ID(optional)

If you only want to track a single workflow, you can hardcode the workflow ID here.

Creating a HubSpot Private App

  1. Go to HubSpot Settings → Integrations → Private Apps
  2. Click "Create a private app"
  3. Give it a name like "FlowLens"
  4. Under Scopes, add crm.objects.deals.read
  5. Create the app and copy the access token
  6. Add the token to your .env.local file

Workflow Instrumentation

To capture workflow execution data, add Custom Code actions at three key checkpoints in your HubSpot workflow.

Checkpoint Types

STARTWorkflow Entry

Place at the very beginning of your workflow. Captures when a record enters the workflow.

BRANCHBefore/After Branches

Place before or after if/then branches. Captures which path was taken and why.

ACTIONBefore Key Actions

Place before important actions like creating tasks, sending emails, or updating records.

Custom Code Template

Add this as a Custom Code action in your HubSpot workflow. Update the checkpoint type and step name for each placement.

const axios = require('axios');
const crypto = require('crypto');

exports.main = async (event, callback) => {
  const FLOWLENS_URL = 'https://your-flowlens-url.com/api/log';
  const FLOWLENS_SECRET = 'your-hmac-secret';
  
  const body = JSON.stringify({
    portalId: event.origin.portalId.toString(),
    workflowId: event.origin.workflowId.toString(),
    objectType: 'deal',
    objectId: event.object.objectId.toString(),
    checkpoint: 'START', // Change to 'BRANCH' or 'ACTION'
    stepName: 'Workflow Started', // Describe this checkpoint
    conditions: {
      // For BRANCH checkpoints, include condition details:
      // property: 'dealstage',
      // op: 'EQ',
      // value: 'contractsent',
      // result: true,
      // actual: event.inputFields['dealstage']
    },
    payload: {
      // Any additional context you want to capture
      dealstage: event.inputFields['dealstage'],
      amount: event.inputFields['amount']
    }
  });

  const signature = crypto
    .createHmac('sha256', FLOWLENS_SECRET)
    .update(body)
    .digest('hex');

  try {
    await axios.post(FLOWLENS_URL, body, {
      headers: {
        'Content-Type': 'application/json',
        'x-flowlens-signature': signature
      }
    });
  } catch (err) {
    console.error('FlowLens logging failed:', err.message);
  }

  callback({ outputFields: {} });
};

HubSpot Sidebar Extension

The HubSpot UI Extension adds a FlowLens debugging card directly inside HubSpot Deal records, allowing you to debug workflows without leaving HubSpot.

Prerequisites

  • HubSpot CLI installed globally
  • A HubSpot developer account
  • FlowLens backend deployed and accessible

1. Install HubSpot CLI

npm install -g @hubspot/cli

2. Authenticate with HubSpot

hs auth

Follow the prompts to authenticate with your HubSpot account.

3. Clone and Configure Extension

git clone https://github.com/umara25/FlowLens.git
cd FlowLens/hubspot-extension

# Edit src/app/extensions/FlowLensCard.jsx
# Update FLOWLENS_API_URL to your deployed URL
# Update workflowId to your workflow ID

4. Deploy to HubSpot

# For development (watches for changes)
hs project dev

# For production deployment
hs project upload

Using the Extension

  1. Open any Deal record in HubSpot
  2. Find the "FlowLens" card in the sidebar
  3. Optionally enter what you expected to happen
  4. Click "Explain" to analyze the workflow execution
  5. View the likely cause, evidence, and suggested fixes

API Reference

POST/api/log

Receives checkpoint logs from HubSpot workflow custom code actions.

Headers

Content-Type: application/json
x-flowlens-signature: HMAC_SHA256(secret, body)

Request Body

{
  "portalId": "123456",
  "workflowId": "789",
  "objectType": "deal",
  "objectId": "456",
  "checkpoint": "START",
  "stepName": "Workflow Start",
  "conditions": { ... },
  "payload": { ... }
}

Response

{ "ok": true, "id": "uuid" }
GET/api/explain

Analyzes checkpoint logs and returns an explanation of why the workflow behaved unexpectedly.

Query Parameters

portalId (required)
workflowId (required)
dealId (required)
expectation (optional)

Response

{
  "ok": true,
  "summary": "Brief summary of what happened",
  "likely_cause": "The most probable reason for the issue",
  "evidence": [
    "Supporting fact 1",
    "Supporting fact 2"
  ],
  "where": {
    "checkpoint": "BRANCH",
    "stepName": "Check Deal Stage",
    "timestamp": "2024-01-15T10:30:00Z"
  },
  "fix": [
    "Suggested fix 1",
    "Suggested fix 2"
  ],
  "debug": {
    "rules_hit": ["BRANCH_CONDITION_FAILED"],
    "missing_data": []
  },
  "meta": {
    "logsAnalyzed": 5,
    "dealFetched": true
  }
}

Explanation Logic

FlowLens uses a rule-based system to analyze checkpoint logs and determine why a workflow didn't behave as expected.

Detection Rules

NO_LOGS

No checkpoint logs found. The workflow either never ran, or instrumentation is missing.

START_NO_BRANCH

Workflow started but no branch checkpoint was reached.

BRANCH_CONDITION_FAILED

A branch condition evaluated to false.

ACTION_FAILED

An action checkpoint recorded an error.

NO_ACTION_REACHED

Workflow reached branches but no action was executed.

WORKFLOW_COMPLETED

All checkpoints present and no errors detected.

Troubleshooting

Logs aren't being captured

  • Verify your FlowLens URL is accessible
  • Check that the HMAC secret matches
  • Look at HubSpot custom code action logs for errors
  • Ensure the workflow is active

401 Unauthorized errors

  • The HMAC signature doesn't match
  • Make sure you're signing the exact JSON body
  • In dev mode, validation is skipped

Deal data not showing

  • Set the HUBSPOT_ACCESS_TOKEN env var
  • Verify Private App has deals read scope
  • Check that the deal ID exists

"Unclear" explanations

  • Ensure all checkpoint types are instrumented
  • Include condition details in BRANCH checkpoints
  • Add meaningful step names

Built by Umar Ahmer