Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
2.7 kB ยท 97 lines
TypeScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798import { getLogger } from "@logtape/logtape";import { and, eq, gte, inArray, lte } from "@openstatus/db";import { db } from "@openstatus/db";import { integration, user, usersToWorkspaces,} from "@openstatus/db/src/schema";import { EmailClient } from "@openstatus/emails";
import { env } from "../env";
const logger = getLogger(["workflow", "emails"]);const email = new EmailClient({ apiKey: env().RESEND_API_KEY });
export async function sendFollowUpEmails() { const date1 = new Date(); date1.setDate(date1.getDate() - 2); const date2 = new Date(); date2.setDate(date2.getDate() - 1);
const users = await db .select({ email: user.email, workspaceId: usersToWorkspaces.workspaceId, }) .from(user) .innerJoin(usersToWorkspaces, eq(user.id, usersToWorkspaces.userId)) .where(and(gte(user.createdAt, date1), lte(user.createdAt, date2))) .all();
const workspaceIds = [ ...new Set(users.map((u) => u.workspaceId).filter(Boolean)), ];
const slackWorkspaceIds = new Set<number>(); if (workspaceIds.length > 0) { const slackIntegrations = await db .select({ workspaceId: integration.workspaceId }) .from(integration) .where( and( eq(integration.name, "slack-agent"), inArray(integration.workspaceId, workspaceIds), ), ) .all(); for (const row of slackIntegrations) { if (row.workspaceId) { slackWorkspaceIds.add(row.workspaceId); } } }
const slackEmails: string[] = []; const noSlackEmails: string[] = [];
for (const u of users) { if (!u.email || u.email.trim() === "") continue; const hasSlack = u.workspaceId ? slackWorkspaceIds.has(u.workspaceId) : false; if (hasSlack) { slackEmails.push(u.email); } else { noSlackEmails.push(u.email); } }
const batchSize = 80;
for (let i = 0; i < noSlackEmails.length; i += batchSize) { const batch = noSlackEmails.slice(i, i + batchSize); try { await email.sendFollowUpBatched({ to: batch }); } catch (error) { logger.error("Follow-up email batch failed", { batch_size: batch.length, error_name: error instanceof Error ? error.name : typeof error, }); break; } }
for (let i = 0; i < slackEmails.length; i += batchSize) { const batch = slackEmails.slice(i, i + batchSize); try { await email.sendSlackFeedbackBatched({ to: batch }); } catch (error) { logger.error("Slack feedback email batch failed", { batch_size: batch.length, error_name: error instanceof Error ? error.name : typeof error, }); break; } }}