Skip to main content

Webhook

Webhooks allow you to create and update checks by sending HTTP POST requests to an endpoint.

github-webhook.yaml
---
apiVersion: canaries.flanksource.com/v1
kind: Canary
metadata:
name: github-status
spec:
webhook:
name: Github
transformDeleteStrategy: Ignore
transform:
expr: |
has(results.json.component) ?
[{
"description": results.json.component.description,
"detail": results.json,
"message": results.json.page.status_description,
"duration": 1,
"icon": "github",
"name": "Github/" + results.json.component.name,
"pass": results.json.component.status == "operational",
"start": results.json.component_update.created_at,
}].toJSON():
has(results.json.incident.components) && results.json.incident.components.size() > 0 ?
results.json.incident.components.map(c, {
"description": c.description,
"detail": results.json,
"icon": "github",
"duration": 1,
"message": c.status + ": " + results.json.incident.incident_updates[0].body + " " + results.json.incident.shortlink,
"name": "Github/" + c.name,
"pass": c.status == "operational",
"start": c.updated_at,
}).toJSON():
[{
"detail": results.json,
"icon": "github",
"duration": 1,
"message": results.json.incident.status + ": " + results.json.incident.incident_updates[0].body + " " + results.json.incident.shortlink,
"name": "Github/" + results.json.incident.name,
"pass": has(results.json.incident.resolved_at) && results.json.incident.resolved_at != null,
"start": results.json.incident.updated_at,
}].toJSON()

This example:

  1. Defines a webhook named Github accessible via http://<host>/webhook/Github
  2. Transforms the incoming JSON into check

This webhook can be called with:

curl -s -X POST 'http://localhost/webhook/Github' --json '{
"meta": {
"unsubscribe": "http://www.githubstatus.com/?unsubscribe=mv95chy3sdq7",
"documentation": "https://help.statuspage.io/knowledge_base/topics/webhook-notifications",
"generated_at": "2024-07-19T04:47:30.290Z"
},
"page": {
"id": "kctbh9vrtdwd",
"status_indicator": "none",
"status_description": "All Systems Operational"
},
"component": {
"status": "operational",
"name": "Copilot",
"created_at": "2021-08-11T16:02:09.505Z",
"updated_at": "2024-07-19T04:47:22.288Z",
"position": 10,
"description": "Orchestration and Compute for GitHub Copilot",
"showcase": false,
"start_date": "2021-08-11T00:00:00.000Z",
"id": "h2ftsgbw7kmk",
"page_id": "kctbh9vrtdwd",
"group_id": null
},
"component_update": {
"old_status": "partial_outage",
"new_status": "operational",
"created_at": "2024-07-19T04:47:22.293Z",
"component_type": "Component",
"state": "sn_created",
"id": "zm5p6v0wb9ts",
"component_id": "h2ftsgbw7kmk"
}
}'

Input

The request is available to the transformation function with these fields:

FieldDescriptionScheme
results.content

Request body text, See YAML, CSV

string

results.headers

map[string]string

results.json

If Content-Type: application/json unmarshalls the request body to a JSON

JSON Object|Array

Output

The return value is a list of checks

Transform Result

FieldDescriptionScheme
name*

Name of the check to use, the name is used to lookup existing checks to update

string

pass*

Set to true if the health check is passing

boolean

duration

Time in ms for duration of the check

int64

invalid

Set to true if the check is not configured correctly, and can never pass

boolean

deletedAt

The time the check or event logically ended

time.Time

error

An error message to be shown, if non-empty sets pass: false automatically

string

icon

Icon

labels

map[string]string

message

Informational message to be shown to users

string

namespace

string

start

The time the check or event logically started (e.g if coming from an external source)

time.Time

data

map[string]interface{}

description

string

detail

interface{}

displayType

string

endpoint

string

metrics

Add custom metrics to be exported

[]Metric

transformDeleteStrategy

How to handle checks that were returned in a previous transformation, but not in the current

MarkHealthy | MarkUnhealthy | Ignore
type

string