fix(email): include course name in student welcome subject (#739)
* fix(email): include course name in student welcome subject The studentCourseWelcome template used a static subject, so bulk course assignments produced identical inbox titles. Resolve the subject from courseName at send time and sanitize it like other email headers. Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com> * fix(email): use course-only subject for student welcome email Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
This commit is contained in:
co-authored by
Rotimi Best
Cursor Agent
parent
51f90bf450
commit
8288f157b3
@@ -3,6 +3,7 @@ import * as z from 'zod';
|
||||
import type { EmailResponse } from '../utils/types';
|
||||
import type { SendTemplateConfig } from './types';
|
||||
import { deliverEmail } from '../send';
|
||||
import { sanitizeEmailSubject } from '../utils/functions/email-helpers';
|
||||
|
||||
/**
|
||||
* Send a single email using a template
|
||||
@@ -13,10 +14,14 @@ export async function sendTemplateEmail<TSchema extends z.ZodType>(
|
||||
): Promise<EmailResponse[]> {
|
||||
const content = config.template.render(config.fields);
|
||||
|
||||
const resolvedSubject =
|
||||
config.subject ??
|
||||
(typeof config.template.subject === 'function' ? config.template.subject(config.fields) : config.template.subject);
|
||||
|
||||
return deliverEmail([
|
||||
{
|
||||
to: config.to,
|
||||
subject: config.subject ?? config.template.subject,
|
||||
subject: sanitizeEmailSubject(resolvedSubject),
|
||||
content,
|
||||
from: config.from ?? config.template.from,
|
||||
replyTo: config.replyTo ?? config.template.replyTo,
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { EmailId } from '../utils/types';
|
||||
* Base email template interface
|
||||
*/
|
||||
export interface EmailTemplate<TSchema extends z.ZodType = z.ZodType> {
|
||||
subject: string;
|
||||
subject: string | ((fields: z.infer<TSchema>) => string);
|
||||
schema: TSchema;
|
||||
render: (fields: z.infer<TSchema>) => string;
|
||||
from?: string;
|
||||
@@ -47,7 +47,7 @@ export interface SendTemplateConfig<TSchema extends z.ZodType = z.ZodType> exten
|
||||
*/
|
||||
export interface DefineEmailConfig<TSchema extends z.ZodType = z.ZodType> {
|
||||
id: EmailId;
|
||||
subject: string;
|
||||
subject: string | ((fields: z.infer<TSchema>) => string);
|
||||
schema: TSchema;
|
||||
render: (fields: z.infer<TSchema>) => string;
|
||||
from?: string;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ZEmailBranding } from '../core/branding';
|
||||
|
||||
export const studentCourseWelcomeEmail = defineEmail({
|
||||
id: 'studentCourseWelcome',
|
||||
subject: 'You have access to a course — sign in to get started',
|
||||
subject: (fields) => `You have access to ${fields.courseName} course`,
|
||||
schema: z.object({
|
||||
orgName: z.string().min(1),
|
||||
courseName: z.string().min(1),
|
||||
|
||||
Reference in New Issue
Block a user