From 1621a6f305a834661f05d368d3005fb0b57c23a7 Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 22 Apr 2026 16:42:27 +0000 Subject: [PATCH 1/4] Add event-based automations documentation - Create event-automations.mdx covering webhook-triggered automations - Document built-in GitHub events vs custom webhook integrations - Include GitHub event-based automation example - Add Linear custom integration walkthrough with: - Webhook registration process - Agent-assisted setup workflow - Parameters reference (signature header, event key) - Automation creation after webhook registration - Add filter expressions reference for JMESPath - Update docs.json navigation Co-authored-by: openhands --- docs.json | 1 + .../usage/automations/event-automations.mdx | 176 ++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 openhands/usage/automations/event-automations.mdx diff --git a/docs.json b/docs.json index 4337398f..f18fd5a6 100644 --- a/docs.json +++ b/docs.json @@ -417,6 +417,7 @@ "pages": [ "openhands/usage/automations/overview", "openhands/usage/automations/creating-automations", + "openhands/usage/automations/event-automations", "openhands/usage/automations/managing-automations" ] } diff --git a/openhands/usage/automations/event-automations.mdx b/openhands/usage/automations/event-automations.mdx new file mode 100644 index 00000000..bf19b960 --- /dev/null +++ b/openhands/usage/automations/event-automations.mdx @@ -0,0 +1,176 @@ +--- +title: Event-Based Automations +description: Trigger automations from GitHub events or custom webhooks instead of cron schedules. +--- + + +**Beta Feature**: Event-based automations are in beta for **OpenHands Cloud** and **OpenHands Enterprise** users. + + +Event-based automations run when something happens—a PR is opened, an issue is commented on, or a webhook fires—instead of on a schedule. This is ideal for responsive workflows like auto-reviewing PRs, triaging issues, or reacting to external service events. + +## Built-in vs Custom Integrations + +| Type | Setup | Best For | +|------|-------|----------| +| **Built-in (GitHub)** | None—just create the automation | PR reviews, issue triage, push-triggered tasks | +| **Custom Webhooks** | Register webhook first, then create automation | Linear, Stripe, Slack, and other services | + +## GitHub Events (Built-in) + +GitHub is a built-in integration. Create automations that respond to GitHub events without any webhook setup. + +### Example: Auto-Review PRs with a Specific Label + +When a PR is labeled with `openhands`, automatically review it: + +``` +Create an event-based automation called "Auto Review PRs" that triggers +when a pull request is labeled with "openhands" in any of my repos. + +It should review the PR for code quality and best practices, then post +the review as a comment. +``` + +The agent will create an automation with: +- **Trigger type**: `event` +- **Source**: `github` +- **Event**: `pull_request.labeled` +- **Filter**: Matches PRs labeled `openhands` + +### Example: Respond to @openhands Mentions + +``` +Create an automation that responds when someone mentions @openhands +in an issue comment. It should analyze the issue context and provide +a helpful response. +``` + +### Available GitHub Events + +| Event | Common Actions | Use Case | +|-------|---------------|----------| +| `pull_request` | `opened`, `labeled`, `synchronize`, `ready_for_review` | PR automation | +| `issues` | `opened`, `labeled`, `assigned` | Issue triage | +| `issue_comment` | `created` | Mention responses | +| `push` | — | Branch-based triggers | +| `release` | `published` | Release workflows | + +Use wildcards like `pull_request.*` to match all actions for an event type. + +### Filtering Events + +Filters let you narrow which events trigger your automation using [JMESPath expressions](https://jmespath.org/). + +**Common filter patterns:** + +```javascript +// Match a specific label +contains(pull_request.labels[].name, 'openhands') + +// Case-insensitive mention in comment +icontains(comment.body, '@openhands') + +// Match repos in your org +glob(repository.full_name, 'myorg/*') + +// Push to main branch only +ref == 'refs/heads/main' + +// Combine conditions +glob(repository.full_name, 'myorg/*') && contains(pull_request.labels[].name, 'bug') +``` + +--- + +## Custom Webhooks + +For services beyond GitHub—like Linear, Stripe, or Slack—register a custom webhook first, then create automations that use it. + +### Walkthrough: Linear Integration + +This example walks through setting up a Linear webhook to auto-triage new issues. + +#### Step 1: Register the Webhook with OpenHands + +Ask the agent to help you register a webhook: + +``` +I want to set up a webhook integration for Linear so I can automate +issue triage. Can you help me register it? +``` + +The agent will ask: +- **Webhook name**: A descriptive name (e.g., "Linear Issues") +- **Signing secret**: Whether you have one from Linear, or should generate one + +The registration requires these parameters: + +| Parameter | Description | Linear Value | +|-----------|-------------|--------------| +| `source` | Unique identifier for this integration | `linear` | +| `signature_header` | HTTP header containing the HMAC signature | `Linear-Signature` | +| `event_key_expr` | JMESPath expression to extract event type from payload | `type` | +| `webhook_secret` | Secret for verifying webhook signatures | From Linear or auto-generated | + + +If you don't have a signing secret yet, let the system generate one. You'll configure it in Linear during the next step. + + +The agent will create the webhook and return: +- **Webhook URL**: The endpoint to configure in Linear +- **Signing secret** (if generated): Store this securely—it's shown only once + +#### Step 2: Configure the Webhook in Linear + +1. Go to **Linear Settings → API → Webhooks** +2. Click **New webhook** +3. Paste the webhook URL from Step 1 +4. If OpenHands generated a secret, enter it in Linear's signing secret field +5. Select which events to send (e.g., Issues, Comments) +6. Save the webhook + +#### Step 3: Create the Automation + +Now create an automation that triggers on Linear events: + +``` +Create an event-based automation called "Triage Linear Issues" that triggers +when a new issue is created in Linear. + +It should analyze the issue title and description, suggest appropriate labels, +and add a comment with initial triage notes. +``` + +The agent creates an automation with: +- **Source**: `linear` (your registered webhook) +- **Event**: `Issue` (Linear's event type) +- **Filter**: `action == 'create'` + +### Custom Webhook Parameters + +When registering any custom webhook, these parameters define how OpenHands processes incoming events: + +| Parameter | Required | Description | +|-----------|----------|-------------| +| `name` | Yes | Human-readable name | +| `source` | Yes | Unique identifier (lowercase, alphanumeric with hyphens) | +| `event_key_expr` | No | JMESPath to extract event type (default: `type`) | +| `signature_header` | No | Header containing HMAC signature (default: `X-Signature-256`) | +| `webhook_secret` | No | Signing secret—provide yours or let the system generate one | + +### Common Services + +| Service | Signature Header | Event Key | +|---------|-----------------|-----------| +| Linear | `Linear-Signature` | `type` | +| Stripe | `Stripe-Signature` | `type` | +| Slack | `X-Slack-Signature` | `type` | +| Twilio | `X-Twilio-Signature` | `type` | + +--- + +## Next Steps + +- [Automations Overview](/openhands/usage/automations/overview) — Cron-based automations and general examples +- [Managing Automations](/openhands/usage/automations/managing-automations) — Update, disable, or delete automations From 73e7fd9a237da0c827795a8ed961b4de7ebeb996 Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 22 Apr 2026 16:47:10 +0000 Subject: [PATCH 2/4] Clarify webhook secret handling and agent behavior - Linear provides the signing secret (not configurable) - Agent provides curl commands but user executes them (security) - After webhook registration, agent handles automation creation end-to-end - Add tip about auto-generated secrets for other services Co-authored-by: openhands --- .../usage/automations/event-automations.mdx | 71 +++++++++++-------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/openhands/usage/automations/event-automations.mdx b/openhands/usage/automations/event-automations.mdx index bf19b960..0afd6605 100644 --- a/openhands/usage/automations/event-automations.mdx +++ b/openhands/usage/automations/event-automations.mdx @@ -87,11 +87,26 @@ glob(repository.full_name, 'myorg/*') && contains(pull_request.labels[].name, 'b For services beyond GitHub—like Linear, Stripe, or Slack—register a custom webhook first, then create automations that use it. + +**How secrets are handled**: The agent will provide the curl command you need to register a webhook, but you execute it yourself. This keeps your signing secrets secure—the agent never asks for or handles sensitive credentials directly. + +Once the webhook is registered, the agent can create automations end-to-end on your behalf. + + ### Walkthrough: Linear Integration This example walks through setting up a Linear webhook to auto-triage new issues. -#### Step 1: Register the Webhook with OpenHands +#### Step 1: Get Your Webhook Secret from Linear + +Linear provides the webhook signing secret—you cannot configure your own. + +1. Go to **Linear Settings → API → Webhooks** +2. Click **New webhook** +3. Copy the **signing secret** that Linear displays (you'll need this in the next step) +4. Leave the webhook URL blank for now—you'll get it from OpenHands + +#### Step 2: Register the Webhook with OpenHands Ask the agent to help you register a webhook: @@ -100,39 +115,37 @@ I want to set up a webhook integration for Linear so I can automate issue triage. Can you help me register it? ``` -The agent will ask: -- **Webhook name**: A descriptive name (e.g., "Linear Issues") -- **Signing secret**: Whether you have one from Linear, or should generate one - -The registration requires these parameters: - -| Parameter | Description | Linear Value | -|-----------|-------------|--------------| -| `source` | Unique identifier for this integration | `linear` | -| `signature_header` | HTTP header containing the HMAC signature | `Linear-Signature` | -| `event_key_expr` | JMESPath expression to extract event type from payload | `type` | -| `webhook_secret` | Secret for verifying webhook signatures | From Linear or auto-generated | +The agent will walk you through the setup and provide a curl command like this: + +```bash +curl -X POST "https://app.all-hands.dev/api/automation/v1/webhooks" \ + -H "Authorization: Bearer ${OPENHANDS_API_KEY}" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Linear Issues", + "source": "linear", + "event_key_expr": "type", + "signature_header": "Linear-Signature", + "webhook_secret": "YOUR_LINEAR_SIGNING_SECRET" + }' +``` - -If you don't have a signing secret yet, let the system generate one. You'll configure it in Linear during the next step. - +**You run this command yourself**—replace `YOUR_LINEAR_SIGNING_SECRET` with the secret from Step 1. The response includes a `webhook_url` that you'll configure in Linear. -The agent will create the webhook and return: -- **Webhook URL**: The endpoint to configure in Linear -- **Signing secret** (if generated): Store this securely—it's shown only once + +If you're integrating a service that lets you configure the signing secret (unlike Linear), you can omit `webhook_secret` from the request. The automation service will generate one and return it in the response—store it securely, as it's shown only once. + -#### Step 2: Configure the Webhook in Linear +#### Step 3: Complete the Linear Webhook Configuration -1. Go to **Linear Settings → API → Webhooks** -2. Click **New webhook** -3. Paste the webhook URL from Step 1 -4. If OpenHands generated a secret, enter it in Linear's signing secret field -5. Select which events to send (e.g., Issues, Comments) -6. Save the webhook +1. Return to the Linear webhook you started in Step 1 +2. Paste the `webhook_url` from the previous step +3. Select which events to send (e.g., Issues, Comments) +4. Save the webhook -#### Step 3: Create the Automation +#### Step 4: Create the Automation -Now create an automation that triggers on Linear events: +Now the webhook is registered, the agent can create automations for you end-to-end. Just describe what you want: ``` Create an event-based automation called "Triage Linear Issues" that triggers @@ -142,7 +155,7 @@ It should analyze the issue title and description, suggest appropriate labels, and add a comment with initial triage notes. ``` -The agent creates an automation with: +The agent creates the automation with: - **Source**: `linear` (your registered webhook) - **Event**: `Issue` (Linear's event type) - **Filter**: `action == 'create'` From 958ec67a96cc3b69d5328d5f149db785f1f60d78 Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 29 Apr 2026 17:09:50 +0000 Subject: [PATCH 3/4] Address review comments on event-based automations docs - Fix header capitalization to match style guide (Built-In vs. Custom) - Add prose explanation for JMESPath filter expressions - Clarify two-phase workflow for custom webhooks (registration vs automation) - Add Accordion explaining event_key_expr with concrete Linear example - Add disclaimer about verifying signature headers with service docs - Improve Next Steps section with intro linking to Automations Overview --- .../usage/automations/event-automations.mdx | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/openhands/usage/automations/event-automations.mdx b/openhands/usage/automations/event-automations.mdx index 0afd6605..ff696114 100644 --- a/openhands/usage/automations/event-automations.mdx +++ b/openhands/usage/automations/event-automations.mdx @@ -9,14 +9,14 @@ description: Trigger automations from GitHub events or custom webhooks instead o Event-based automations run when something happens—a PR is opened, an issue is commented on, or a webhook fires—instead of on a schedule. This is ideal for responsive workflows like auto-reviewing PRs, triaging issues, or reacting to external service events. -## Built-in vs Custom Integrations +## Built-In vs. Custom Integrations | Type | Setup | Best For | |------|-------|----------| | **Built-in (GitHub)** | None—just create the automation | PR reviews, issue triage, push-triggered tasks | | **Custom Webhooks** | Register webhook first, then create automation | Linear, Stripe, Slack, and other services | -## GitHub Events (Built-in) +## GitHub Events (Built-In) GitHub is a built-in integration. Create automations that respond to GitHub events without any webhook setup. @@ -60,7 +60,7 @@ Use wildcards like `pull_request.*` to match all actions for an event type. ### Filtering Events -Filters let you narrow which events trigger your automation using [JMESPath expressions](https://jmespath.org/). +Filters let you narrow which events trigger your automation. They use [JMESPath expressions](https://jmespath.org/) to match fields in the event payload—so you can trigger only on specific labels, users, branches, or other conditions. **Common filter patterns:** @@ -88,9 +88,11 @@ glob(repository.full_name, 'myorg/*') && contains(pull_request.labels[].name, 'b For services beyond GitHub—like Linear, Stripe, or Slack—register a custom webhook first, then create automations that use it. -**How secrets are handled**: The agent will provide the curl command you need to register a webhook, but you execute it yourself. This keeps your signing secrets secure—the agent never asks for or handles sensitive credentials directly. +**Two-phase workflow for custom webhooks:** -Once the webhook is registered, the agent can create automations end-to-end on your behalf. +1. **Webhook registration (one-time setup)**: You execute the curl command yourself to register the webhook. This keeps your signing secrets secure—the agent provides the command but never handles your credentials directly. + +2. **Automation creation (repeatable)**: Once the webhook is registered, the agent can create, update, and manage automations for that webhook source conversationally—no manual curl commands needed. ### Walkthrough: Linear Integration @@ -132,6 +134,17 @@ curl -X POST "https://app.all-hands.dev/api/automation/v1/webhooks" \ **You run this command yourself**—replace `YOUR_LINEAR_SIGNING_SECRET` with the secret from Step 1. The response includes a `webhook_url` that you'll configure in Linear. + +The `event_key_expr` is a JMESPath expression that extracts the event type from incoming webhook payloads. This extracted value is what you match against in the automation's `on` field. + +For example, Linear sends payloads like: +```json +{"type": "Issue", "action": "create", "data": {...}} +``` + +With `event_key_expr: "type"`, the system extracts `"Issue"` as the event type. Then in your automation, you set `on: "Issue"` to match it. + + If you're integrating a service that lets you configure the signing secret (unlike Linear), you can omit `webhook_secret` from the request. The automation service will generate one and return it in the response—store it securely, as it's shown only once. @@ -174,6 +187,8 @@ When registering any custom webhook, these parameters define how OpenHands proce ### Common Services +These are example configurations for popular services. **Always verify with each service's webhook documentation**, as signature headers and payload formats may change. + | Service | Signature Header | Event Key | |---------|-----------------|-----------| | Linear | `Linear-Signature` | `type` | @@ -185,5 +200,7 @@ When registering any custom webhook, these parameters define how OpenHands proce ## Next Steps -- [Automations Overview](/openhands/usage/automations/overview) — Cron-based automations and general examples +New to automations? Start with the [Automations Overview](/openhands/usage/automations/overview) for the bigger picture, including cron-based scheduling and general concepts. + +- [Automations Overview](/openhands/usage/automations/overview) — Cron-based automations and general concepts - [Managing Automations](/openhands/usage/automations/managing-automations) — Update, disable, or delete automations From ec87f9228c6de999befe644a31b25c4b4bb5f54a Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 29 Apr 2026 17:47:44 +0000 Subject: [PATCH 4/4] Improve webhook registration instructions with explicit setup steps - Add instruction to create OpenHands API key from settings page - Add export statements for OPENHANDS_API_KEY and LINEAR_WEBHOOK_SECRET - Update curl command to use environment variables directly - User can now run the curl command as-is after exporting values --- .../usage/automations/event-automations.mdx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/openhands/usage/automations/event-automations.mdx b/openhands/usage/automations/event-automations.mdx index ff696114..c79171db 100644 --- a/openhands/usage/automations/event-automations.mdx +++ b/openhands/usage/automations/event-automations.mdx @@ -110,14 +110,17 @@ Linear provides the webhook signing secret—you cannot configure your own. #### Step 2: Register the Webhook with OpenHands -Ask the agent to help you register a webhook: +First, set up your environment variables: -``` -I want to set up a webhook integration for Linear so I can automate -issue triage. Can you help me register it? +1. Create an OpenHands API key at [app.all-hands.dev/settings/api-keys](https://app.all-hands.dev/settings/api-keys) +2. Export the API key and the webhook secret from Step 1: + +```bash +export OPENHANDS_API_KEY="your-openhands-api-key" +export LINEAR_WEBHOOK_SECRET="your-linear-signing-secret-from-step-1" ``` -The agent will walk you through the setup and provide a curl command like this: +Then run the following command to register the webhook: ```bash curl -X POST "https://app.all-hands.dev/api/automation/v1/webhooks" \ @@ -128,11 +131,11 @@ curl -X POST "https://app.all-hands.dev/api/automation/v1/webhooks" \ "source": "linear", "event_key_expr": "type", "signature_header": "Linear-Signature", - "webhook_secret": "YOUR_LINEAR_SIGNING_SECRET" + "webhook_secret": "'"${LINEAR_WEBHOOK_SECRET}"'" }' ``` -**You run this command yourself**—replace `YOUR_LINEAR_SIGNING_SECRET` with the secret from Step 1. The response includes a `webhook_url` that you'll configure in Linear. +The response includes a `webhook_url` that you'll configure in Linear. The `event_key_expr` is a JMESPath expression that extracts the event type from incoming webhook payloads. This extracted value is what you match against in the automation's `on` field.