Openstatus
www.openstatus.dev
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}