Reputation: 1
I want to create a Nodemailer frontend-backend app to send fully customizable email templates. I try to fetch the resource from:
'use client'
import React, { useState } from "react";
export default function Compose() {
const [emailData, setEmailData] = useState({
from: '',
to: '',
subject: '',
message: '',
attachments: [],
});
const handleChange = (e) => {
const { name, value } = e.target;
setEmailData({ ...emailData, [name]: value });
};
const handleFileChange = (e: { target: { files: any; }; }) => {
setEmailData({ ...emailData, attachments: [...e.target.files] });
};
const sendEmail = async () => {
try {
const formData = new FormData();
formData.append('from', emailData.from);
formData.append('to', emailData.to);
formData.append('subject', emailData.subject);
formData.append('message', emailData.message);
emailData.attachments.forEach((file) => formData.append("attachments", file));
console.log("Sending data:", formData);
const response = await fetch('http://localhost:5000/send-email', {
method: 'POST',
body: formData,
});
if (response.ok) {
alert("Email sent successfully");
} else {
alert('Failed to send the email');
}
} catch (error) {
console.error('Error sending email', error);
}
};
return (
<div className="w-full bg-gray-100 py-2 px-4 absolute top-20 left-1 rounded-lg shadow-lg">
<p className="text-lg font-semibold">New Message</p>
<div className="border-b-2 border-gray-300 my-2"></div>
<input
className="w-full p-2 border-b-2 border-gray-400 bg-transparent outline-none focus:border-blue-500"
placeholder="From"
name='from'
value={emailData.from}
onChange={handleChange}
/>
<input
className="w-full p-2 border-b-2 border-gray-400 bg-transparent outline-none focus:border-blue-500"
placeholder="To"
name='to'
value={emailData.to}
onChange={handleChange}
/>
<input
className="w-full p-2 border-b-2 border-gray-400 bg-transparent outline-none focus:border-blue-500"
placeholder="Subject"
name='subject'
value={emailData.subject}
onChange={handleChange}
/>
<textarea
placeholder="Compose your email..."
className="w-full h-40 p-2 mt-2 border rounded-md outline-none resize-none"
name='message'
value={emailData.message}
onChange={handleChange}
></textarea>
<div className="p-4 flex justify-end">
<button className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700" onClick={sendEmail}>
Send
</button>
</div>
</div>
);
}
As you can see I try to fetch the resource from (const response = await fetch('http://localhost:5000/send-email',) but it return a error in the the nodemailer app "Error: Missing credentials for "PLAIN" and I can't fetch the resource from my nodemailer.js. What you guys can recommend me to do?
import express from "express";
import multer from "multer";
import nodemailer from "nodemailer";
import cors from "cors";
import dotenv from "dotenv";
dotenv.config(); // Load environment variables
const app = express();
app.use(express.urlencoded({ extended: true })); // To parse URL-encoded bodies
// CORS setup to allow requests from your frontend
app.use(cors({
origin: 'http://192.168.1.6:3000', // Allow this origin (adjust to match your client URL)
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
}));
const upload = multer(); // Memory storage (adjust as needed)
app.post("/send-email", upload.array("attachments"), async (req, res) => {
const { from, to, subject, message } = req.body;
const attachments = req.files.map((file) => ({
filename: file.originalname,
content: file.buffer, // Use buffer instead of path
}));
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587, // Port for STARTTLS
secure: false, // Use false for STARTTLS
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASSWORD, // Ensure app password here if using 2FA
},
tls: {
rejectUnauthorized: false, // Disable certificate validation (useful for dev)
},
});
const mailOptions = {
from: from, // Dynamic 'from' field from the request body
to: to, // Dynamic 'to' field from the request body
subject: subject, // Dynamic 'subject' field from the request body
text: message, // Dynamic 'message' field from the request body
attachments: attachments, // Attachments if provided
};
try {
await transporter.sendMail(mailOptions);
res.status(200).send("Email Sent!");
} catch (error) {
console.error(error);
res.status(500).send("Error sending email");
}
});
app.listen(5000, () => console.log("Server running on port 5000"));
Upvotes: -1
Views: 35