Sending Webhook Messages from Heroku to Discord
In this article, we delve into the seamless integration of Heroku, a popular cloud platform, with Discord, a widely used communication platform. The focus is on sending webhook messages from Heroku to Discord, enhancing real-time updates and notifications for various applications. The article guides readers through the process, offering a step-by-step approach to set up and configure webhooks, ensuring efficient and automated communication between Heroku-hosted applications and Discord channels. With this integration, users can stay informed, monitor events, and streamline communication effortlessly.
In order to communicate between Heroku and Discord we need to create a small application to parse our webhook messages to the format from Discord. The app contains the following aspects:
Features
- Express.js Server Setup:
- Utilizes the Express.js framework to create a web server.
- Listens on the specified port (
process.env.PORT
or defaulting to 3000).
- Heroku Webhook Handling:
- Provides a route (
/heroku-webhook
) to handle incoming Heroku webhook events. - Extracts relevant data from the Heroku webhook payload, including event data and metadata.
- Formats a message based on the extracted data to provide a concise summary of the Heroku event.
- Provides a route (
- Discord Webhook Integration:
- Utilizes the Axios library to send a formatted payload to a Discord webhook.
- The Discord payload includes an embed with information about the Heroku event.
- Environment Variable Usage:
- Uses
process.env
to read thePORT
andDISCORD_WEBHOOK
environment variables.s. - Provides default values for
PORT
(3000) and logs theDISCORD_WEBHOOK
value.
- Uses
You can find the code I used on my GitHub Repository.
Setup
We will need some dependencies to create our application. Let’s install them using the following commands:
npm init
npm install [email protected]
npm install [email protected]
npm install [email protected]
You should be able to obtain a package.json file similar to mine:
{
"name": "heroku-discord",
"version": "1.0.0",
"description": "Parser for heroku webhook messages to discord webhook messages",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/WebCDC/heroku-discord.git"
},
"author": "Rui Coelho",
"license": "ISC",
"bugs": {
"url": "https://github.com/WebCDC/heroku-discord/issues"
},
"homepage": "https://github.com/WebCDC/heroku-discord#readme",
"dependencies": {
"axios": "^1.6.5",
"body-parser": "^1.20.2",
"express": "^4.18.2"
}
}
Let’s create an index.js file:
const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');
const app = express();
const port = process.env.PORT || 3000;
const webhook = process.env.DISCORD_WEBHOOK;
console.log(webhook)
app.use(bodyParser.json());
app.post('/heroku-webhook', (req, res) => {
// Extract relevant data from Heroku webhook payload
const herokuEventData = req.body.data;
const herokuEventMetada = req.body.webhook_metadata;
const message = `Event ID => ${herokuEventMetada.event.id}\nEvent Type => ${herokuEventMetada.event.include}\nTriggered by => ${herokuEventData.user.email}\nStatus => ${herokuEventData.status}`
// Transform data to match Discord webhook payload structure
const discordPayload = {
embeds: [
{
title: 'Heroku Notification',
description: message,
fields: [
{ name: 'App Name', value: herokuEventData.app.name, inline: true },
// Add more fields as needed
],
},
],
};
// Send payload to Discord webhook
axios.post(`${webhook}`, discordPayload)
.then(() => res.sendStatus(200))
.catch(error => {
console.error('Error sending Discord webhook:', error);
res.sendStatus(500);
});
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Let’s break this code down.
Dependencies
express
: A web application framework for Node.js.body-parser
: Middleware to parse incoming request bodies in a middleware before your handlers.axios
: A promise-based HTTP client for the browser and Node.js.
const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');
Application Setup
- Creates an instance of the Express application.
- Defines the port for the server to run on (using the environment variable
PORT
or defaulting to 3000). - Retrieves the Discord webhook URL from the environment variable
DISCORD_WEBHOOK
.
const app = express();
const port = process.env.PORT || 3000;
const webhook = process.env.DISCORD_WEBHOOK;
Middleware Setup
- Uses
body-parser
middleware to parse incoming JSON requests.
app.use(bodyParser.json());
Webhook Handling
- Defines a route (
/heroku-webhook
) to handle incoming POST requests from Heroku. - Extracts relevant data from the Heroku webhook payload.
- Formats a message using the extracted data.
- Creates a Discord payload with an embed object containing the formatted message and additional information.
- Sends the payload to the specified Discord webhook.
app.post('/heroku-webhook', (req, res) => {
// ... (Handling Heroku webhook data)
// Transform data to match Discord webhook payload structure
const discordPayload = {
embeds: [
{
title: 'Heroku Notification',
description: message,
fields: [
{ name: 'App Name', value: herokuEventData.app.name, inline: true },
// Add more fields as needed
],
},
],
};
// Send payload to Discord webhook
axios.post(`${webhook}`, discordPayload)
.then(() => res.sendStatus(200))
.catch(error => {
console.error('Error sending Discord webhook:', error);
res.sendStatus(500);
});
});
Server Initialization
Starts the server and listens on the specified port.
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Server Initialization
- Starts the server and listens on the specified port.
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});