Step-by-Step Guide to Creating a GitHub Webhook
Introduction
Webhooks are essential in integrating applications by allowing real-time data updates without constantly polling an API. This guide will walk you through setting up a GitHub webhook to capture repository events and process them in your application.
Step 1: Set Up a Web Server for Receiving Webhooks
To test webhooks locally, use tools like Ngrok or SvixPlay to create a public URL that can forward GitHub webhook requests to your local development server.
- Install Ngrok or use an alternative like SvixPlay to create a public-facing endpoint.
- Start Ngrok to forward requests to your localhost. For example:This will generate a public URL (e.g.,
ngrok http 3000
https://abcd1234.ngrok.io
) that you’ll use as the webhook URL in GitHub.
Step 2: Create a Webhook in GitHub
Navigate to Your GitHub Repository: Go to your repository settings by selecting Settings > Webhooks > Add webhook.
Configure the Webhook:
- Payload URL: Enter your public URL (e.g.,
https://abcd1234.ngrok.io/github-webhook
). - Content type: Set it to
application/json
. - Secret: Enter a secret key (recommended). This helps verify that the requests you receive are genuinely from GitHub.
- Events: Choose the events to trigger the webhook (e.g.,
push
,pull request
), or select “Send me everything” to capture all repository events.
- Payload URL: Enter your public URL (e.g.,
Save the Webhook: Click Add webhook to save your configuration. GitHub will immediately attempt a ping to your endpoint to verify the setup.
Step 3: Set Up Code to Handle Webhook Events
Create a server script to process webhook events and respond to GitHub.
Sample Code in Node.js
Here's an example using Node.js and Express to listen to incoming webhook events:
const express = require("express");
const crypto = require("crypto");
const app = express();
app.use(express.json()); // Parse JSON bodies
const GITHUB_SECRET = process.env.GITHUB_SECRET || "your_secret_key";
// Middleware to verify GitHub signature
function verifyGitHubSignature(req, res, next) {
const signature = req.headers["x-hub-signature-256"];
const hash = `sha256=${crypto
.createHmac("sha256", GITHUB_SECRET)
.update(JSON.stringify(req.body))
.digest("hex")}`;
if (signature !== hash) {
return res.status(401).send("Invalid signature");
}
next();
}
app.post("/github-webhook", verifyGitHubSignature, (req, res) => {
const event = req.headers["x-github-event"];
console.log(`Received GitHub event: ${event}`);
// Handle the event types you need
if (event === "push") {
console.log("Push event received:", req.body);
} else if (event === "pull_request") {
console.log("Pull request event received:", req.body);
}
res.sendStatus(200);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Install Dependencies:
npm install express
Run the Server:
node server.js
Test the Webhook: Trigger events in your GitHub repository (e.g., create a new pull request or push to a branch) to verify that your server receives and logs the events.
Step 4: Verify Webhook Requests
Each time GitHub sends a webhook, it includes a signature in the headers. Verifying this signature adds a security layer to ensure the request genuinely originated from GitHub.
- GitHub Signature (x-hub-signature-256): The signature header is generated by hashing the payload with the secret key. The code example above demonstrates how to verify this signature.
Step 5: Review Webhook Delivery History
After creating the webhook, you can see its delivery history in GitHub:
- Go to Settings > Webhooks in your GitHub repository.
- Select your webhook to view recent delivery logs, including status, response times, and detailed payload information.
Conclusion
Webhooks provide a powerful way to integrate GitHub actions into your applications. By following this setup, you can securely and efficiently handle GitHub webhook events, opening up possibilities for automated workflows, notifications, and data synchronization.