How to resolve webhook error 400 when sending webhooks from Github to Discord
If you're encountering a 400 error when trying to set up a GitHub webhook with Discord, it usually indicates an issue with the request payload or URL configuration. Here are common reasons for the 400 error and how to resolve them:
1. Use the Correct Discord Webhook URL
Make sure you are using the full and correct URL provided by Discord for your webhook. The URL should look something like:
https://discord.com/api/webhooks/{webhook_id}/{webhook_token}
If this URL is incorrect, GitHub will return a 400 error because it can’t find the appropriate webhook endpoint.
- Verify the URL: Double-check that your Discord webhook URL matches what Discord provides.
- No Modifications: Avoid adding query parameters or additional paths to the Discord webhook URL; GitHub should send requests to it directly as provided by Discord.
2. Set the Content Type Correctly
Discord expects the payload to be in application/json
format. By default, GitHub webhooks should be set to use application/json
, but if you’ve changed it, this can cause a 400 error.
- Go to GitHub Repository Settings > Webhooks.
- Content Type: Ensure it’s set to
application/json
.
3. Check Payload Format Compatibility
Discord expects a specific payload structure, which may not match GitHub’s default payload format. To work around this:
- Use Only Specific Events: Configure your GitHub webhook to trigger only for specific events compatible with Discord. For example,
push
events generally work well, as they include concise information. - Consider Using a Middleware: If you need to process other events, set up a middleware server (using Node.js, Python, etc.) to capture the GitHub webhook, modify the payload to match Discord’s format, and then forward it to Discord.
4. Use a Service Like Zapier (Optional)
If direct integration continues to be problematic, you can use tools like Zapier or IFTTT to bridge GitHub and Discord without dealing with payload incompatibility issues.
Example: Setting Up Middleware with Node.js
If you want to set up middleware yourself to handle payload formatting, here’s a basic example in Node.js:
const express = require("express");
const axios = require("axios");
const app = express();
app.use(express.json());
const DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/{webhook_id}/{webhook_token}";
app.post("/github-webhook", async (req, res) => {
try {
const payload = {
content: `New update from GitHub!\n\nRepository: ${req.body.repository.full_name}\nEvent: ${req.headers["x-github-event"]}`
};
await axios.post(DISCORD_WEBHOOK_URL, payload, {
headers: { "Content-Type": "application/json" }
});
res.sendStatus(200);
} catch (error) {
console.error("Error forwarding to Discord:", error);
res.sendStatus(500);
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
With this setup:
- The middleware receives the GitHub webhook.
- It formats a custom message and sends it to Discord.
- You can trigger this middleware by setting the webhook URL in GitHub to point to your middleware server (
http://your-middleware-url.com/github-webhook
).
Alternative: Use Svix's Transformations Feature for Easier Integration
If setting up middleware feels too complex or you’d prefer a more streamlined solution, consider using Svix’s Transformations feature. Svix allows you to configure a GitHub webhook to send payloads to Svix first, where you can automatically transform the payload to match Discord’s requirements. Svix will then forward the modified webhook to Discord.
With Svix, you can skip writing custom middleware code and use a user-friendly interface to adjust the payload structure. This approach provides flexibility and reduces setup time, making it an ideal choice for simplifying GitHub-to-Discord webhook integrations.