Examples

Label bot

A webhook receiver that labels new threads and closes them from a comment command.

label-bot is a webhook receiver that works with any configured forge. View the source. It does two things:

  • When an issue or pull request opens with a title that matches a pattern, the bot adds a label and posts a comment.
  • When a comment contains /close, the bot closes the thread if the commenter has write access to the repository.

The bot calls provider.can() before each write. On a forge that can't add labels, such as Bitbucket or Tangled, the bot posts the comment and reports the label as unsupported in its response.

Run it

FORGES_GITHUB_TOKEN=ghp_... \
FORGES_GITHUB_WEBHOOK_SECRET=... \
LABEL_BOT_PATTERN='^(feat|fix)[(:]' \
LABEL_BOT_LABEL=triage \
pnpm --filter @forges-examples/label-bot start

LABEL_BOT_COMMENT sets the text of the comment. PORT sets the port, which defaults to 3000.

Point the forge's webhook at http://<host>:3000/webhooks/<forge>, for example /webhooks/github. If you configure several instances of the same forge, add the instance host to the path: /webhooks/gitlab/gitlab.example.com.

If a delivery's signature doesn't verify, the bot responds with 401. For any other delivery, it responds with a JSON list of the actions it took.

src/handler.ts exports a (request: Request) => Promise<Response> handler, so it runs on any runtime that supports the Fetch API. src/server.ts serves the handler with node:http.

Collaborator checks

Before the bot closes a thread, it calls repos.permissionFor() to read the commenter's role. On a forge with no collaborator API, the bot reports unsupported and leaves the thread open.

What it shows

Run the tests

pnpm --filter @forges-examples/label-bot test

The tests sign deliveries with hmacSha256Hex() from forges. They serve responses from the fixtures in test/fixtures/github/, without a network connection.

Copyright © 2026