import { Callout, Steps, Tabs } from "nextra/components";
import UniversalTabs from "@/components/UniversalTabs";
import { snippets } from "@/lib/generated/snippets";
import { Snippet } from "@/components/code";

# GitHub Webhooks

GitHub can send webhooks for repository events — pushes, pull requests, issues, releases, and so on. This guide walks through connecting GitHub webhooks to Hatchet.

## Setup

<Steps>

### Create the webhook in Hatchet

In the Hatchet dashboard, go to **Webhooks** and create a new webhook with the following settings:

| Field                    | Value                                                                |
| ------------------------ | -------------------------------------------------------------------- |
| **Name**                 | `github` (or whatever you'd like)                                    |
| **Source**               | GitHub                                                               |
| **Event Key Expression** | `'github:' + headers['x-github-event'] + ':' + input.action`         |
| **Secret**               | A secret string of your choosing (you'll use the same one in GitHub) |

A quick note on the event key expression: GitHub sends the event type (like `pull_request` or `issues`) in the `x-github-event` header, and the specific action (like `opened` or `closed`) in the payload's `action` field. The expression above combines them to produce keys like `github:pull_request:opened`.

Not all GitHub events have an `action` field, though. Push events, for instance, don't. If you want to handle events that might not have an `action`, you could use a simpler expression like `'github:' + headers['x-github-event']` and handle action-level routing in your task logic instead. Or you could create two separate webhooks — one for action-based events and one for action-less events.

Once you've created the webhook, copy the URL.

### Configure the webhook in GitHub

Go to your repository (or organization) settings, find **Webhooks**, and add a new webhook. See [GitHub's webhook docs](https://docs.github.com/en/webhooks/using-webhooks/creating-webhooks) for the full walkthrough.

1. **Payload URL**: Paste the Hatchet webhook URL.
2. **Content type**: Select `application/json`.
3. **Secret**: Enter the same secret you used when creating the webhook in Hatchet.
4. **Events**: Choose "Let me select individual events" and pick the ones you care about, or select "Send me everything" if you prefer.

<Callout type="warning">
  Make sure you set the content type to `application/json`. GitHub defaults to
  `application/x-www-form-urlencoded`, which won't work with Hatchet's JSON
  payload parsing.
</Callout>

### Write a task that listens for GitHub events

Here's an example that triggers when a pull request is opened:

<UniversalTabs items={["Python", "Typescript", "Go", "Ruby"]}>
  <Tabs.Tab title="Python">
    <Snippet src={snippets.python.webhooks.worker.git_hub_webhook_task} />
  </Tabs.Tab>
  <Tabs.Tab title="Typescript">
    <Snippet src={snippets.typescript.webhooks.workflow.git_hub_webhook_task} />
  </Tabs.Tab>
  <Tabs.Tab title="Go">
    <Snippet src={snippets.go.webhooks.main.git_hub_webhook_task} />
  </Tabs.Tab>
  <Tabs.Tab title="Ruby">
    <Snippet src={snippets.ruby.webhooks.worker.git_hub_webhook_task} />
  </Tabs.Tab>
</UniversalTabs>

### Test it

After saving the webhook in GitHub, GitHub will send a `ping` event to verify the connection. You can also use the "Redeliver" button in GitHub's webhook settings to replay past events, or just open a PR to trigger a real event.

</Steps>
