How to Use Discord Webhook With Custom Template Engines Like Handlebars
🔍 WiseChecker

How to Use Discord Webhook With Custom Template Engines Like Handlebars

Discord webhooks let you send automated messages to a text channel without using a bot. You compose a JSON payload with content, embeds, and username fields. But when you need to send personalized messages for many users or events, building each JSON payload manually becomes tedious. Template engines like Handlebars allow you to define a message template once and fill it with dynamic data. This article explains how to combine Discord webhooks with Handlebars to generate custom messages from any data source.

Key Takeaways: Using Handlebars With Discord Webhooks

  • Handlebars template syntax: Use double curly braces {{variable}} to insert dynamic values into your webhook JSON payload.
  • Node.js script with axios and Handlebars: Compile the template, pass data, and send the rendered JSON to the Discord webhook URL.
  • Escaping JSON in templates: Use triple curly braces {{{variable}}} to avoid double-escaping embedded HTML or Markdown content.

ADVERTISEMENT

What Is a Discord Webhook and Why Use a Template Engine

A Discord webhook is a simple HTTPS endpoint that accepts a POST request with a JSON body. The JSON can include fields like content for plain text, embeds for rich embed objects, username to override the webhook name, and avatar_url for a custom icon. You can send the request from any programming language or automation tool.

The problem is that hardcoding each message quickly becomes error-prone when you have many users or events. For example, sending a welcome message to 500 new members requires 500 different payloads. A template engine like Handlebars solves this by letting you write the message structure once and plug in variables like {{username}} or {{join_date}}.

Handlebars is a logic-less templating language. It supports conditionals ({{#if}}), loops ({{#each}}), and partials for reusable blocks. When combined with Discord webhooks, you can generate complex embed layouts that change depending on the data you supply.

Prerequisites for Using Handlebars With Discord Webhooks

Before you start, you need the following items ready:

  • A Discord webhook URL. In Discord, open Server Settings > Integrations > Webhooks. Click New Webhook, name it, select a channel, and copy the URL.
  • Node.js installed on your system (version 16 or later). You will use npm to install the axios and handlebars packages.
  • A data source. This can be a JSON file, a database query, or an API response. For this article, we use a static JSON array of user objects.

ADVERTISEMENT

Steps to Create a Handlebars Template and Send a Discord Webhook

1. Set Up the Node.js Project

  1. Create a project folder
    Open a terminal and run mkdir discord-webhook-handlebars && cd discord-webhook-handlebars.
  2. Initialize npm
    Run npm init -y to create a package.json file with default values.
  3. Install dependencies
    Run npm install axios handlebars. This installs the HTTP client and the template engine.

2. Create a Handlebars Template File

Create a file named welcome-template.hbs with the following content:

{
  "content": "Welcome to the server, {{username}}!",
  "embeds": [
    {
      "title": "New Member",
      "description": "{{username}} joined on {{join_date}}.",
      "color": "{{color}}",
      "fields": [
        {
          "name": "Roles",
          "value": "{{roles}}"
        }
      ]
    }
  ],
  "username": "Welcome Bot"
}

The double curly braces {{variable}} are Handlebars placeholders. When you compile this template with a data object, Handlebars replaces each placeholder with the corresponding value from the data object.

3. Write the Node.js Script

Create a file named send-webhook.js and add the following code:

const axios = require('axios');
const Handlebars = require('handlebars');
const fs = require('fs');

// Read the template file
const templateSource = fs.readFileSync('welcome-template.hbs', 'utf8');
const template = Handlebars.compile(templateSource);

// Sample data
const users = [
  { username: 'Alice', join_date: '2024-03-15', color: 3447003, roles: 'Member' },
  { username: 'Bob', join_date: '2024-03-16', color: 15277667, roles: 'Member, Booster' }
];

// Discord webhook URL (replace with your own)
const webhookUrl = 'https://discord.com/api/webhooks/your-webhook-id/your-webhook-token';

async function sendWebhook(payload) {
  try {
    const response = await axios.post(webhookUrl, payload, {
      headers: { 'Content-Type': 'application/json' }
    });
    console.log('Message sent:', response.status);
  } catch (error) {
    console.error('Error sending webhook:', error.response?.data || error.message);
  }
}

// Loop through each user and send a personalized message
users.forEach(user => {
  const renderedPayload = JSON.parse(template(user));
  sendWebhook(renderedPayload);
});

The script reads the template, compiles it with Handlebars, and then iterates over the users array. For each user, it renders the template with that user’s data, parses the resulting string into a JSON object, and sends it to the Discord webhook.

4. Run the Script

In the terminal, run node send-webhook.js. You should see two messages appear in your Discord channel — one for Alice and one for Bob.

Common Mistakes and Things to Avoid

Double-Escaping JSON Strings

When you use {{variable}} inside a JSON template, Handlebars escapes HTML characters by default. If your variable contains valid Markdown or embed content, the escaping breaks the formatting. To prevent this, use triple curly braces {{{variable}}} or register a Handlebars helper that outputs raw text.

Invalid JSON After Rendering

If a variable contains a newline or a double quote, the rendered JSON may become invalid. Always sanitize user input before passing it to the template. Use a helper function to escape double quotes and remove line breaks inside string values.

Missing Variables Cause Empty Strings

If a data object does not contain a referenced variable, Handlebars outputs an empty string. This can produce unexpected embed content. Use the {{#if}} helper to conditionally include fields only when the variable exists.

Discord Webhook vs Bot: Key Differences

Item Webhook Bot
Setup Create from Server Settings, no code needed Register application in Discord Developer Portal
Permissions Fixed to the webhook creator’s permissions Granular via OAuth2 scopes and bot tokens
Rate Limits 30 requests per second per webhook 50 requests per second per bot
Message Types Plain text, embeds, files Same plus slash commands, buttons, modals
User Identity Shows as webhook name, not a user Shows as the bot user
Template Engine Integration Simple with Handlebars in any language Possible but requires library support for components

Webhooks are ideal for simple automated messages where you do not need interactive features. Bots are better when you need slash commands, buttons, or real-time event subscriptions.

You can now generate personalized Discord messages using Handlebars templates. Start by designing a template for your most common notification — for example, a new member welcome or a server update. To extend the script, add Handlebars helpers for formatting dates or truncating long text. For advanced use, integrate the template with a database query so that each webhook pull sends messages for the latest records.

ADVERTISEMENT