@akson/chatsuite-sdk
Version:
Production-ready TypeScript SDK for ChatSuite - WhatsApp automation with built-in session management, message queuing, webhook server, and database sync
281 lines (235 loc) ⢠8.22 kB
text/typescript
/**
* Message Queue Example
*
* Demonstrates advanced message queuing features:
* - Rate limiting and retry logic
* - Priority queuing
* - Bulk operations
* - Queue monitoring
*
* Run: npx ts-node examples/message-queue.ts
*/
import { MessageQueue, RateLimiter } from '../src/index';
async function messageQueueExample() {
console.log('š¬ Message Queue Example');
// Create a message queue with advanced configuration
const queue = new MessageQueue({
name: 'demo-queue',
concurrency: 3, // Process 3 messages concurrently
maxAttempts: 5,
retryDelay: 2000, // 2 seconds base delay
retryBackoff: 'exponential', // 2s, 4s, 8s, 16s...
timeout: 30000, // 30 second timeout per message
// Rate limiting: 10 messages per minute
rateLimit: {
max: 10,
window: 60000, // 1 minute
keyGenerator: (context) => {
// Rate limit per recipient
return context.recipient || 'global';
}
},
// Message processor function
processor: async (item) => {
const { type, recipient, message, delay } = item.data;
console.log(`š Processing: ${type} to ${recipient} (attempt ${item.attempts})`);
// Simulate processing time
if (delay) {
await new Promise(resolve => setTimeout(resolve, delay));
}
// Simulate different message types
switch (type) {
case 'text':
return simulateTextMessage(recipient, message);
case 'media':
return simulateMediaMessage(recipient, message);
case 'bulk':
return simulateBulkMessage(recipient, message);
default:
throw new Error(`Unknown message type: ${type}`);
}
},
// Batch processing for efficiency
enableBatch: false, // Set to true for batch processing
batchSize: 10,
batchDelay: 5000
});
// Event handlers for monitoring
queue.on('job:added', (item) => {
console.log(`ā Job added: ${item.id} (priority: ${item.priority})`);
});
queue.on('job:started', (item) => {
console.log(`š Job started: ${item.id} (${item.data.type})`);
});
queue.on('job:completed', (item, result) => {
console.log(`ā
Job completed: ${item.id} - ${result.status}`);
});
queue.on('job:failed', (item, error) => {
console.log(`ā Job failed: ${item.id} - ${error.message}`);
});
queue.on('job:retry', (item, attempt) => {
console.log(`š Job retry: ${item.id} (attempt ${attempt}/${item.maxAttempts})`);
});
queue.on('rate:limit', (key, limit) => {
console.log(`š« Rate limited: ${key} (${limit.max}/${limit.window}ms)`);
});
queue.on('queue:idle', () => {
console.log('š“ Queue is idle');
});
// Start the queue
console.log('Starting message queue...');
queue.start();
console.log('ā
Message queue started');
// Add various message types with different priorities
console.log('\nš¤ Adding messages to queue...');
// High priority urgent messages
await queue.add({
type: 'text',
recipient: '+1234567890',
message: 'URGENT: Critical system alert!',
delay: 1000
}, 10); // Highest priority
await queue.add({
type: 'text',
recipient: '+0987654321',
message: 'URGENT: Please respond immediately',
delay: 1000
}, 10);
// Normal priority messages
for (let i = 1; i <= 5; i++) {
await queue.add({
type: 'text',
recipient: `+111222333${i}`,
message: `Normal priority message ${i}`,
delay: 2000
}, 5); // Medium priority
}
// Low priority bulk messages
await queue.addBulk({
recipients: ['+1111111111', '+2222222222', '+3333333333', '+4444444444'],
message: { text: 'This is a bulk notification' },
delay: 1000,
priority: 1, // Low priority
metadata: { campaign: 'newsletter' }
});
// Media messages (slower processing)
await queue.add({
type: 'media',
recipient: '+5555555555',
message: {
url: 'https://example.com/image.jpg',
caption: 'Check out this image!'
},
delay: 5000 // Simulate slower media processing
}, 7); // High priority
// Simulate messages that will fail
await queue.add({
type: 'invalid',
recipient: '+9999999999',
message: 'This will fail',
delay: 1000
}, 3);
// Monitor queue statistics
const statsInterval = setInterval(() => {
const stats = queue.getStats();
console.log('\nš Queue Statistics:');
console.log(` Pending: ${stats.pending}`);
console.log(` Processing: ${stats.processing}`);
console.log(` Completed: ${stats.completed}`);
console.log(` Failed: ${stats.failed}`);
console.log(` Total: ${stats.total}`);
console.log(` Throughput: ${stats.throughput.toFixed(2)} items/sec`);
// Show queue items by status
const pendingItems = queue.getItems('pending');
const processingItems = queue.getItems('processing');
if (pendingItems.length > 0) {
console.log(` Next pending: ${pendingItems[0].data.type} (priority: ${pendingItems[0].priority})`);
}
if (processingItems.length > 0) {
console.log(` Currently processing: ${processingItems.map(i => i.data.type).join(', ')}`);
}
}, 5000); // Every 5 seconds
// Add more messages periodically
const addInterval = setInterval(async () => {
const messageTypes = ['text', 'media'];
const priorities = [1, 3, 5, 7, 10];
const recipients = ['+1111111111', '+2222222222', '+3333333333'];
const type = messageTypes[Math.floor(Math.random() * messageTypes.length)];
const priority = priorities[Math.floor(Math.random() * priorities.length)];
const recipient = recipients[Math.floor(Math.random() * recipients.length)];
await queue.add({
type,
recipient,
message: `Random ${type} message at ${new Date().toLocaleTimeString()}`,
delay: Math.random() * 3000
}, priority);
console.log(`š² Added random ${type} message (priority: ${priority})`);
}, 8000); // Every 8 seconds
console.log('\nš® Message queue demo running!');
console.log('Features demonstrated:');
console.log(' ā
Priority-based processing');
console.log(' ā
Rate limiting and throttling');
console.log(' ā
Retry logic with backoff');
console.log(' ā
Concurrent processing');
console.log(' ā
Real-time statistics');
console.log(' ā
Bulk operations');
console.log('\nPress Ctrl+C to stop...');
// Graceful shutdown
process.on('SIGINT', () => {
console.log('\nš Shutting down queue...');
clearInterval(statsInterval);
clearInterval(addInterval);
queue.stop();
console.log('ā
Queue stopped');
process.exit(0);
});
}
// Simulate message processing functions
async function simulateTextMessage(recipient: string, message: any) {
// Simulate API call delay
await new Promise(resolve => setTimeout(resolve, 500));
// Simulate occasional failures
if (Math.random() < 0.1) { // 10% failure rate
throw new Error('Network timeout');
}
return {
status: 'sent',
messageId: `msg_${Date.now()}`,
recipient,
timestamp: new Date().toISOString()
};
}
async function simulateMediaMessage(recipient: string, message: any) {
// Media messages take longer
await new Promise(resolve => setTimeout(resolve, 2000));
// Simulate occasional failures
if (Math.random() < 0.15) { // 15% failure rate for media
throw new Error('Media upload failed');
}
return {
status: 'sent',
messageId: `media_${Date.now()}`,
recipient,
mediaType: 'image',
timestamp: new Date().toISOString()
};
}
async function simulateBulkMessage(recipient: string, message: any) {
// Bulk processing
await new Promise(resolve => setTimeout(resolve, 300));
return {
status: 'sent',
messageId: `bulk_${Date.now()}`,
recipient,
timestamp: new Date().toISOString()
};
}
// Handle errors
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});
// Run the example
if (require.main === module) {
messageQueueExample().catch(console.error);
}
export { messageQueueExample };