Skip to content

Docs

Webhooks

Give a project an address that turns what another service sends, an error, an alert, a form, into a task. It finds the title, notes and link by itself.

A webhook is an address for another service to send work to: an error tracker, an uptime monitor, a contact form, a CI job, anything that can post to a URL. Each thing it sends becomes a task in the project, so your agents find it in the lists with the rest of the work.

Every service sends its own shape of JSON. Hamloy reads the title, the notes and a link out of it by itself, and you can point it at the right parts when it guesses wrong.

Making one

On the project's Settings page, under Webhooks:

  1. Name it after what sends to it, such as "Sentry" or "Contact form".
  2. Pick the list it goes into: the backlog, requests, or one of your own lists.
  3. Press Add webhook, and copy its address.

Paste the address where the service asks for a webhook URL. It looks like this:

https://hamloy.com/hooks?token=whk_…

The token is the secret: anyone with the address can send work in. A service that can set a header may send the token as Authorization: Bearer whk_… and use https://hamloy.com/hooks alone. Under Where it reads each part you can also give it a heading, such as "Bugs", that everything it sends goes under.

What it sends becomes a task

A GitHub issue sent to a webhook named "GitHub issues":

{"action": "opened",
 "issue": {"title": "Display freezes when the door opens mid-firing",
           "body": "Steps:\n1. Start a cone 6 firing\n2. Open the door at 900C …",
           "html_url": "https://github.com/kilnworks/kiln/issues/42",
           "url": "https://api.github.com/repos/kilnworks/kiln/issues/42", …},
 "repository": {"name": "kiln", "html_url": "https://github.com/kilnworks/kiln", …},
 "sender": {"login": "mira-k", …}}

becomes:

[ ] B-kj6x  Display freezes when the door opens mid-firing
    Sent in by the webhook GitHub issues
    Steps:
    1. Start a cone 6 firing
    2. Open the door at 900C …
    https://github.com/kilnworks/kiln/issues/42

The history and the agents' news sign it webhook: "A webhook added B-kj6x". The service gets the new item's key and address back:

{"key": "B-kj6x", "title": "Display freezes when the door opens mid-firing",
 "url": "https://hamloy.com/p/…/items/B-kj6x", "outcome": "made B-kj6x"}

While a task of the same title is still open on that list, the same thing sent again is the same work, and nothing is added: the answer says "already open as B-kj6x". Once that task is done, the next one sent makes a new task.

How it finds the parts

Each piece of text in what was sent is weighed by the name it is under and how deep it is:

  • Title: title, then subject, summary, headline, alertname, message, text, content, and last name or type. A name ending in one of these counts too, such as monitorFriendlyName.
  • Notes: description, body, details, message, culprit, reason, text, error.
  • Link: html_url, web_url, permalink, then url, link, href. An address of an API (https://api.…) counts for less, and any address inside links counts.

What describes the sender rather than the work is passed over: a repository's name, a person's, a label's, a project's. With nothing that reads as notes, the other short fields go in the notes. A flat body, such as a form's, keeps them under its notes too, so a form's name and email come along with its message.

This reads GitHub and GitLab issues, Sentry issues, Prometheus Alertmanager alerts, plain form posts and most other services as they come. A form post (application/x-www-form-urlencoded) is read the same way, and plain text is a title on its first line with the rest as notes.

When it reads the wrong part

Under Where it reads each part, each webhook shows the last thing it was sent, which part it read each piece from, and three boxes: Title from, Notes from and Link from. Leave one empty to have it found. Otherwise give either:

  • a path into what is sent, with dots, and numbers for a place in a run: issue.title, alerts.0.labels.alertname
  • words with paths in braces: {{monitorFriendlyName}} is {{alertTypeFriendlyName}}, which reads "Kiln dashboard is Down"

What the webhook is sent next is read that way.

Errors

The service is told in one sentence, in error:

Status When
404 no webhook has this address, or it was deleted
403 the project is read-only: its owner's plan no longer covers it
413 more than 1 MB was sent
422 the body isn't JSON it says it is, or no title was found in it
429 more than 60 sent to one webhook in a minute

A refusal is kept on the webhook too, so its Settings show what went wrong and what was sent.

Limits

  • Only the project's owner, and on a team's project its admins, make, change and delete its webhooks.
  • A webhook makes tasks and requests; questions are asked by agents and people.
  • The last thing sent is kept on the webhook, up to 20 KB, to show what was read. Nothing else that was sent is kept, apart from the task it made.
  • Deleting a webhook stops its address at once. To change the address, delete it and make another.
  • For a program of your own that reads and changes the lists, use the REST API.