mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 00:03:23 +00:00
Add afterChange hook to auto-schedule jobs for pending emails
✨ Smart Job Scheduling: - Automatically creates processing jobs for pending emails - Prevents orphaned emails that bypass sendEmail() function - Checks for existing jobs to avoid duplicates - Respects scheduledAt for delayed sending - Handles both create and update operations intelligently 🔍 Logic: - Only triggers for emails with status 'pending' - Skips if email was already pending (prevents duplicate jobs) - Queries existing jobs to avoid creating duplicates - Uses mailing config queue or defaults to 'default' - Graceful error handling (logs but doesn't fail email operations) 📈 Benefits: - Complete email processing coverage - Works for emails created via admin interface - Handles manual status changes back to pending - Maintains scheduling for delayed emails - Zero-configuration auto-recovery
This commit is contained in:
@@ -183,6 +183,58 @@ const Emails: CollectionConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
hooks: {
|
||||||
|
afterChange: [
|
||||||
|
async ({ doc, previousDoc, req, operation }) => {
|
||||||
|
// Only process if this is a pending email and we have jobs configured
|
||||||
|
if (doc.status !== 'pending' || !req.payload.jobs) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if this is an update and status didn't change to pending
|
||||||
|
if (operation === 'update' && previousDoc?.status === 'pending') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check if a processing job already exists for this email
|
||||||
|
const existingJobs = await req.payload.find({
|
||||||
|
collection: 'payload-jobs',
|
||||||
|
where: {
|
||||||
|
'input.emailId': {
|
||||||
|
equals: String(doc.id),
|
||||||
|
},
|
||||||
|
task: {
|
||||||
|
equals: 'process-email',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
limit: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
// If no job exists, create one
|
||||||
|
if (existingJobs.totalDocs === 0) {
|
||||||
|
const mailingContext = (req.payload as any).mailing
|
||||||
|
const queueName = mailingContext?.config?.queue || 'default'
|
||||||
|
|
||||||
|
await req.payload.jobs.queue({
|
||||||
|
queue: queueName,
|
||||||
|
task: 'process-email',
|
||||||
|
input: {
|
||||||
|
emailId: String(doc.id)
|
||||||
|
},
|
||||||
|
// If scheduled, set the waitUntil date
|
||||||
|
waitUntil: doc.scheduledAt ? new Date(doc.scheduledAt) : undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(`Auto-scheduled processing job for email ${doc.id}`)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to auto-schedule job for email ${doc.id}:`, error)
|
||||||
|
// Don't throw - we don't want to fail the email creation/update
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
timestamps: true,
|
timestamps: true,
|
||||||
// indexes: [
|
// indexes: [
|
||||||
// {
|
// {
|
||||||
|
|||||||
Reference in New Issue
Block a user