Building an Email Scheduler with Node.js and React
In this blog post, we'll walk through how to build a simple email scheduler application using Node.js, Express, and React. This project demonstrates how to schedule and send emails with a user-friendly interface.
Project Overview
Our Email Scheduler application allows users to compose and schedule emails to be sent at specific times. It features a React frontend for the user interface and a Node.js backend for handling email sending and scheduling.
Tech Stack
Frontend: React
Backend: Node.js, Express
Email Service: Nodemailer
Scheduling: node-cron
Styling: Tailwind CSS
Setting Up the Backend
Install Dependencies
Install the required packages:
npm install express nodemon nodemailer dotenv cors node-cron
Create the Backend Code
Create a file named
server.js
in thebackend
directory and add the following code:import express from "express"; import nodemailer from "nodemailer"; import dotenv from "dotenv"; import cors from "cors"; import cron from "node-cron"; const app = express(); dotenv.config(); app.use(cors()); app.use(express.json()); app.post("/sendEmail", (req, res) => { const { name, email, subject, message } = req.body; const transporter = nodemailer.createTransport({ service: "Gmail", auth: { user: process.env.EMAIL_FROM, pass: process.env.EMAIL_PASS, }, }); const mailOptions = { from: process.env.EMAIL_FROM, to: email, subject: subject, text: `${message} sent by ${name}`, }; cron.schedule("0 9 * * *", () => { transporter.sendMail(mailOptions, (error, info) => { if (error) { console.log("Error occurred: ", error); } else { console.log("Email sent: " + info.response); } }); }); res.status(200).json({ message: "Email scheduled successfully" }); }); app.listen(5000, () => { console.log("Server is running on port 5000"); });
Create the
.env
FileCreate a
.env
file in thebackend
directory with the following content:EMAIL_FROM=your-email@gmail.com EMAIL_PASS=your-email-password
Replace
your-email@gmail.com
andyour-email-password
with your actual email credentials.
Setting Up the Frontend
Create the Frontend Code
Replace the code in src/App.js
with the following:
import { useState } from "react";
import "./App.css";
function App() {
const [form, setForm] = useState({
name: "",
fromMail: "",
toMail: "",
subject: "",
intro: "",
body: "",
footer: ""
});
const handleChange = (e) => {
const { name, value } = e.target;
setForm((prevForm) => ({
...prevForm,
[name]: value
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await fetch("http://localhost:5000/sendEmail", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(form)
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Error:", error);
}
};
return (
<div>
<h1 className="text-5xl font-semibold text-cyan-200 ml-3">Email Scheduler</h1>
<form
className="form p-6 max-w-full mx-auto text-white rounded-xl"
onSubmit={handleSubmit}
>
<h2 className="text-lg text-cyan-400 mb-4">Send a Mail to anyone</h2>
<div className="flex gap-4 mb-3">
<label className="relative w-full">
<input
type="text"
placeholder="Your Name"
name="name"
value={form.name}
onChange={handleChange}
required
className="input w-full p-3 bg-neutral-700 text-white rounded-lg border border-neutral-600 focus:border-cyan-400 outline-none mb-1"
/>
</label>
<label className="relative w-full">
<input
type="email"
placeholder="Your Email"
name="fromMail"
value={form.fromMail}
onChange={handleChange}
required
className="input w-full p-3 bg-neutral-700 text-white rounded-lg border border-neutral-600 focus:border-cyan-400 outline-none"
/>
</label>
<p className="text-cyan-400 mt-3 text-lg">To</p>
<label className="relative w-full">
<input
type="email"
placeholder="Receiver Email"
name="toMail"
value={form.toMail}
onChange={handleChange}
required
className="input w-full p-3 bg-neutral-700 text-white rounded-lg border border-neutral-600 focus:border-cyan-400 outline-none"
/>
</label>
</div>
<div className="flex gap-4">
<p className="text-cyan-400 mt-2 text-lg">Subject</p>
<label className="relative mb-4 w-full">
<input
type="text"
placeholder="Subject"
name="subject"
value={form.subject}
onChange={handleChange}
required
className="input w-full p-3 bg-neutral-700 text-white rounded-lg border border-neutral-600 focus:border-cyan-400 outline-none"
/>
</label>
</div>
<div className="flex gap-4">
<p className="text-cyan-400 mt-2 text-lg">Intro</p>
<label className="relative mb-3 w-full">
<input
type="text"
placeholder="Email"
name="intro"
value={form.intro}
onChange={handleChange}
required
className="input w-full p-3 bg-neutral-700 text-white rounded-lg border border-neutral-600 focus:border-cyan-400 outline-none"
/>
</label>
</div>
<div className="flex gap-4">
<p className="text-cyan-400 mt-2 text-lg">Body</p>
<label className="relative mb-3 w-full">
<textarea
type="text"
placeholder="Email"
name="body"
value={form.body}
onChange={handleChange}
required
className="textarea w-full p-3 bg-neutral-700 text-white rounded-lg border border-neutral-600 focus:border-cyan-400 outline-none textarea-lg"
rows={3}
></textarea>
</label>
</div>
<div className="flex gap-4">
<p className="text-cyan-400 mt-2 text-lg">Footer</p>
<label className="relative mb-3 w-full">
<input
type="text"
placeholder="Email"
name="footer"
value={form.footer}
onChange={handleChange}
required
className="input w-full p-3 bg-neutral-700 text-white rounded-lg border border-neutral-600 focus:border-cyan-400 outline-none"
/>
</label>
</div>
<button
type="submit"
className="submit w-full p-3 bg-cyan-400 text-white rounded-lg hover:bg-cyan-500 transition-transform duration-300 ease-in-out transform active:scale-95 active:shadow-lg"
>
Send
</button>
</form>
</div>
);
}
export default App;
Conclusion
In this tutorial, we’ve built a basic email scheduler application using Node.js, Express, and React. We’ve covered setting up the backend server to handle email sending and scheduling, as well as creating a React frontend to interact with
Subscribe to my newsletter
Read articles from Rishabh Raj Verma directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Rishabh Raj Verma
Rishabh Raj Verma
I’m a Full-Stack Developer skilled in the MERN stack with a strong understanding of Machine Learning. I enjoy building responsive web applications and using AI to solve problems. I’m always excited to learn new technologies and apply them to create innovative solutions.