discord-webhook-kit
v0.1.0
Published
Modern, TypeScript-first Discord Webhook client
Maintainers
Readme
discord-webhook-kit
Modern, TypeScript-first Discord Webhook client with full type safety, ESM support, and modern features.
Features
- TypeScript-first: Full type safety with comprehensive type definitions
- Modern: ESM and CJS dual build support
- Safe defaults: Prevents accidental
@everyonementions - Rate limit handling: Automatic retry with configurable backoff
- Lightweight: Minimal dependencies (only
undici) - Simple API: Easy to use and predictable
- EmbedBuilder: Fluent API for building embeds with method chaining
- AlertClient: Pre-configured alerts for error monitoring (info/success/warn/error)
Installation
npm install discord-webhook-kitQuick Start
import { WebhookClient } from "discord-webhook-kit";
const webhook = new WebhookClient(
"https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
);
// Send a simple message
await webhook.send("Hello, Discord!");
// Send with custom username and avatar
await webhook.send({
content: "Hello from custom bot!",
username: "My Bot",
avatar_url: "https://example.com/avatar.png",
});Usage Examples
Simple Text Message
const webhook = new WebhookClient(WEBHOOK_URL);
await webhook.send("Hello, World!");Rich Embed Message
await webhook.send({
content: "Check out this embed!",
embeds: [
{
title: "Embed Title",
description: "This is the embed description",
color: 0x00ff00, // Green color
fields: [
{ name: "Field 1", value: "Value 1", inline: true },
{ name: "Field 2", value: "Value 2", inline: true },
],
footer: {
text: "Footer text",
},
timestamp: new Date().toISOString(),
},
],
});Using EmbedBuilder (Method Chaining)
import { WebhookClient, EmbedBuilder } from "discord-webhook-kit";
const embed = new EmbedBuilder()
.setTitle("My title here")
.setAuthor(
"Author here",
"https://cdn.discordapp.com/embed/avatars/0.png",
"https://www.google.com"
)
.setURL("https://www.google.com")
.addField("First field", "this is inline", true)
.addField("Second field", "this is not inline")
.setColor("#00b0f4")
.setThumbnail("https://cdn.discordapp.com/embed/avatars/0.png")
.setDescription("Oh look a description :)")
.setImage("https://cdn.discordapp.com/embed/avatars/0.png")
.setFooter(
"Hey its a footer",
"https://cdn.discordapp.com/embed/avatars/0.png"
)
.setTimestamp();
await webhook.send({ embeds: [embed] });With Default Options
const webhook = new WebhookClient(WEBHOOK_URL, {
username: "Notification Bot",
avatarUrl: "https://example.com/bot-avatar.png",
retryOnRateLimit: true,
maxRetries: 5,
timeout: 10000,
});
// All messages will use the default username and avatar
await webhook.send("This uses default settings!");Send to Thread
const webhook = new WebhookClient(WEBHOOK_URL, {
threadId: "1234567890",
});
await webhook.send("Message sent to a specific thread!");Disable Rate Limit Retry
const webhook = new WebhookClient(WEBHOOK_URL, {
retryOnRateLimit: false,
});
try {
await webhook.send("Message");
} catch (error) {
if (error instanceof DiscordWebhookError && error.isRateLimit()) {
console.log("Rate limited! Try again later.");
}
}API Reference
WebhookClient
new WebhookClient(webhookUrl: string, options?: WebhookClientOptions)Constructor Options
| Option | Type | Default | Description |
| ------------------ | --------- | ------- | ------------------------------------ |
| username | string | - | Default username for all messages |
| avatarUrl | string | - | Default avatar URL for all messages |
| wait | boolean | true | Wait for server confirmation |
| threadId | string | - | Thread ID to send messages to |
| retryOnRateLimit | boolean | true | Automatically retry on rate limit |
| maxRetries | number | 3 | Maximum retry attempts on rate limit |
| timeout | number | 30000 | Request timeout in milliseconds |
Methods
send(content: string | WebhookMessage): Promise<WebhookResponse>
Sends a message to the Discord webhook.
// String shorthand
await webhook.send("Hello!");
// Full message object
await webhook.send({
content: "Hello!",
username: "Custom Name",
embeds: [{ title: "Embed" }],
});getMaskedUrl(): string
Returns a masked version of the webhook URL safe for logging.
console.log(webhook.getMaskedUrl());
// Output: /webhooks/1234567890/abcd...wxyzWebhookMessage
| Field | Type | Description |
| ------------------ | ----------------- | -------------------------------- |
| content | string | Message content (max 2000 chars) |
| username | string | Override webhook username |
| avatar_url | string | Override webhook avatar |
| tts | boolean | Text-to-speech message |
| embeds | WebhookEmbed[] | Array of embeds (max 10) |
| allowed_mentions | AllowedMentions | Mention control |
| flags | number | Message flags |
| thread_name | string | Thread name (for forum channels) |
| applied_tags | string[] | Tag IDs (for forum channels) |
WebhookEmbed
| Field | Type | Description |
| ------------- | --------------------- | ---------------------------- |
| title | string | Embed title (max 256 chars) |
| description | string | Embed description (max 4096) |
| url | string | URL for title link |
| color | number | Color code (decimal) |
| timestamp | string | ISO8601 timestamp |
| footer | WebhookEmbedFooter | Footer object |
| image | WebhookEmbedMedia | Image object |
| thumbnail | WebhookEmbedMedia | Thumbnail object |
| author | WebhookEmbedAuthor | Author object |
| fields | WebhookEmbedField[] | Fields array (max 25) |
EmbedBuilder
Builder class for creating embeds with method chaining.
| Method | Description |
| --------------------------------- | -------------------------------- |
| setTitle(title) | Set embed title |
| setDescription(description) | Set embed description |
| setURL(url) | Set embed URL |
| setColor(color) | Set color (hex string or number) |
| setAuthor(name, iconUrl?, url?) | Set author info |
| setThumbnail(url) | Set thumbnail image |
| setImage(url) | Set main image |
| setFooter(text, iconUrl?) | Set footer |
| setTimestamp(timestamp?) | Set timestamp (default: now) |
| addField(name, value, inline?) | Add a field |
| addFields(...fields) | Add multiple fields |
| toJSON() | Convert to plain embed object |
DiscordWebhookError
Custom error class for Discord API errors.
try {
await webhook.send("Message");
} catch (error) {
if (error instanceof DiscordWebhookError) {
console.log("Status:", error.status);
console.log("Message:", error.message);
console.log("Raw body:", error.rawBody);
console.log("Request ID:", error.requestId);
console.log("Is rate limit:", error.isRateLimit());
}
}AlertClient (Error Alerting)
AlertClient provides a convenient way to send formatted alerts to Discord, perfect for error monitoring and application notifications.
import { AlertClient } from "discord-webhook-kit";
const alert = new AlertClient(WEBHOOK_URL, {
appName: "My API",
environment: "production",
username: "Alert Bot",
avatarUrl: "https://example.com/avatar.png",
});
// Info alert (blue)
await alert.info("User logged in", {
fields: [{ name: "User ID", value: "12345" }],
});
// Success alert (green)
await alert.success("Payment completed", {
fields: [
{ name: "Amount", value: "$100.00" },
{ name: "Order ID", value: "ORD-123" },
],
});
// Warning alert (yellow)
await alert.warn("High memory usage detected", {
fields: [{ name: "Usage", value: "85%" }],
});
// Error alert (red) - with Error object auto-formatting
try {
await riskyOperation();
} catch (err) {
await alert.error(err); // Auto-formats Error with stack trace
}
// Error alert with custom message and error
await alert.error("Database operation failed", {
error: caughtError,
fields: [{ name: "Query", value: "SELECT * FROM users" }],
});AlertClient Options
| Option | Type | Default | Description |
| ------------- | -------- | --------- | -------------------------------- |
| appName | string | "Alert" | Application name shown in title |
| environment | string | - | Environment (e.g., "production") |
| username | string | - | Default webhook username |
| avatarUrl | string | - | Default webhook avatar |
Alert Colors
| Level | Color | Hex Code |
| --------- | ------ | --------- |
| info | Blue | #3498db |
| success | Green | #00ff1d |
| warn | Yellow | #f1c40f |
| error | Red | #ff0000 |
Error Auto-Formatting
When passing an Error object to alert.error(), it automatically:
- Extracts error name and message
- Includes
codeandstatusproperties if present - Formats stack trace in a code block
- Respects Discord's field limits (auto-trims long content)
Safe Defaults
By default, discord-webhook-kit disables @everyone and @here mentions to prevent accidental mass pings:
// Default: allowed_mentions is set to { parse: [] }
await webhook.send("@everyone Hello!"); // Won't ping everyone
// To enable mentions, explicitly set allowed_mentions
await webhook.send({
content: "@everyone Hello!",
allowed_mentions: { parse: ["everyone"] },
});Requirements
- Node.js 18.0.0 or higher
Related
- Discord.js Documentation - Official Discord.js docs
- Discord Webhook API - Official Discord API documentation
License
MIT
