Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Hog intro #10388

Merged
merged 12 commits into from
Jan 22, 2025
78 changes: 75 additions & 3 deletions contents/docs/hog/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,85 @@ availability:
enterprise: full
---

Hog is the coolest programming language in the world (we're biased).
We want you to have the power to transform and export your data in real time, without the headache of maintaining your own service to get it done.

It is being used to build our CDP product, which you can follow along with in [GitHub](https://github.com/PostHog/posthog/issues/22833).
Enter Hog: the language that drives our [realtime destinations](/docs/cdp/destinations).

We’ve written Hog destination templates for dozens of services. But you can also write destinations yourself. Here’s how it works.

> **Note:** Hog shouldn't be confused with [HogQL](/docs/hogql), our SQL-like query language used inside PostHog. If you're looking to query data in PostHog, see those docs.

## Quickstart
## Hog by example: webhook

When creating a destination, you’ll start with an input interface sheet. This enables easy changes and maintenance to your destination.

You can include additional inputs while editing the destination:

- Click **Edit source code**
- Click **Add input variable**

While editing your destination, each input's property name is noted beside its title.

Let's walk through the default [webhook template](/docs/cdp/destinations/webhook). It's a great starting point for your own destinations.

```hog

let payload := {
// This is the object we use to specify our HTTP request
'headers': inputs.headers,
'body': inputs.body,
'method': inputs.method
}

if (inputs.debug) {
// If we're running in debug mode, we'll take an extra step:
// Printing the request's URL and payload object
print('Request', inputs.url, payload)
}

// Create and fire a request with the specified URL and payload object
let res := fetch(inputs.url, payload);

// When the request returns, execution continues
// The response is stored to the above constant, `res`
// You can write code that handles the response from here

if (inputs.debug) {
// If we're in debug mode, print the status code and body for the response
print('Response', res.status, res.body);
}
```

It’s okay if your destination service is a little pickier, though. Let’s say the endpoint you’re targeting expects to receive a body with a specific structure. You could wrap the `inputs.body` JSON content in another object, then pass this along to the payload:

```hog

let wrapped_input := {
'some_necessary_property': 'its necessary value',
'content': inputs.body
}

let payload := {
'headers': inputs.headers,
'body': wrapped_input,
'method': inputs.method
}
```

You could even add a new input field to your destination, which is convenient if you think you’ll want to change the value again in the future, or reuse this destination for multiple targets.

![Input UI sheet screenshot](https://res.cloudinary.com/dmukukwp6/image/upload/custom_destination_input_f74eb7947d.png)

Imagine a destination endpoint that can update one of many tables, and therefore requires a table name to be specified. With a string input named `table`, you could write this:

```hog

let table_patch := {
'table': inputs.table,
'content': inputs.body
}
```
### Keep in mind

Hog was designed to be syntax-compatible with SQL / HogQL. This means all HogQL expressions work as Hog code.

Expand Down
Loading