Openstatus www.openstatus.dev
at 4c0f4c00a38753a5d0dfd7e7b7b7706dec6f1503 47 lines 1.5 kB view raw
1import { and, gte, lte } from "@openstatus/db"; 2import { db } from "@openstatus/db"; 3import { user } from "@openstatus/db/src/schema"; 4import { EmailClient } from "@openstatus/emails"; 5import { env } from "../env"; 6// import { db } from "../lib/db"; 7 8const email = new EmailClient({ apiKey: env().RESEND_API_KEY }); 9 10export async function sendFollowUpEmails() { 11 // Get users created 2-3 days ago 12 const date1 = new Date(); 13 date1.setDate(date1.getDate() - 3); 14 const date2 = new Date(); 15 date2.setDate(date2.getDate() - 2); 16 17 const users = await db 18 .select({ 19 email: user.email, 20 }) 21 .from(user) 22 .where(and(gte(user.createdAt, date1), lte(user.createdAt, date2))) 23 .all(); 24 25 console.log(`Found ${users.length} users to send follow ups.`); 26 27 // Filter valid emails 28 const validEmails = users 29 .map((u) => u.email) 30 .filter((email) => email !== null) 31 // I don't know why but I can't have both filter at the same time 32 .filter((email) => email.trim() !== ""); 33 34 // Chunk emails into batches of 80 35 const batchSize = 80; 36 for (let i = 0; i < validEmails.length; i += batchSize) { 37 const batch = validEmails.slice(i, i + batchSize); 38 console.log(`Sending batch with ${batch.length} emails...`); 39 try { 40 await email.sendFollowUpBatched({ to: batch }); 41 } catch { 42 //Stop email send when rate limit error is faced in order to avoid wasteful API calls 43 console.error("Rate limit exceeded. Stopping further sends."); 44 break; 45 } 46 } 47}