@eliware/discord-webhook
v2.0.0
Published
A simple, promise-based Discord webhook sender for Node.js with built-in rate limit handling.
Maintainers
Readme
@eliware/discord-webhook v2.0.0 


A simple, promise-based Discord webhook sender for Node.js with built-in rate limit handling.
Table of Contents
Features
- Send messages to Discord webhooks with a single function
- Handles Discord rate limits automatically (HTTP 429)
- ESM-first, TypeScript types included
- Customizable fetch for testing/mocking
- Supports default webhook URL from
process.env.DISCORD_WEBHOOK - Validates Discord payload size limits before making a request
- Supports request timeouts, cancellation, threads, and
waitresponses
Requirements
- Node.js 26 or newer
Installation
npm install @eliware/discord-webhookUsage
ESM Example
import { sendMessage } from '@eliware/discord-webhook';
const webhookUrl = 'https://discord.com/api/webhooks/your-webhook-id/your-webhook-token';
const messageBody = { content: 'Hello from discord-webhook!' };
(async () => {
try {
const response = await sendMessage({ url: webhookUrl, body: messageBody });
if (response.ok) {
console.log('Message sent successfully!');
} else {
console.error('Failed to send message:', response.status, await response.text());
}
} catch (err) {
console.error('Error sending message:', err);
}
})();API
sendMessage({ body, url = process.env.DISCORD_WEBHOOK, maxRetries = 3, fetchFn = fetch, timeoutMs, signal, wait, threadId, threadName })
Sends a message to a Discord webhook URL, handling rate limits with automatic retry.
Parameters:
body(object): The JSON body to send (e.g.,{ content: 'Hello!' }).url(string, optional): The Discord webhook URL. Defaults toprocess.env.DISCORD_WEBHOOK.maxRetries(number, optional): Maximum number of retries on rate limit (default: 3).fetchFn(function, optional): Custom fetch function for testing/mocking (default:fetch).timeoutMs(number, optional): Request timeout in milliseconds.signal(AbortSignal, optional): Cancels an in-flight request.wait(boolean, optional): Requests the created Discord message response.threadId/threadName(string, optional): Sends to a Discord thread.
Returns:
Promise<Response>: The fetch response.
Throws:
- Error if the URL or body is invalid.
- Error if content or embed fields exceed Discord limits; validation happens before
fetch. - Error if max retries are exceeded due to rate limiting.
Payload limits
The library rejects payloads that Discord will refuse, including content over 2,000 characters, more than 10 embeds, more than 25 fields per embed, and embed text over 6,000 characters. It also validates title, description, field, footer, and author limits.
TypeScript
Type definitions are included and cover sendMessage, validateWebhookBody, and DISCORD_LIMITS.
const response = await sendMessage({
body: { content: 'Hello!' },
url: process.env.DISCORD_WEBHOOK,
maxRetries: 3,
timeoutMs: 30_000,
signal: abortController.signal,
wait: true,
threadId: 'thread-id',
threadName: 'thread-name',
});Errors / Troubleshooting
sendMessage validates the webhook URL, body, retry and timeout options before making a request. HTTP failures include the response status and body when available. Rate limits are retried up to maxRetries; timeout and caller cancellation errors are reported explicitly. The default timeout is 30 seconds and retries are bounded to 10 even when a larger value is supplied.
For local development, run:
npm test
npm run lint
npm run typecheck
npm audit --omit=dev --audit-level=moderate
npm run packSecurity
Treat webhook URLs as credentials. Store them in DISCORD_WEBHOOK or another secret store; do not commit real URLs or log request credentials.
Support
For help, questions, or to chat with the author and community, visit:
License
MIT © 2025 Eli Sterling, eliware.org



