fix: batch email sending in message system to avoid overloading SMTP
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m27s
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m27s
Messages were sent in a tight for-loop with no throttling. Now uses sendBatchNotifications (10/batch, 150ms per email, 500ms between batches) and fires in the background so the admin gets instant response. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,8 @@ import { TRPCError } from '@trpc/server'
|
||||
import { router, protectedProcedure, adminProcedure } from '../trpc'
|
||||
import { logAudit } from '@/server/utils/audit'
|
||||
import { sendStyledNotificationEmail, getEmailPreviewHtml } from '@/lib/email'
|
||||
import { sendBatchNotifications } from '../services/notification-sender'
|
||||
import type { NotificationItem } from '../services/notification-sender'
|
||||
|
||||
export const messageRouter = router({
|
||||
/**
|
||||
@@ -68,7 +70,7 @@ export const messageRouter = router({
|
||||
},
|
||||
})
|
||||
|
||||
// If not scheduled, deliver immediately for EMAIL channel
|
||||
// If not scheduled, deliver immediately for EMAIL channel (batched to avoid overloading SMTP)
|
||||
if (!isScheduled && input.deliveryChannels.includes('EMAIL')) {
|
||||
const users = await ctx.prisma.user.findMany({
|
||||
where: { id: { in: recipientUserIds } },
|
||||
@@ -77,23 +79,25 @@ export const messageRouter = router({
|
||||
|
||||
const baseUrl = process.env.NEXTAUTH_URL || 'https://portal.monaco-opc.com'
|
||||
|
||||
for (const user of users) {
|
||||
try {
|
||||
await sendStyledNotificationEmail(
|
||||
user.email,
|
||||
user.name || '',
|
||||
'MESSAGE',
|
||||
{
|
||||
const items: NotificationItem[] = users.map((user) => ({
|
||||
email: user.email,
|
||||
name: user.name || '',
|
||||
type: 'MESSAGE',
|
||||
userId: user.id,
|
||||
context: {
|
||||
name: user.name || undefined,
|
||||
title: input.subject,
|
||||
message: input.body,
|
||||
linkUrl: `${baseUrl}/messages`,
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
console.error(`[Message] Failed to send email to ${user.email}:`, error)
|
||||
}
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
// Fire-and-forget: batch send in background so the mutation returns quickly
|
||||
sendBatchNotifications(items).then((result) => {
|
||||
console.log(`[Message] Batch ${result.batchId}: ${result.sent} sent, ${result.failed} failed`)
|
||||
}).catch((err) => {
|
||||
console.error('[Message] Batch send error:', err)
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user