Webhook Implementation Guide
Webhooks provide real-time event notifications from the Nudj platform to your external systems, enabling seamless integration and automated workflows based on user engagement activities.
Settings Location : Navigate to Admin Panel → Settings → Developer → Webhooks to manage webhook endpoints and event subscriptions.
Webhook Overview
What are Webhooks?
Webhooks are HTTP callbacks that Nudj sends to your configured endpoints when specific events occur within your communities. They enable real-time data synchronization and automated response workflows.
Key Benefits:
Real-time event notifications
Automated workflow triggers
Reduced polling overhead
Decoupled system architecture
Scalable integration patterns
Event Types
User Events
User registration and profile updates
Login and authentication events
User status changes
Community membership changes
Engagement Events
Challenge starts and completions
Action participations and submissions
Reward earning and redemption
Achievement unlocks and progress
Community Events
Post creation and interactions
Comment submissions
Like and reaction events
Moderation actions
Administrative Events
Configuration changes
User management actions
Content creation and updates
System maintenance notifications
Webhook Configuration
Setting Up Webhook Endpoints
Endpoint Requirements
// Your webhook endpoint should:
// 1. Accept POST requests
// 2. Respond with 2xx status codes
// 3. Process requests within 10 seconds
// 4. Handle duplicate events idempotently
app . post ( '/webhooks/nudj' , ( req , res ) => {
const event = req . body ;
// Verify webhook signature
if ( ! verifySignature ( req )) {
return res . status ( 401 ). send ( 'Unauthorized' );
}
// Process event
processNudjEvent ( event );
// Respond quickly
res . status ( 200 ). send ( 'OK' );
});
Configuration via Admin API
const webhookConfig = {
url: 'https://your-domain.com/webhooks/nudj' ,
events: [
'user.registered' ,
'challenge.completed' ,
'reward.earned' ,
'achievement.unlocked'
],
authentication: {
type: 'signature' ,
secret: 'your-webhook-secret'
},
retryPolicy: {
maxRetries: 3 ,
backoffStrategy: 'exponential'
}
};
// Configure webhook
const response = await fetch ( 'https://api.nudj.cx/admin/webhooks/configs' , {
method: 'PUT' ,
headers: {
'Authorization' : 'Bearer your-admin-token' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( webhookConfig )
});
Authentication & Security
Signature Verification
const crypto = require ( 'crypto' );
function verifySignature ( req ) {
const signature = req . headers [ 'x-nudj-signature' ];
const payload = JSON . stringify ( req . body );
const secret = process . env . NUDJ_WEBHOOK_SECRET ;
const expectedSignature = crypto
. createHmac ( 'sha256' , secret )
. update ( payload )
. digest ( 'hex' );
return signature === `sha256= ${ expectedSignature } ` ;
}
Security Best Practices
Always verify webhook signatures
Use HTTPS endpoints only
Implement rate limiting
Store webhook secrets securely
Log all webhook events for debugging
Event Processing
Event Structure
Standard Event Format
{
"id" : "evt_1234567890abcdef" ,
"type" : "challenge.completed" ,
"timestamp" : "2024-01-15T10:30:00Z" ,
"organizationId" : "org_12345" ,
"communityId" : "com_67890" ,
"data" : {
"challengeId" : "chal_abcdef" ,
"userId" : "user_123456" ,
"completedAt" : "2024-01-15T10:29:45Z" ,
"score" : 85 ,
"timeToComplete" : 120 ,
"actionsCompleted" : 5
},
"metadata" : {
"source" : "web" ,
"version" : "1.0" ,
"retryCount" : 0
}
}
Event Processing Patterns
async function processNudjEvent ( event ) {
const { type , data , organizationId , communityId } = event ;
switch ( type ) {
case 'user.registered' :
await handleUserRegistration ( data );
break ;
case 'challenge.completed' :
await handleChallengeCompletion ( data );
break ;
case 'reward.earned' :
await handleRewardEarned ( data );
break ;
case 'achievement.unlocked' :
await handleAchievementUnlocked ( data );
break ;
default :
console . log ( `Unhandled event type: ${ type } ` );
}
}
Idempotency Handling
Duplicate Event Protection
const processedEvents = new Set ();
function isEventProcessed ( eventId ) {
return processedEvents . has ( eventId );
}
function markEventProcessed ( eventId ) {
processedEvents . add ( eventId );
// Consider using database storage for persistence
}
async function processNudjEvent ( event ) {
if ( isEventProcessed ( event . id )) {
console . log ( `Event ${ event . id } already processed` );
return ;
}
try {
await handleEvent ( event );
markEventProcessed ( event . id );
} catch ( error ) {
console . error ( `Error processing event ${ event . id } :` , error );
// Don't mark as processed to allow retry
}
}
Common Integration Patterns
CRM Integration
Salesforce Integration
async function handleUserRegistration ( userData ) {
const sfClient = new SalesforceClient ();
try {
// Create or update contact in Salesforce
const contact = await sfClient . createContact ({
Email: userData . email ,
FirstName: userData . firstName ,
LastName: userData . lastName ,
Nudj_User_ID__c: userData . userId ,
Engagement_Score__c: userData . initialScore
});
console . log ( `Created Salesforce contact: ${ contact . Id } ` );
} catch ( error ) {
console . error ( 'Salesforce integration error:' , error );
}
}
async function handleChallengeCompletion ( challengeData ) {
const sfClient = new SalesforceClient ();
try {
// Update engagement metrics
await sfClient . updateContact ( challengeData . userId , {
Last_Challenge_Completed__c: new Date (),
Total_Challenges_Completed__c: challengeData . totalCompleted ,
Engagement_Score__c: challengeData . newScore
});
} catch ( error ) {
console . error ( 'Challenge completion sync error:' , error );
}
}
Marketing Automation
Email Campaign Triggers
async function handleAchievementUnlocked ( achievementData ) {
const emailClient = new EmailMarketingClient ();
try {
// Trigger congratulatory email
await emailClient . sendTemplate ({
templateId: 'achievement-congratulations' ,
recipient: achievementData . userEmail ,
variables: {
userName: achievementData . userName ,
achievementName: achievementData . achievementName ,
badgeUrl: achievementData . badgeImageUrl ,
communityName: achievementData . communityName
}
});
// Add to achievement segment
await emailClient . addToSegment (
achievementData . userEmail ,
'high-achievers'
);
} catch ( error ) {
console . error ( 'Email automation error:' , error );
}
}
Analytics & Reporting
Custom Analytics Integration
async function handleEngagementEvent ( eventData ) {
const analyticsClient = new CustomAnalyticsClient ();
try {
await analyticsClient . track ({
event: eventData . type ,
userId: eventData . userId ,
properties: {
communityId: eventData . communityId ,
timestamp: eventData . timestamp ,
value: eventData . data . score || 0 ,
category: 'engagement'
}
});
} catch ( error ) {
console . error ( 'Analytics tracking error:' , error );
}
}
Advanced Implementation
Batch Processing
Event Queue Implementation
const EventQueue = require ( 'bull' );
const eventQueue = new EventQueue ( 'nudj events' );
// Add events to queue for batch processing
app . post ( '/webhooks/nudj' , ( req , res ) => {
eventQueue . add ( 'process-event' , req . body , {
attempts: 3 ,
backoff: 'exponential'
});
res . status ( 200 ). send ( 'Queued' );
});
// Process events in batches
eventQueue . process ( 'process-event' , async ( job ) => {
const event = job . data ;
await processNudjEvent ( event );
});
Error Handling & Monitoring
Comprehensive Error Handling
async function processNudjEvent ( event ) {
const logger = new Logger ({
service: 'nudj-webhook-handler' ,
eventId: event . id
});
try {
logger . info ( 'Processing event' , { type: event . type });
await handleEvent ( event );
logger . info ( 'Event processed successfully' );
} catch ( error ) {
logger . error ( 'Event processing failed' , {
error: error . message ,
stack: error . stack ,
eventData: event
});
// Send to dead letter queue or retry mechanism
await handleEventError ( event , error );
throw error ; // Re-throw to trigger webhook retry
}
}
Async Processing
async function handleHighVolumeEvents ( events ) {
const BATCH_SIZE = 10 ;
const batches = chunk ( events , BATCH_SIZE );
for ( const batch of batches ) {
await Promise . all (
batch . map ( event => processEventAsync ( event ))
);
}
}
async function processEventAsync ( event ) {
return new Promise (( resolve , reject ) => {
setTimeout ( async () => {
try {
await processNudjEvent ( event );
resolve ();
} catch ( error ) {
reject ( error );
}
}, 0 );
});
}
Testing & Debugging
Local Development Setup
Webhook Testing Environment
// Using ngrok for local development
const ngrok = require ( 'ngrok' );
async function setupLocalWebhooks () {
const url = await ngrok . connect ( 3000 );
console . log ( `Webhook tunnel: ${ url } /webhooks/nudj` );
// Update webhook configuration to use tunnel URL
await updateWebhookConfig ({
url: ` ${ url } /webhooks/nudj`
});
}
Webhook Simulation
// Test webhook handler with sample events
const sampleEvents = [
{
id: 'test_001' ,
type: 'challenge.completed' ,
timestamp: new Date (). toISOString (),
data: {
challengeId: 'test_challenge' ,
userId: 'test_user' ,
score: 100
}
}
];
async function testWebhookHandler () {
for ( const event of sampleEvents ) {
try {
await processNudjEvent ( event );
console . log ( `Event ${ event . id } processed successfully` );
} catch ( error ) {
console . error ( `Event ${ event . id } failed:` , error . message );
}
}
}
Monitoring & Maintenance
Health Monitoring
Webhook Health Checks
app . get ( '/webhooks/health' , ( req , res ) => {
const healthStatus = {
status: 'healthy' ,
timestamp: new Date (). toISOString (),
eventsProcessed: getEventCount (),
lastEventTime: getLastEventTime (),
errorRate: getErrorRate ()
};
res . json ( healthStatus );
});
Key Metrics to Track
Event processing latency
Success/failure rates
Queue depth and processing times
Error types and frequencies
Throughput (events per minute/hour)
Troubleshooting
Common Issues
Timeout Errors : Optimize processing time or use async patterns
Duplicate Events : Implement proper idempotency handling
Authentication Failures : Verify webhook secrets and signatures
High Error Rates : Check endpoint availability and error handling
Best Practices
Design Principles
Webhook Design Guidelines
Keep endpoints lightweight and fast
Use async processing for heavy operations
Implement proper error handling and retries
Log all events for debugging and auditing
Design for idempotency from the start
Security Considerations
Security Checklist
Verify all webhook signatures
Use HTTPS endpoints only
Implement rate limiting
Sanitize and validate event data
Store secrets securely
Monitor for suspicious activity
Scaling Considerations
High-Volume Handling
Use message queues for async processing
Implement horizontal scaling
Consider event batching for efficiency
Monitor and optimize database performance
Implement circuit breakers for external dependencies
Getting Started
Implementation Checklist
Setup Steps
Set up webhook endpoint infrastructure
Implement signature verification
Configure event types and filters
Test with sample events
Deploy to production
Monitor and optimize performance
Support Resources
Webhook Development Support Our developer support team provides assistance with webhook implementation, debugging, and optimization. Access our developer Slack channel for real-time support.
Next Steps
Ready to implement webhooks? Follow these steps:
Review your integration requirements
Set up your webhook endpoint infrastructure
Configure webhooks in the admin dashboard
Test with sample events
Deploy and monitor in production
Webhook API Reference For detailed API documentation and event schemas, see the Webhook API Reference section.