Modern Discord webhook notification service for Node.js. Send rich embeds, file attachments, and threaded messages with zero dependencies. Built specifically for Discord's powerful webhook capabilities.
npm install discord-notifyA powerful, zero-dependency Discord webhook notification service for Node.js applications. Send beautiful, formatted notifications to Discord channels with rich embeds, file attachments, thread support, and full TypeScript support.
Discord Notify is the most comprehensive Discord webhook library for Node.js, designed specifically to leverage Discord's powerful features:




``bash`
npm install discord-notify
> ๐ Looking for secure installation instructions? See SECURE_INSTALLATION.md for best practices on handling secrets, environment variables, and production deployments.
`typescript
import DiscordNotifyFactory from 'discord-notify';
// Create your notifier
const notifier = DiscordNotifyFactory({
webhookUrl: 'https://discord.com/api/webhooks/YOUR_WEBHOOK_URL',
appName: 'My Awesome App',
environment: 'production'
});
// Send notifications instantly
await notifier.success('User registration completed!');
await notifier.error('Database connection failed');
await notifier.alert('High memory usage detected');
await notifier.info('Scheduled backup completed');
`
`typescript
// Simple text message
await notifier.send('Hello from my app!');
// Rich embed with all Discord features
await notifier.send({
title: 'Server Status Report',
description: 'Current server metrics and health status',
color: 0x0099ff,
fields: [
{ name: 'CPU Usage', value: '45%', inline: true },
{ name: 'Memory Usage', value: '67%', inline: true },
{ name: 'Active Users', value: '1,234', inline: false }
],
thumbnail: { url: 'https://example.com/server-icon.png' },
image: { url: 'https://example.com/server-graph.png' }
});
`
`typescript
// Success notifications (green)
await notifier.success('Deployment completed successfully');
// Error notifications (red)
await notifier.error('Application crashed with error details');
// Alert notifications (orange)
await notifier.alert('High CPU usage detected on server');
// Info notifications (blue)
await notifier.info('New user registered: john_doe');
`
`typescript
import { readFileSync } from 'fs';
// Send log files, reports, or any file type
const logContent = readFileSync('/var/log/app.log', 'utf8');
const logBuffer = new TextEncoder().encode(logContent);
await notifier.sendFile(
{
title: 'Daily Log Report',
description: 'Application logs for today',
color: 0x00ff00
},
{
name: app-${new Date().toISOString().split('T')[0]}.log,`
data: logBuffer,
contentType: 'text/plain'
}
);
`typescript
const threadId = '1234567890123456789';
// Send to specific thread for organized conversations
await notifier.sendToThread(
{
title: 'Deployment Started',
description: 'New version deployment initiated',
color: 0xffff00,
fields: [
{ name: 'Version', value: 'v2.1.0', inline: true },
{ name: 'Environment', value: 'production', inline: true }
]
},
threadId
);
`
`typescript
// With bot token - tags are auto-created and applied
const notifier = DiscordNotifyFactory({
webhookUrl: 'YOUR_WEBHOOK_URL',
botToken: 'YOUR_BOT_TOKEN',
forum: {
defaultForumChannelId: 'YOUR_FORUM_CHANNEL_ID',
autoCreateTags: true // Default: true when botToken exists
}
});
// Create forum post with tags (tags auto-created if missing)
if (notifier.forum) {
const threadId = await notifier.forum.post({
title: 'Bug Report: Database Connection',
message: {
title: 'Error Details',
description: 'Database connection failed at 3:45 PM',
color: 0xff0000
},
tags: ['bug', 'database', 'critical'] // Tag names - auto-resolved to IDs
});
}
// Or ensure tags exist first
if (notifier.forum) {
const tagIds = await notifier.forum.ensureTags('channel-id', ['bug', 'feature']);
// Returns tag IDs in same order as input
}
`
`typescript
// Without bot token - tags shown as embed field/footer
const notifier = DiscordNotifyFactory({
webhookUrl: 'YOUR_WEBHOOK_URL',
forum: {
onMissingBot: 'fallbackToWebhook', // Default
tagsFieldMode: 'field' // 'field' | 'footer' | 'none'
}
});
// Tags will appear as a field in the embed
await notifier.send({
title: 'Bug Report',
description: 'Database connection issue',
tags: ['bug', 'database'] // Shown as "Tags: bug, database" field
});
`
`typescript
const extendedNotifier = notifier.extend({
title: 'Base Information',
description: 'This is the base embed'
});
await extendedNotifier.send({
title: 'Additional Information',
description: 'This will be sent as a second embed'
});
`
Discord Notify is perfect for:
typescript
// Monitor your app health
setInterval(async () => {
const status = await checkAppHealth();
if (!status.healthy) {
await notifier.error({
title: 'Application Health Check Failed',
description: 'Issues detected in system',
fields: [
{ name: 'Database', value: status.db ? 'Connected' : 'Failed', inline: true },
{ name: 'API', value: status.api ? 'Healthy' : 'Issues', inline: true },
{ name: 'Error', value: status.error || 'Unknown error', inline: false }
]
});
}
}, 300000); // Check every 5 minutes
`$3
`typescript
// Notify team about deployments
await notifier.success({
title: 'Deployment Successful',
description: 'New version deployed to production',
fields: [
{ name: 'Version', value: 'v2.1.0', inline: true },
{ name: 'Duration', value: '2m 34s', inline: true },
{ name: 'Environment', value: 'production', inline: true }
]
});
`$3
`typescript
try {
// Some operation that might fail
throw new Error('Something went wrong');
} catch (error) {
await notifier.error({
title: 'Application Error',
description: error.message,
fields: [
{ name: 'Stack Trace', value: error.stack || 'No stack trace', inline: false },
{ name: 'Timestamp', value: new Date().toISOString(), inline: true },
{ name: 'Environment', value: process.env.NODE_ENV || 'unknown', inline: true }
]
});
}
`$3
`typescript
// Create Discord bots with rich notifications
await notifier.send({
title: 'Bot Command Executed',
description: 'User performed an action',
fields: [
{ name: 'User', value: 'john_doe', inline: true },
{ name: 'Command', value: '/status', inline: true },
{ name: 'Channel', value: '#general', inline: true }
],
color: 0x00ff00
});
`API Reference
$3
Creates a new Discord notifier instance.
Parameters:
-
webhookUrl (string, required): Your Discord webhook URL
- appName (string, optional): Name of your application
- environment (string, optional): Environment name
- username (string, optional): Override webhook username
- avatarUrl (string, optional): Override webhook avatar URL
- threadId (string, optional): Default thread ID for all messages
- botToken (string, optional): Bot token for advanced features (forum tags, deduplication, message editing)
- forumChannelId (string, optional): Forum channel ID (legacy - use forum.defaultForumChannelId)
- forum (object, optional): Forum configuration
- defaultForumChannelId (string, optional): Default forum channel ID
- autoCreateTags (boolean, optional): Auto-create missing tags (default: true when botToken exists)
- onMissingBot ('fallbackToWebhook' | 'ignoreTags' | 'throw', optional): Behavior when tags provided but no bot token (default: 'fallbackToWebhook')
- tagsFieldMode ('field' | 'footer' | 'none', optional): How to display tags in webhook fallback (default: 'field')
- tagCacheTtlMs (number, optional): Tag cache TTL in milliseconds (default: 900000 = 15 minutes)Note on
botToken: The bot token is used internally with different Discord API endpoints and parameters (GET, POST, PATCH requests with various content types). The code follows DRY (Don't Repeat Yourself) principles - all bot API calls use a centralized getBotHeaders() helper function to generate headers consistently, eliminating code duplication across 16+ API calls.Returns: A
DiscordNotify instance with the following methods:$3
| Method | Description | Example |
|--------|-------------|---------|
|
send(args) | Send basic notification | notifier.send('Hello!') |
| success(args) | Send success notification (green) | notifier.success('Task completed!') |
| error(args) | Send error notification (red) | notifier.error('Something failed') |
| alert(args) | Send alert notification (orange) | notifier.alert('Warning detected') |
| info(args) | Send info notification (blue) | notifier.info('Information message') |
| sendFile(args, file) | Send with file attachment | notifier.sendFile(args, fileData) |
| sendToThread(args, threadId) | Send to specific thread | notifier.sendToThread(args, '123456789') |
| extend(args) | Create multi-embed notifier | notifier.extend(baseEmbed) |
| forum.ensureTags(channelId, tags) | Resolve tag names to IDs, auto-create if missing | await notifier.forum?.ensureTags('channel-id', ['bug']) |
| forum.post({ title, message, tags }) | Create forum post with tags | await notifier.forum?.post({ title: 'Bug', tags: ['bug'] }) |$3
`typescript
interface SendArgs {
content?: string; // Plain text message (outside embed)
title?: string; // Embed title
description?: string; // Embed description
color?: number; // Embed color (hex)
fields?: DiscordField[]; // Embed fields
timestamp?: string; // Embed timestamp
footer?: { text: string; icon_url?: string; };
thumbnail?: { url: string; };
image?: { url: string; };
author?: { name: string; url?: string; icon_url?: string; };
url?: string; // URL for embed title
}interface DiscordField {
name: string;
value: string;
inline?: boolean;
}
interface FileAttachment {
name: string;
data: Uint8Array | string;
contentType?: string;
}
interface ForumConfig {
defaultForumChannelId?: string;
autoCreateTags?: boolean;
onMissingBot?: 'fallbackToWebhook' | 'ignoreTags' | 'throw';
tagsFieldMode?: 'field' | 'footer' | 'none';
tagCacheTtlMs?: number;
}
`Note: The
tags field in SendArgs accepts tag names (not IDs). When botToken is provided, these are automatically resolved to tag IDs. When botToken is missing, tags are displayed as metadata based on tagsFieldMode.Discord Webhook Setup
1. Create a Discord Webhook:
- Go to your Discord server settings
- Navigate to Integrations > Webhooks
- Click "New Webhook"
- Choose a channel and give it a name
- Copy the webhook URL
2. Test Your Webhook:
`typescript
import DiscordNotifyFactory from 'discord-notify';const notifier = DiscordNotifyFactory({
webhookUrl: 'YOUR_WEBHOOK_URL_HERE'
});
await notifier.success('Webhook is working!');
`Community and Support





Examples
Check out complete working examples in the examples directory:
- Basic Usage Example - CommonJS example with comprehensive features
- TypeScript Usage Example - Full TypeScript example with type safety
Testing
`bash
Run all tests
npm run test:fullUnit tests only
npm run test:unitIntegration tests (requires Discord webhook URL)
export DISCORD_WEBHOOK_URL="your_webhook_url"
npm run test:integration
`Contributing
Contributions are welcome! We love contributions from the community. Please see our Contributing Guide for:
- ๐ Development Setup - How to get started
- ๐ Coding Standards - TypeScript and code style guidelines
- ๐งช Testing - How to write and run tests
- ๐ Documentation - Keeping docs up to date
- ๐ Pull Request Process - How to submit changes
- ๐ฏ Conventional Commits - For automatic changelog generation
$3
`bash
Fork and clone
git clone https://github.com/YOUR_USERNAME/discord-notify.git
cd discord-notifyInstall and setup
npm install
npm run build
npm run test:fullMake your changes and submit a PR!
``This project is licensed under the MIT License - see the LICENSE file for details.
- Documentation: API Reference
- Forum Threads: Forum Thread Testing Guide
- Bot Permissions: Bot Permissions Guide - Complete guide to required Discord bot permissions
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Discord Community: Join our Discord
See CHANGELOG.md for a complete list of changes and version history.
---
Discord Notify - Modern Discord notifications for Node.js applications. Built with TypeScript, zero dependencies, and full Discord API compliance.