A GitHub webhook server that posts repository events to Slashwork via their GraphQL API. Supports pull requests, issues, pushes, and releases with config-driven routing to different Slashwork groups.
| Event | Actions |
|---|---|
pull_request |
opened, closed/merged, review_requested, ready_for_review, synchronize |
issues |
opened, closed, reopened, labeled, assigned |
issue_comment |
created |
push |
all pushes (no action filter) |
release |
published, created, edited |
- Bun v1.0+
- Install dependencies:
bun install- Copy the environment template and fill in your values:
cp .env.example .env-
Edit
.envwith your actual credentials (see sections below). -
Edit
config.tsto configure event routing (see Configuration).
Event routing is configured in config.ts at the project root:
import type { SkiphooksConfig } from "./src/config.ts";
const config: SkiphooksConfig = {
github: {
webhookSecret: process.env.GITHUB_WEBHOOK_SECRET!,
},
slashwork: {
graphqlUrl: process.env.SLASHWORK_GRAPHQL_URL!,
},
groups: {
myproject: {
id: "g_abc123",
authToken: process.env.SLASHWORK_AUTH_TOKEN_MYPROJECT!,
},
},
routes: {
// Group-based route — references a named group for its ID and auth token
myproject: { group: "myproject" },
// Direct stream route — specifies stream ID and auth token inline
releases: {
streamId: "g_def456",
authToken: process.env.SLASHWORK_AUTH_TOKEN_RELEASES!,
},
},
};
export default config;- Secrets stay in
.envand are referenced viaprocess.env. - Routes are path-based — each route name becomes a
/github/<name>endpoint. Only configured routes are active — requests to unknown routes return 404. - Groups let multiple routes share the same auth token and target ID. Routes can reference a group by name or specify
streamId/authTokendirectly.
See the Slashwork Developer docs for full details.
- Create a stream (or use an existing one) where notifications will be posted.
- Create an application with a dedicated auth token — this goes in a
SLASHWORK_AUTH_TOKEN_*env var. - Find the group ID of your target stream(s) from their URLs — these go in
config.tsgroups or routes. - Set
SLASHWORK_GRAPHQL_URLtohttps://<your-instance>.slashwork.com/api/graphql.
- Go to your repo (or org) Settings → Webhooks → Add webhook.
- Payload URL:
https://<your-server>/github/<route-name>(matching a route inconfig.ts) - Content type:
application/json - Secret: Same value as your
GITHUB_WEBHOOK_SECRETenv var. - Events: Select the events you want (Pull requests, Issues, Pushes, Releases).
bun run devbun run startbun testDeployed to Clever Cloud via GitHub Actions. Every push to main runs typecheck and tests, then deploys automatically on success.
Required GitHub secrets (Settings > Secrets and variables > Actions):
CLEVER_TOKENCLEVER_SECRET
- Signature mismatch (401): Ensure
GITHUB_WEBHOOK_SECRETmatches exactly between GitHub and your.env. Check for trailing whitespace. - Posts not appearing: Verify group IDs in
config.tspoint to valid streams. Check server logs for GraphQL errors. - Token issues: Ensure your
SLASHWORK_AUTH_TOKEN_*env vars have write permissions to the target groups. - No events received: Confirm the webhook is active in GitHub (Settings → Webhooks) and the desired events are selected.
- Event ignored: Check that the route exists in
config.tsand the action is one of the supported actions listed above.