From 2e77d4625ac8f4e8a4e13b62d3d4a9384de9c4e0 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 1 Jun 2025 14:33:10 -0700 Subject: [PATCH] feat(email): add customizable "FROM" email for resend (#447) * add customizable from email on resend via envvar * use existing getBaseDomain utility --- apps/sim/app/api/help/route.ts | 9 +++++---- apps/sim/app/api/workspaces/invitations/route.ts | 3 ++- apps/sim/lib/auth.ts | 7 ++++--- apps/sim/lib/mailer.ts | 5 +++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/sim/app/api/help/route.ts b/apps/sim/app/api/help/route.ts index 0edb77d61..34f96fce3 100644 --- a/apps/sim/app/api/help/route.ts +++ b/apps/sim/app/api/help/route.ts @@ -3,6 +3,7 @@ import { Resend } from 'resend' import { z } from 'zod' import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console-logger' +import { getBaseDomain } from '@/lib/urls/utils' const resend = env.RESEND_API_KEY ? new Resend(env.RESEND_API_KEY) : null const logger = createLogger('HelpAPI') @@ -98,8 +99,8 @@ ${message} // Send email using Resend const { data, error } = await resend.emails.send({ - from: 'Sim Studio ', - to: ['help@simstudio.ai'], + from: `Sim Studio `, + to: [`help@${getBaseDomain()}`], subject: `[${type.toUpperCase()}] ${subject}`, replyTo: email, text: emailText, @@ -121,7 +122,7 @@ ${message} // Send confirmation email to the user await resend.emails .send({ - from: 'Sim Studio ', + from: `Sim Studio `, to: [email], subject: `Your ${type} request has been received: ${subject}`, text: ` @@ -137,7 +138,7 @@ ${images.length > 0 ? `You attached ${images.length} image(s).` : ''} Best regards, The Sim Studio Team `, - replyTo: 'help@simstudio.ai', + replyTo: `help@${getBaseDomain()}`, }) .catch((err) => { logger.warn(`[${requestId}] Failed to send confirmation email`, err) diff --git a/apps/sim/app/api/workspaces/invitations/route.ts b/apps/sim/app/api/workspaces/invitations/route.ts index cc3952dff..8576341a8 100644 --- a/apps/sim/app/api/workspaces/invitations/route.ts +++ b/apps/sim/app/api/workspaces/invitations/route.ts @@ -7,6 +7,7 @@ import { WorkspaceInvitationEmail } from '@/components/emails/workspace-invitati import { getSession } from '@/lib/auth' import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console-logger' +import { getBaseDomain } from '@/lib/urls/utils' import { db } from '@/db' import { user, workspace, workspaceInvitation, workspaceMember } from '@/db/schema' @@ -228,7 +229,7 @@ async function sendInvitationEmail({ } await resend.emails.send({ - from: 'noreply@simstudio.ai', + from: `noreply@${getBaseDomain()}`, to, subject: `You've been invited to join "${workspaceName}" on Sim Studio`, html: emailHtml, diff --git a/apps/sim/lib/auth.ts b/apps/sim/lib/auth.ts index 7350f1ea6..f837d41c0 100644 --- a/apps/sim/lib/auth.ts +++ b/apps/sim/lib/auth.ts @@ -17,6 +17,7 @@ import { createLogger } from '@/lib/logs/console-logger' import { db } from '@/db' import * as schema from '@/db/schema' import { env } from './env' +import { getBaseDomain } from './urls/utils' const logger = createLogger('Auth') @@ -145,7 +146,7 @@ export const auth = betterAuth({ const html = await renderPasswordResetEmail(username, url) const result = await resend.emails.send({ - from: 'Sim Studio ', + from: `Sim Studio `, to: user.email, subject: getEmailSubject('reset-password'), html, @@ -187,7 +188,7 @@ export const auth = betterAuth({ // In production, send an actual email const result = await resend.emails.send({ - from: 'Sim Studio ', + from: `Sim Studio `, to: data.email, subject: getEmailSubject(data.type), html, @@ -1077,7 +1078,7 @@ export const auth = betterAuth({ ) await resend.emails.send({ - from: 'Sim Studio ', + from: `Sim Studio `, to: invitation.email, subject: `${inviterName} has invited you to join ${organization.name} on Sim Studio`, html, diff --git a/apps/sim/lib/mailer.ts b/apps/sim/lib/mailer.ts index dbf4c3242..8958e735b 100644 --- a/apps/sim/lib/mailer.ts +++ b/apps/sim/lib/mailer.ts @@ -1,6 +1,7 @@ import { Resend } from 'resend' import { createLogger } from '@/lib/logs/console-logger' import { env } from './env' +import { getBaseDomain } from './urls/utils' interface EmailOptions { to: string @@ -41,7 +42,7 @@ export async function sendEmail({ from, }: EmailOptions): Promise { try { - const senderEmail = from || 'noreply@simstudio.ai' + const senderEmail = from || `noreply@${getBaseDomain()}` if (!resend) { logger.info('Email not sent (Resend not configured):', { @@ -89,7 +90,7 @@ export async function sendBatchEmails({ emails, }: BatchEmailOptions): Promise { try { - const senderEmail = 'noreply@simstudio.ai' + const senderEmail = `noreply@${getBaseDomain()}` const results: SendEmailResult[] = [] if (!resend) {