# Functions

> Transform, filter, and enrich events with JavaScript before they reach destinations

Source: https://docs.graph8.com/developers/functions/

Functions are JavaScript code that runs on every event in transit - between your app and destinations. Use them to filter unwanted events, transform data shapes, or enrich events with external data.

## What Functions Can Do

| Capability | Example |
|-----------|---------|
| **Filter** | Drop bot traffic, test events, internal users |
| **Transform** | Rename fields, change event structure, normalize data |
| **Enrich** | Add geolocation, company data, or third-party API lookups |
| **Route** | Send different events to different warehouse tables |

## Writing a Function

Functions are JavaScript that receives an event and returns a modified event (or `"drop"` to filter it out).

### Basic Transform

```javascript
// Rename event properties to match your warehouse schema
function transform(event, ctx) {
  if (event.type === 'track') {
    event.properties.source = event.properties.utm_source;
    delete event.properties.utm_source;
  }
  return event;
}
```

### Filter Events

```javascript
// Drop events from internal users
function transform(event, ctx) {
  const internalDomains = ['graph8.com', 'yourcompany.com'];
  const email = event.traits?.email || event.properties?.email || '';

  if (internalDomains.some(d => email.endsWith(`@${d}`))) {
    return 'drop'; // magic string — event is discarded
  }
  return event;
}
```

### Enrich with External API

```javascript
// Add company data from a third-party API
async function transform(event, ctx) {
  const email = event.traits?.email;
  if (!email) return event;

  const domain = email.split('@')[1];
  const resp = await ctx.fetch(`https://api.example.com/company/${domain}`);

  if (resp.ok) {
    const company = await resp.json();
    event.traits.company_name = company.name;
    event.traits.company_size = company.employee_count;
    event.traits.industry = company.industry;
  }

  return event;
}
```

### Strip PII

```javascript
// Remove sensitive fields before sending to warehouse
function transform(event, ctx) {
  delete event.traits?.phone;
  delete event.traits?.address;
  delete event.properties?.credit_card;

  // Hash email for analytics (keep original for CRM)
  if (event.traits?.email) {
    event.traits.email_hash = ctx.crypto.sha256(event.traits.email);
  }

  return event;
}
```

### Route to Custom Tables

```javascript
// Send different events to different warehouse tables
function transform(event, ctx) {
  if (event.event === 'purchase') {
    event.JITSU_TABLE_NAME = 'purchases';
  } else if (event.event === 'page') {
    event.JITSU_TABLE_NAME = 'pageviews';
  }
  return event;
}
```

## Available APIs

Functions run in a sandboxed environment with these APIs:

| API | Usage | Description |
|-----|-------|-------------|
| `ctx.fetch(url, options)` | HTTP requests | Call external APIs (enrichment, validation, webhooks) |
| `ctx.store` | Persistent storage | Key-value store that persists between function calls |
| `ctx.log` | Logging | Write to Live Events log for debugging |
| `ctx.geo` | Geolocation | IP-based location data (city, country, region) |
| `ctx.ua` | User agent | Parsed browser and device information |
| `ctx.headers` | HTTP headers | Original request headers |
| `ctx.getWarehouse` | Warehouse queries | Query your data warehouse from within a function |
| `ctx.source` | Source metadata | Information about the originating stream |
| `ctx.destination` | Destination metadata | Target destination details |

## Managing Functions

1. Go to **Connections > Functions** in your graph8 dashboard
2. Click **+ Create Function**
3. Write your JavaScript in the code editor
4. Test with sample events using the built-in debugger
5. Attach to a stream-destination link

Functions include a built-in editor with syntax highlighting and a debugger that lets you test with sample event payloads.

## Return Values

| Return | What Happens |
|--------|-------------|
| `event` (modified) | Modified event is sent to destination |
| New object | Replaces the original event entirely |
| `"drop"` | Event is discarded (not sent to any destination) |
| Array of objects | One event becomes multiple events |
| Nothing | Original event is sent unchanged |

> **Tip: Pipeline Order**
> Functions run after the [SDK](https://docs.graph8.com/developers/sdk/) sends events and before [Destinations](https://docs.graph8.com/developers/destinations/) receive them. Use [Live Events](https://docs.graph8.com/developers/live-events/) to see function execution results in real-time.
