initial commit

This commit is contained in:
coo1estguy
2026-08-19 12:04:44 +05:30
commit f86776ec75
195 changed files with 57011 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
/**
* Example project demonstrating how to use Notifkit via its HTTP API — no SDK,
* just fetch. Any language that can POST JSON works the same way.
*
* Before running this, start a Notifkit server. The custom-server example is
* one:
* $ cd ../custom-server && node index.js
*
* To run this example:
* $ ADMIN_API_KEY=my_super_secret_admin_key npm start
*/
const API_BASE = process.env.NOTIFKIT_API_URL || 'http://localhost:3000/v1';
const API_KEY = process.env.ADMIN_API_KEY || 'my_super_secret_admin_key';
// Every /v1 route is authenticated. Only /health, /live, /ready and /metrics are not.
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${API_KEY}`,
};
async function main() {
console.log('🚀 Starting Notifkit example...\n');
try {
// 1. Sync Templates (Configure how notifications should look)
console.log('1️⃣ Syncing email template...');
const templateRes = await fetch(`${API_BASE}/templates`, {
method: 'PUT',
headers,
body: JSON.stringify({
templates: [{
id: 'welcome_email',
channel: 'email',
// The per-channel fields live under `content`.
content: {
subject: 'Welcome to Notifkit, {{name}}!',
html: '<h1>Hello {{name}}</h1><p>Thanks for signing up!</p>',
text: 'Hello {{name}}! Thanks for signing up!'
}
}]
})
});
console.log('Template Response:', await templateRes.json());
console.log();
// 2. Create a User (Register a recipient)
console.log('2️⃣ Registering a user...');
const userRes = await fetch(`${API_BASE}/users`, {
method: 'POST',
headers,
body: JSON.stringify({
id: 'user_123',
email: 'test@example.com',
preferences: {
channels: { email: true }
}
})
});
console.log('User Response:', await userRes.json());
console.log();
// 3. Send a Notification
console.log('3️⃣ Sending notification...');
const notifyRes = await fetch(`${API_BASE}/notify`, {
method: 'POST',
headers,
body: JSON.stringify({
user: 'user_123',
template: 'welcome_email',
channels: ['email'],
data: {
name: 'Alice'
}
})
});
// 202 Accepted — queued, not delivered. Track it with
// GET /v1/notifications/{taskId}.
console.log('Notify Response:', await notifyRes.json());
console.log('\n✅ Example completed successfully!');
} catch (err) {
console.error('❌ Error executing example:', err.message);
}
}
main();
+9
View File
@@ -0,0 +1,9 @@
{
"name": "notifkit-example",
"version": "1.0.0",
"type": "module",
"description": "Example Node.js project demonstrating Notifkit API usage",
"scripts": {
"start": "node index.js"
}
}
+19
View File
@@ -0,0 +1,19 @@
# Custom Server Example
This example demonstrates how to bootstrap the `NotifkitServer` orchestrator with custom notification provider transports, custom concurrency options, and graceful process shutdown handlers.
## Prerequisites
- Node.js >= 22
- Running PostgreSQL and Redis instances (or environment variables `DATABASE_URL` and `REDIS_URL`)
## How to Run
```bash
# Set environment variables (optional if running locally with defaults)
export DATABASE_URL="postgresql://platform:platform@localhost:5432/notifkit"
export REDIS_URL="redis://localhost:6379"
# Run the server example
node index.js
```
+59
View File
@@ -0,0 +1,59 @@
import { NotifkitServer } from 'notifkit';
/**
* Example Custom Email Transport Provider
*/
class CustomEmailTransport {
constructor() {
this.channel = 'email';
}
async send(task) {
console.log(`[CustomEmailTransport] Sending notification to ${task.recipient.email}...`);
// Simulate async network request to email gateway
await new Promise((resolve) => setTimeout(resolve, 100));
return {
success: true,
providerMessageId: `custom-msg-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`,
};
}
}
async function main() {
console.log('🚀 Starting custom Notifkit Server example...');
const server = new NotifkitServer({
services: ['all'],
port: Number(process.env.PORT || 4000),
logLevel: process.env.LOG_LEVEL || 'info',
redisUrl: process.env.REDIS_URL,
databaseUrl: process.env.DATABASE_URL,
workerConcurrency: 50,
providers: [
new CustomEmailTransport(),
],
});
try {
await server.start();
console.log('✅ Notifkit Server started successfully on port 4000.');
// Graceful shutdown handling
const shutdown = async (signal) => {
console.log(`\n🛑 Received ${signal}, stopping Notifkit Server...`);
await server.stop();
console.log('👋 Server stopped cleanly.');
process.exit(0);
};
process.once('SIGINT', () => shutdown('SIGINT'));
process.once('SIGTERM', () => shutdown('SIGTERM'));
} catch (error) {
console.error('❌ Failed to start Notifkit Server:', error);
process.exit(1);
}
}
main();
+14
View File
@@ -0,0 +1,14 @@
# High-Throughput Load Test Example
This example measures request throughput and latency for the Notifkit REST API ingestion pipeline.
## How to Run
```bash
export NOTIFKIT_API_URL="http://localhost:4000"
export ADMIN_API_KEY="your_admin_api_key"
export COUNT=1000
export CONCURRENCY=100
node index.js
```
+61
View File
@@ -0,0 +1,61 @@
import { NotifkitClient } from 'notifkit';
/**
* Load testing example for measuring Notifkit pipeline throughput.
*/
async function runLoadTest() {
const baseUrl = process.env.NOTIFKIT_API_URL || 'http://localhost:4000';
const apiKey = process.env.ADMIN_API_KEY || 'your_admin_api_key';
const totalNotifications = Number(process.env.COUNT || 500);
const concurrency = Number(process.env.CONCURRENCY || 50);
const client = new NotifkitClient({ baseUrl, apiKey });
console.log(`⚡ Starting load test: ${totalNotifications} notifications (Concurrency: ${concurrency})...`);
const startTime = Date.now();
let completed = 0;
let failed = 0;
const queue = Array.from({ length: totalNotifications }, (_, i) => ({
template: 'benchmark-template',
channels: ['email'],
user: {
id: `bench-user-${i % 100}`,
email: `bench-user-${i % 100}@example.com`,
},
data: { index: i },
}));
async function worker() {
while (queue.length > 0) {
const item = queue.pop();
if (!item) break;
try {
await client.notify(item);
completed++;
} catch (err) {
failed++;
}
}
}
const workers = Array.from({ length: concurrency }, () => worker());
await Promise.all(workers);
const elapsedMs = Date.now() - startTime;
const throughputSec = (completed / (elapsedMs / 1000)).toFixed(2);
console.log(`\n📊 Load Test Results:`);
console.log(` - Total Processed: ${completed + failed}`);
console.log(` - Successful: ${completed}`);
console.log(` - Failed: ${failed}`);
console.log(` - Elapsed Time: ${elapsedMs} ms`);
console.log(` - Throughput: ${throughputSec} req/sec`);
}
runLoadTest().catch((err) => {
console.error('❌ Error executing load test:', err);
process.exit(1);
});
@@ -0,0 +1,12 @@
# Scheduled Notifications & Quiet Hours Example
This example demonstrates how to schedule future notification delivery (`sendAt`) and enforce recipient timezone-aware quiet hours deferrals.
## How to Run
```bash
export NOTIFKIT_API_URL="http://localhost:4000"
export ADMIN_API_KEY="your_admin_api_key"
node index.js
```
+53
View File
@@ -0,0 +1,53 @@
import { NotifkitClient } from 'notifkit';
/**
* Example demonstrating scheduled and quiet-hours aware notification delivery.
*/
async function runScheduledNotificationsExample() {
const client = new NotifkitClient({
baseUrl: process.env.NOTIFKIT_API_URL || 'http://localhost:4000',
apiKey: process.env.ADMIN_API_KEY || 'your_admin_api_key',
});
console.log('🔄 Syncing template...');
await client.syncTemplates({
templates: [
{
id: 'scheduled-reminder',
channel: 'email',
content: {
subject: 'Scheduled Meeting Reminder',
html: '<h3>Meeting Reminder</h3><p>Hi {{name}}, your meeting starts in 15 minutes.</p>',
text: 'Hi {{name}}, your meeting starts in 15 minutes.',
},
},
],
});
// Schedule notification for 10 minutes in the future
const sendAt = new Date(Date.now() + 10 * 60 * 1000).toISOString();
console.log(`⏰ Dispatching scheduled notification for ${sendAt}...`);
const response = await client.notify({
template: 'scheduled-reminder',
channels: ['email'],
user: {
id: 'user-2002',
email: 'alex@example.com',
timezone: 'America/New_York',
// Quiet hours live under `preferences`, and are a list of UTC windows.
preferences: {
quietHours: [{ start: '22:00', end: '08:00' }],
},
},
data: { name: 'Alex' },
sendAt,
});
console.log('✅ Scheduled notification response:', response);
}
runScheduledNotificationsExample().catch((err) => {
console.error('❌ Error executing scheduled notification example:', err);
process.exit(1);
});
+18
View File
@@ -0,0 +1,18 @@
# Multi-step Workflows Example
This example demonstrates how to define, sync, and trigger multi-step drip notification workflows using the `NotifkitClient` SDK.
## Workflow Structure
1. **Step 1**: Dispatches immediate welcome email (`onboarding-welcome`).
2. **Step 2**: Pauses execution using `wait` (`1h`).
3. **Step 3**: Dispatches follow-up email (`onboarding-followup`).
## How to Run
```bash
export NOTIFKIT_API_URL="http://localhost:4000"
export ADMIN_API_KEY="your_admin_api_key"
node index.js
```
+84
View File
@@ -0,0 +1,84 @@
import { NotifkitClient } from 'notifkit';
/**
* Example demonstrating multi-step notification workflows (Notify -> Wait -> Notify)
*/
async function runWorkflowExample() {
const client = new NotifkitClient({
baseUrl: process.env.NOTIFKIT_API_URL || 'http://localhost:4000',
apiKey: process.env.ADMIN_API_KEY || 'your_admin_api_key',
});
console.log('🔄 Syncing onboarding template...');
await client.syncTemplates({
templates: [
{
id: 'onboarding-welcome',
channel: 'email',
content: {
subject: 'Welcome to our Platform!',
html: '<h3>Hello {{name}}!</h3><p>Thank you for signing up.</p>',
text: 'Hello {{name}}! Thank you for signing up.',
},
},
{
id: 'onboarding-followup',
channel: 'email',
content: {
subject: 'Getting Started Tips',
html: '<h3>Tips for {{name}}</h3><p>Check out our documentation to get started.</p>',
text: 'Tips for {{name}}. Check out our documentation to get started.',
},
},
],
});
console.log('✅ Templates synced successfully.');
console.log('🔄 Registering multi-step workflow definition...');
// No step names a recipient: each one inherits the user the instance was
// triggered with, so the same definition serves every subscriber.
const workflow = await client.createWorkflow({
name: 'user-onboarding-drip',
steps: [
{
action: 'notify',
payload: {
template: 'onboarding-welcome',
channels: ['email'],
data: { name: 'Jane Doe' },
},
},
{
action: 'wait',
duration: '1h', // Wait 1 hour before next step
},
{
action: 'notify',
payload: {
template: 'onboarding-followup',
channels: ['email'],
data: { name: 'Jane Doe' },
},
},
],
});
console.log(`✅ Workflow registered: ${workflow.name}`);
console.log('🔄 Registering the recipient...');
await client.addUser({ id: 'user-1001', email: 'user@example.com' });
console.log('🚀 Triggering workflow execution for recipient...');
// input.user.id is who every notify step in this instance sends to.
const execution = await client.triggerWorkflow({
name: 'user-onboarding-drip',
input: { user: { id: 'user-1001' } },
});
console.log('🎉 Workflow triggered. Instance ID:', execution.instanceId);
}
runWorkflowExample().catch((err) => {
console.error('❌ Error executing workflow example:', err);
process.exit(1);
});