mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 08:13:23 +00:00
Remove email outbox collection and process job; refactor email templates with rich text support and slug generation
This commit is contained in:
75
dev/app/api/create-test-user/route.ts
Normal file
75
dev/app/api/create-test-user/route.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { getPayload } from 'payload'
|
||||
import config from '@payload-config'
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const payload = await getPayload({ config })
|
||||
const body = await request.json()
|
||||
|
||||
// Generate random user data if not provided
|
||||
const userData = {
|
||||
email: body.email || `user-${Date.now()}@example.com`,
|
||||
password: body.password || 'TestPassword123!',
|
||||
firstName: body.firstName || 'Test',
|
||||
lastName: body.lastName || 'User',
|
||||
}
|
||||
|
||||
// Create the user
|
||||
const user = await payload.create({
|
||||
collection: 'users',
|
||||
data: userData,
|
||||
})
|
||||
|
||||
// Check if email was queued
|
||||
await new Promise(resolve => setTimeout(resolve, 500)) // Brief delay for email processing
|
||||
|
||||
const { docs: emails } = await payload.find({
|
||||
collection: 'emails' as const,
|
||||
where: {
|
||||
to: {
|
||||
equals: userData.email,
|
||||
},
|
||||
},
|
||||
limit: 1,
|
||||
sort: '-createdAt',
|
||||
})
|
||||
|
||||
return Response.json({
|
||||
success: true,
|
||||
user: {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
},
|
||||
emailQueued: emails.length > 0,
|
||||
email: emails.length > 0 ? {
|
||||
id: emails[0].id,
|
||||
subject: emails[0].subject,
|
||||
status: emails[0].status,
|
||||
} : null,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error creating test user:', error)
|
||||
return Response.json(
|
||||
{
|
||||
error: 'Failed to create user',
|
||||
details: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
return Response.json({
|
||||
message: 'Use POST to create a test user',
|
||||
example: {
|
||||
email: 'optional@example.com',
|
||||
password: 'optional',
|
||||
firstName: 'optional',
|
||||
lastName: 'optional',
|
||||
},
|
||||
note: 'All fields are optional. Random values will be generated if not provided.',
|
||||
})
|
||||
}
|
||||
75
dev/app/api/process-emails/route.ts
Normal file
75
dev/app/api/process-emails/route.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { getPayload } from 'payload'
|
||||
import config from '@payload-config'
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const payload = await getPayload({ config })
|
||||
|
||||
// Queue the combined email queue processing job
|
||||
const job = await payload.jobs.queue({
|
||||
task: 'process-email-queue',
|
||||
input: {},
|
||||
})
|
||||
|
||||
return Response.json({
|
||||
success: true,
|
||||
message: 'Email queue processing job queued successfully (will process both pending and failed emails)',
|
||||
jobId: job.id,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Process emails error:', error)
|
||||
return Response.json(
|
||||
{
|
||||
error: 'Failed to process emails',
|
||||
details: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const payload = await getPayload({ config })
|
||||
|
||||
// Get email queue statistics
|
||||
const pending = await payload.count({
|
||||
collection: 'emails' as const,
|
||||
where: { status: { equals: 'pending' } },
|
||||
})
|
||||
|
||||
const processing = await payload.count({
|
||||
collection: 'emails' as const,
|
||||
where: { status: { equals: 'processing' } },
|
||||
})
|
||||
|
||||
const sent = await payload.count({
|
||||
collection: 'emails' as const,
|
||||
where: { status: { equals: 'sent' } },
|
||||
})
|
||||
|
||||
const failed = await payload.count({
|
||||
collection: 'emails' as const,
|
||||
where: { status: { equals: 'failed' } },
|
||||
})
|
||||
|
||||
return Response.json({
|
||||
statistics: {
|
||||
pending: pending.totalDocs,
|
||||
processing: processing.totalDocs,
|
||||
sent: sent.totalDocs,
|
||||
failed: failed.totalDocs,
|
||||
total: pending.totalDocs + processing.totalDocs + sent.totalDocs + failed.totalDocs,
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Get email stats error:', error)
|
||||
return Response.json(
|
||||
{
|
||||
error: 'Failed to get email statistics',
|
||||
details: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
86
dev/app/api/test-email/route.ts
Normal file
86
dev/app/api/test-email/route.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { getPayload } from 'payload'
|
||||
import config from '@payload-config'
|
||||
import { sendEmail, scheduleEmail } from '@xtr-dev/payload-mailing'
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const payload = await getPayload({ config })
|
||||
const body = await request.json()
|
||||
const { type = 'send', templateSlug, to, variables, scheduledAt } = body
|
||||
|
||||
let result
|
||||
if (type === 'send') {
|
||||
// Send immediately
|
||||
result = await sendEmail(payload, {
|
||||
templateSlug,
|
||||
to,
|
||||
variables,
|
||||
})
|
||||
} else if (type === 'schedule') {
|
||||
// Schedule for later
|
||||
result = await scheduleEmail(payload, {
|
||||
templateSlug,
|
||||
to,
|
||||
variables,
|
||||
scheduledAt: scheduledAt ? new Date(scheduledAt) : new Date(Date.now() + 60000), // Default to 1 minute
|
||||
})
|
||||
} else {
|
||||
return Response.json({ error: 'Invalid type. Use "send" or "schedule"' }, { status: 400 })
|
||||
}
|
||||
|
||||
return Response.json({
|
||||
success: true,
|
||||
emailId: result,
|
||||
message: type === 'send' ? 'Email sent successfully' : 'Email scheduled successfully',
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Test email error:', error)
|
||||
return Response.json(
|
||||
{
|
||||
error: 'Failed to send email',
|
||||
details: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const payload = await getPayload({ config })
|
||||
|
||||
// Get email templates
|
||||
const { docs: templates } = await payload.find({
|
||||
collection: 'email-templates' as const,
|
||||
limit: 10,
|
||||
})
|
||||
|
||||
// Get email queue status
|
||||
const { docs: queuedEmails, totalDocs } = await payload.find({
|
||||
collection: 'emails' as const,
|
||||
limit: 10,
|
||||
sort: '-createdAt',
|
||||
})
|
||||
|
||||
return Response.json({
|
||||
templates,
|
||||
outbox: {
|
||||
emails: queuedEmails,
|
||||
total: totalDocs,
|
||||
},
|
||||
mailing: {
|
||||
pluginActive: !!(payload as any).mailing,
|
||||
service: !!(payload as any).mailing?.service,
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Get mailing status error:', error)
|
||||
return Response.json(
|
||||
{
|
||||
error: 'Failed to get mailing status',
|
||||
details: error instanceof Error ? error.message : 'Unknown error'
|
||||
},
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user