Rate-limited notifications — send emails/SMS without exceeding limits.
1const BullMQ = require("bullmq");23class NotificationService {4 constructor() {5 this.emailQueue = new BullMQ.Queue("emails", {6 limiter: {7 max: 100, // max jobs8 duration: 60000, // per minute9 },10 });1112 this.smsQueue = new BullMQ.Queue("sms", {13 limiter: {14 max: 10,15 duration: 60000,16 },17 });18 }1920 async sendEmail(to, subject, body) {21 return this.emailQueue.add("send", {22 to, subject, body,23 }, {24 attempts: 3,25 backoff: { type: "exponential", delay: 5000 },26 });27 }2829 async sendSMS(to, message) {30 return this.smsQueue.add("send", { to, message });31 }32}3334// Consumer35const emailWorker = new BullMQ.Worker("emails", async (job) => {36 const { to, subject, body } = job.data;37 await transporter.sendMail({ from: "noreply@app.com", to, subject, html: body });38});3940// Per-user rate limiting41const userLimits = new Map();4243async function canSend(userId, type, maxPerHour) {44 const key = `${userId}:${type}`;45 const count = userLimits.get(key) || 0;46 if (count >= maxPerHour) return false;47 userLimits.set(key, count + 1);48 return true;49}5051app.post("/notify", async (req, res) => {52 if (!await canSend(req.user.id, "email", 10)) {53 return res.status(429).json({ error: "Too many notifications" });54 }55 await notificationService.sendEmail(req.user.email, "Update", "New content");56 res.json({ sent: true });57});