Email Workflows
Common patterns for sending emails as background jobs.
Welcome Email
Send a welcome email when a user signs up:
jobs/send-welcome-email.ts
import { pidgey } from '@/lib/pidgey';
export const sendWelcomeEmail = pidgey.defineJob({
name: 'send-welcome-email',
handler: async (data: { userId: string; email: string }) => {
const user = await db.users.findById(data.userId);
await resend.emails.send({
to: data.email,
subject: `Welcome, ${user.name}!`,
template: 'welcome',
});
return { sent: true };
},
config: {
retries: 3,
timeout: 30000,
},
});app/actions/signup.ts
'use server';
import { sendWelcomeEmail } from '@/jobs/send-welcome-email';
export async function signup(formData: FormData) {
const email = formData.get('email') as string;
const user = await db.users.create({ email });
// Send welcome email in background
await sendWelcomeEmail.enqueue({
userId: user.id,
email: user.email,
});
return { success: true };
}Delayed Reminder
Send a follow-up email 24 hours after signup:
await sendFollowUpEmail.enqueue(
{ userId: user.id },
{ delay: 24 * 60 * 60 * 1000 } // 24 hours
);Daily Digest
Use scheduled jobs for recurring emails:
jobs/daily-digest.ts
export const dailyDigest = pidgey.defineScheduledJob({
name: 'daily-digest',
handler: async () => {
const users = await db.users.findMany({ digestEnabled: true });
for (const user of users) {
const activity = await getActivitySummary(user.id);
await sendDigestEmail(user.email, activity);
}
},
schedule: {
cron: '0 9 * * *', // Every day at 9am
timezone: 'America/New_York',
},
});💡
Remember to call
pidgey.syncSchedules() at startup to register scheduled jobs.Bulk Email with Rate Limiting
Process emails in batches to avoid rate limits:
export const sendBulkEmail = pidgey.defineJob({
name: 'send-bulk-email',
handler: async (data: { emails: string[]; template: string }) => {
for (const email of data.emails) {
await resend.emails.send({
to: email,
template: data.template,
});
// Small delay between emails
await new Promise((r) => setTimeout(r, 100));
}
},
config: {
queue: 'bulk', // Separate queue for bulk operations
timeout: 600000, // 10 minute timeout
},
});Run bulk queue with lower concurrency:
npx pidgey worker start --queue bulk --concurrency 1