feat:add email send functionality
This commit is contained in:
@@ -12,6 +12,7 @@ import candidateRoutes from "./routes/candidate.routes.js";
|
||||
import appointmentRoutes from "./routes/appointment.routes.js";
|
||||
import inquiryRoutes from "./routes/inquiry.routes.js";
|
||||
import academicsResearchRoutes from "./routes/academicsResearch.routes.js";
|
||||
import emailConfigRoutes from "./routes/emailConfig.routes.js";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@@ -47,6 +48,7 @@ app.use("/api/candidates", candidateRoutes);
|
||||
app.use("/api/appointments", appointmentRoutes);
|
||||
app.use("/api/inquiry", inquiryRoutes);
|
||||
app.use("/api/academics", academicsResearchRoutes);
|
||||
app.use("/api/email", emailConfigRoutes);
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
app.listen(PORT, () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import prisma from "../prisma/client.js";
|
||||
//CREATE APPOINTMENT
|
||||
import {sendEmail} from "../utils/sendEmail.js";
|
||||
import {getEmailsByType} from "../utils/getEmailByTypes.js";
|
||||
|
||||
export const createAppointment = async (req, res) => {
|
||||
try {
|
||||
@@ -29,6 +30,29 @@ export const createAppointment = async (req, res) => {
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const emailList = await getEmailsByType("APPOINTMENT");
|
||||
|
||||
if (emailList) {
|
||||
await sendEmail({
|
||||
to: emailList,
|
||||
subject: "New Appointment Booked",
|
||||
html: `
|
||||
<h2>New Appointment Booked</h2>
|
||||
<p><b>Name:</b> ${name}</p>
|
||||
<p><b>Phone:</b> ${mobileNumber}</p>
|
||||
<p><b>Email:</b> ${email || "-"}</p>
|
||||
<p><b>Doctor:</b> ${appointment.doctor?.name}</p>
|
||||
<p><b>Department:</b> ${appointment.department?.name}</p>
|
||||
<p><b>Date:</b> ${new Date(date).toLocaleDateString()}</p>
|
||||
<p><b>Message:</b> ${message || "-"}</p>
|
||||
`,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Email failed:", err);
|
||||
}
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: "Appointment booked successfully",
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
import prisma from "../prisma/client.js";
|
||||
|
||||
// CREATE
|
||||
export const createEmailConfig = async (req, res) => {
|
||||
try {
|
||||
const {name, email, type, isActive} = req.body;
|
||||
|
||||
if (!name || !email || !type) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "Name, Email and Type are required",
|
||||
});
|
||||
}
|
||||
|
||||
const newEmail = await prisma.emailConfig.create({
|
||||
data: {
|
||||
name,
|
||||
email,
|
||||
type,
|
||||
isActive: isActive ?? true,
|
||||
},
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: "Email config created",
|
||||
data: newEmail,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: "Failed to create email config",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//GET ALL
|
||||
export const getEmailConfigs = async (req, res) => {
|
||||
try {
|
||||
const emails = await prisma.emailConfig.findMany({
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: emails,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: "Failed to fetch email configs",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// GET SINGLE
|
||||
export const getEmailConfig = async (req, res) => {
|
||||
try {
|
||||
const {id} = req.params;
|
||||
|
||||
const email = await prisma.emailConfig.findUnique({
|
||||
where: {
|
||||
id: Number(id),
|
||||
},
|
||||
});
|
||||
|
||||
if (!email) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: "Email config not found",
|
||||
});
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: email,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: "Failed to fetch email config",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// UPDATE
|
||||
export const updateEmailConfig = async (req, res) => {
|
||||
try {
|
||||
const {id} = req.params;
|
||||
|
||||
const updated = await prisma.emailConfig.update({
|
||||
where: {
|
||||
id: Number(id),
|
||||
},
|
||||
data: req.body,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: "Email config updated",
|
||||
data: updated,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: "Failed to update email config",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// DELETE
|
||||
export const deleteEmailConfig = async (req, res) => {
|
||||
try {
|
||||
const {id} = req.params;
|
||||
|
||||
await prisma.emailConfig.delete({
|
||||
where: {
|
||||
id: Number(id),
|
||||
},
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: "Email config deleted",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: "Failed to delete email config",
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
import express from "express";
|
||||
import {
|
||||
getEmailConfigs,
|
||||
createEmailConfig,
|
||||
updateEmailConfig,
|
||||
deleteEmailConfig,
|
||||
} from "../controllers/emailConfig.controller.js";
|
||||
|
||||
import jwtAuthMiddleware from "../middleware/auth.js";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/getAll", getEmailConfigs);
|
||||
|
||||
router.post("/", jwtAuthMiddleware, createEmailConfig);
|
||||
router.put("/:id", jwtAuthMiddleware, updateEmailConfig);
|
||||
router.delete("/:id", jwtAuthMiddleware, deleteEmailConfig);
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,17 @@
|
||||
import prisma from "../prisma/client.js";
|
||||
|
||||
export const getEmailsByType = async (type) => {
|
||||
try {
|
||||
const emails = await prisma.emailConfig.findMany({
|
||||
where: {
|
||||
type,
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
return emails.map((e) => e.email).join(",");
|
||||
} catch (error) {
|
||||
console.error("Fetch email config error:", error);
|
||||
return "";
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import postmark from "postmark";
|
||||
|
||||
const client = new postmark.ServerClient(process.env.POSTMARK_API_KEY);
|
||||
|
||||
export const sendEmail = async ({to, subject, html, text}) => {
|
||||
try {
|
||||
await client.sendEmail({
|
||||
From: process.env.EMAIL_FROM,
|
||||
To: to,
|
||||
Subject: subject,
|
||||
HtmlBody: html,
|
||||
TextBody: text || "",
|
||||
MessageStream: "outbound",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Email send error:", error);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user