JAVASCRIPT

Node.js: Creating a Simple Webhook Listener with Express

Set up a robust Node.js Express server to listen for and process incoming webhook POST requests, ensuring secure handling of event payloads from external APIs.

const express = require('express');
const bodyParser = require('body-parser'); // For parsing JSON/URL-encoded bodies
const crypto = require('crypto'); // For verifying signatures if provided by webhook source

const app = express();
const port = 3000;

// Middleware to parse JSON bodies
app.use(bodyParser.json());

// Example secret key for webhook signature verification (replace with a strong, environment-variable key)
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || 'your-super-secret-key';

// Webhook listener endpoint
app.post('/webhook', (req, res) => {
  console.log('Received webhook request.');

  // --- Optional: Webhook Signature Verification ---
  // Many webhook providers send a signature in a header (e.g., 'X-Hub-Signature', 'X-Stripe-Signature')
  // This helps ensure the request truly came from the expected source and hasn't been tampered with.
  // Example for GitHub-like HMAC-SHA256 signature verification:
  const signature = req.headers['x-hub-signature-256']; // Or whatever header your provider uses

  if (signature) {
    const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
    const digest = 'sha256=' + hmac.update(JSON.stringify(req.body)).digest('hex'); // Use raw body for verification if available
    // Note: Some webhook providers require verifying the *raw* request body before parsing.
    // If you need the raw body for verification, use a custom bodyParser or put this check before app.use(bodyParser.json())
    // and access req.rawBody (if a custom middleware adds it) or req.body before it's parsed.
    // For simplicity, here we're using the already parsed body.

    if (digest !== signature) {
      console.warn('Webhook signature mismatch. Request might be invalid or tampered with.');
      return res.status(401).send('Signature verification failed.');
    }
    console.log('Webhook signature verified successfully.');
  } else {
    console.log('No webhook signature provided (or not configured). Proceeding without verification.');
  }
  // --- End Signature Verification ---

  const eventPayload = req.body;
  console.log('Webhook Payload:', eventPayload);

  // Process the webhook payload based on its type or content
  if (eventPayload.event_type === 'user.created') {
    console.log(`New user created: ${eventPayload.user.email}`);
    // Perform actions like sending a welcome email, updating a CRM, etc.
  } else if (eventPayload.event_type === 'payment.succeeded') {
    console.log(`Payment successful for order: ${eventPayload.order_id}`);
    // Update order status, fulfill subscription, etc.
  } else {
    console.log(`Unhandled event type: ${eventPayload.event_type}`);
  }

  // Respond to the webhook sender to acknowledge receipt
  // A 200 OK status is generally expected within a few seconds.
  res.status(200).send('Webhook received and processed.');
});

app.listen(port, () => {
  console.log(`Webhook listener running on http://localhost:${port}`);
  console.log('Waiting for incoming webhook requests...');
});

// To test locally, you can use a tool like ngrok to expose your local server
// ngrok http 3000
How it works: This Node.js Express snippet creates a server that listens for incoming HTTP POST requests, commonly used for webhooks. It uses `body-parser` to automatically parse JSON payloads. The core logic resides in the `/webhook` endpoint, which receives the payload and processes it based on the `event_type`. Crucially, it includes an optional but highly recommended section for webhook signature verification using Node.js's `crypto` module. This ensures that the incoming request genuinely originates from the expected source and has not been tampered with, enhancing the security of your API integrations. The server responds with a 200 OK status to acknowledge receipt.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs