import { Resend } from "resend"; import { getSetting } from "./settings"; function getResend() { return new Resend(process.env.RESEND_API_KEY); } const FROM = process.env.EMAIL_FROM ?? "noreply@mailsend.second-brain.ru"; const BASE_URL = process.env.BETTER_AUTH_URL ?? "https://school.second-brain.ru"; async function getSchoolName() { return getSetting("schoolName"); } // ── HTML template (inline styles for maximum email client compatibility) ─────── function base(content: string, schoolName = "Second Brain") { return `
|
| ${label} → |
|
${text.replace(/\n/g, " |
Привет, ${name}!
Вам открыт доступ к курсу «${courseTitle}».
Перейдите на платформу чтобы начать обучение:
${btn(`${BASE_URL}/dashboard`, "Перейти к курсам")} `, school), }).catch((e) => console.error("[email] sendCourseAccessEmail:", e)); } export async function sendHomeworkSubmittedEmail( to: string, curatorName: string, studentName: string, lessonTitle: string, submissionId: string ) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Новая работа на проверку — ${lessonTitle}`, html: base(`Привет, ${curatorName}!
Студент ${studentName} сдал работу по уроку «${lessonTitle}».
Откройте работу чтобы проверить и оставить фидбек:
${btn(`${BASE_URL}/curator/homework/${submissionId}`, "Проверить работу")} `, school), }).catch((e) => console.error("[email] sendHomeworkSubmittedEmail:", e)); } export async function sendFeedbackReceivedEmail( to: string, studentName: string, lessonTitle: string, feedbackText: string, lessonUrl: string ) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Получен фидбек по уроку «${lessonTitle}»`, html: base(`Привет, ${studentName}!
Куратор проверил вашу работу по уроку «${lessonTitle}» и оставил обратную связь:
${quote(feedbackText)}Вернитесь к уроку чтобы увидеть полный фидбек:
${btn(lessonUrl, "Открыть урок")} `, school), }).catch((e) => console.error("[email] sendFeedbackReceivedEmail:", e)); } export async function sendWelcomeEmail(to: string, name: string) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Добро пожаловать в ${school}`, html: base(`Привет, ${name}!
Ваш аккаунт на образовательной платформе ${school} создан.
После того как администратор откроет вам доступ к курсу, вы получите письмо и сможете начать обучение.
${btn(`${BASE_URL}/dashboard`, "Перейти на платформу")} `, school), }).catch((e) => console.error("[email] sendWelcomeEmail:", e)); } export async function sendTestEmail(to: string) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Тест — ${school} LMS`, html: base(`Привет!
Это тестовое письмо от платформы ${school} LMS.
Так будут выглядеть все уведомления — доступ к курсу, фидбек по ДЗ и другие.
Если письмо отображается корректно, значит email-уведомления настроены и работают.
${btn(`${BASE_URL}/dashboard`, "Открыть платформу")} `, school), }).catch((e) => console.error("[email] sendTestEmail:", e)); } export async function sendAccessEmail( to: string, name: string, courseTitle: string, tempPassword: string ) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Доступ к курсу «${courseTitle}» открыт`, html: base(`Привет!
Вам открыт доступ к курсу «${courseTitle}» на образовательной платформе ${school}.
Ваши данные для входа:
${quote(`Логин: ${to}\nПароль: ${tempPassword}`)}После входа рекомендуем сразу сменить пароль в разделе «Профиль».
Если пароль не подходит — воспользуйтесь ссылкой «Забыли пароль?» на странице входа.
${btn(`${BASE_URL}/login`, "Войти на платформу")} `, school), }).catch((e) => console.error("[email] sendAccessEmail:", e)); } export async function sendPasswordResetEmail(to: string, name: string, resetUrl: string) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Сброс пароля — ${school}`, html: base(`Привет, ${name}!
Вы запросили сброс пароля для вашего аккаунта на платформе ${school}.
Нажмите на кнопку ниже чтобы задать новый пароль. Ссылка действительна 1 час.
Если вы не запрашивали сброс — просто проигнорируйте это письмо.
${btn(resetUrl, "Задать новый пароль")} `, school), }).catch((e) => console.error("[email] sendPasswordResetEmail:", e)); } export async function sendVerificationEmail(to: string, name: string, verifyUrl: string) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Подтвердите email — ${school}`, html: base(`Привет, ${name}!
Вы зарегистрировались на образовательной платформе ${school}.
Нажмите на кнопку ниже, чтобы подтвердить email и активировать аккаунт. Ссылка действительна 24 часа.
Если вы не регистрировались — просто проигнорируйте это письмо.
${btn(verifyUrl, "Подтвердить email")} `, school), }).catch((e) => console.error("[email] sendVerificationEmail:", e)); } export async function sendQuestionCreatedEmail( to: string, recipientName: string, studentName: string, questionTitle: string, ) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Новый вопрос от ${studentName}`, html: base(`Привет, ${recipientName}!
Студент ${studentName} задал новый вопрос:
${quote(questionTitle)}Откройте панель, чтобы ответить:
${btn(`${BASE_URL}/admin/questions`, "Перейти к вопросам")} `, school), }).catch((e) => console.error("[email] sendQuestionCreatedEmail:", e)); } export async function sendQuestionReplyEmail( to: string, studentName: string, questionTitle: string, questionId: string, ) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Ответ на ваш вопрос`, html: base(`Привет, ${studentName}!
Школа ответила на ваш вопрос:
${quote(questionTitle)}Откройте тред чтобы прочитать ответ:
${btn(`${BASE_URL}/questions/${questionId}`, "Читать ответ")} `, school), }).catch((e) => console.error("[email] sendQuestionReplyEmail:", e)); } export async function sendQuestionFollowUpEmail( to: string, recipientName: string, studentName: string, questionTitle: string, ) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Новый ответ от студента — ${questionTitle}`, html: base(`Привет, ${recipientName}!
Студент ${studentName} добавил сообщение в вопрос:
${quote(questionTitle)}Откройте панель, чтобы ответить:
${btn(`${BASE_URL}/admin/questions`, "Перейти к вопросам")} `, school), }).catch((e) => console.error("[email] sendQuestionFollowUpEmail:", e)); } export async function sendHomeworkUpdatedEmail( to: string, recipientName: string, studentName: string, lessonTitle: string, submissionId: string, ) { const school = await getSchoolName(); await getResend().emails.send({ from: FROM, to, subject: `Студент обновил работу — ${lessonTitle}`, html: base(`Привет, ${recipientName}!
Студент ${studentName} обновил работу по уроку «${lessonTitle}».
Откройте работу чтобы проверить изменения:
${btn(`${BASE_URL}/curator/homework/${submissionId}`, "Открыть работу")} `, school), }).catch((e) => console.error("[email] sendHomeworkUpdatedEmail:", e)); }