[英]Nodemailer Nextjs Typescript form not sending emails
我正在使用Next.js
Typescript
和Nodemailer
开展个人项目。 这是我第一次使用Nodemailer
。 我在使它工作时遇到问题。 我正在关注本教程。 这是我在下面的代码,因为它在教程中。
Nodemailer.ts
:在这里我不得不替换any
类型的APIResponse
,因为代码给了我错误, VSCode
建议我在文件底部创建该函数。 此外,此文件的位置是/pages/api/nodemailer.ts
import { NextApiHandler, NextApiRequest } from "next";
import nodemailer from "nodemailer";
type Fields = {
name: string;
message: string;
email: string;
};
const transporter = nodemailer.createTransport({
service: 'hotmail',
auth: {
user: process.env.NEXT_PUBLIC_EMAIL_ADDRESS,
pass: process.env.NEXT_PUBLIC_PASSWORD,
},
});
export const config = {
api: {
bodyParser: false,
},
};
const handler: NextApiHandler<any> = async(req, res) => {
if (req.method !== "POST") {
return res.status(404).send({ error: "Begone." });
}
res.setHeader("Content-Type", "application/json")
try {
const { fields } = await formidablePromise(req, {});
const { name, email, message } = fields;
if (!name || !name.trim()) {
throw new Error("Please provide a valid name.");
}
if (!email || !email.trim()) {
throw new Error("Please provide a valid email address.");
}
if (!message || !message.trim()) {
throw new Error("Please provide a valid email message.");
}
await transporter.sendMail({
to: 'info@someemail.com.au',
from: 'info@someemail.com.au',
replyTo: email,
subject: `Hello from ${name}`,
text: message,
html: `<p>${message.replace(/(?:\r\n|\r|\n)/g, "<br>")}</p>`,
});
res.status(200).json({});
} catch (error) {
res.status(500).json({ error: error });
}
}
export default handler;
function formidablePromise(req: NextApiRequest, arg1: {}): { fields: any; } | PromiseLike<{ fields: any; }> {
throw new Error("Function not implemented.");
}
Form.tsx
:它在/components/Form.tsx
import { FaFacebook, FaTwitter } from 'react-icons/fa';
import React, { ChangeEvent, FormEvent, useRef, useState } from 'react';
import styles from './Form.module.css';
export interface FormProps {
result: boolean
isChecked: boolean
callTime: {time: string, isChecked: boolean}[]
loading: boolean
}
const Form: React.FC<FormProps> = () => {
const [loading, setLoading] = useState<boolean>(false)
const [name, setName] = useState<string>("");
const [email, setEmail] = useState<string>("");
const [mobile, setMobile] = useState<string | number | any>("");
const [message, setMessage] = useState<string>("");
console.log('NAme:', name, ', email', email, ', mobile', mobile, ', message', message);
async function sendEmail(event: FormEvent) {
event.preventDefault();
setLoading(true);
try {
const formData = new FormData();
if (!name.trim()) {
throw new Error("Please provide a valid name.");
}
if (!email.trim()) {
throw new Error("Please provide a valid email address.");
}
if (!mobile.trim()) {
throw new Error("Please provide a valid mobile number.");
}
if (!message.trim()) {
throw new Error("Please provide a valid message.");
}
formData.append("name", name);
formData.append("email", email);
formData.append("mobile", mobile);
formData.append("message", message);
console.log('form data', formData);
const response = await fetch("/api/nodemailer", {
method: "POST",
body: formData,
});
const responseData = await response.json();
console.log('form responseData', responseData);
if (responseData.error) {
throw new Error(responseData.error);
}
console.log("Thanks, we will be in touch soon!");
setName("");
setEmail("");
setMobile("");
setMessage("");
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
}
console.log('send email', sendEmail);
return (
<>
<div className={styles.wrapper}>
<form
onSubmit={sendEmail}
className={styles.formContainer}>
<h3>Get <span>in</span> touch</h3>
<label>Full Name<span className={styles.required}>*</span></label>
<input
type="text"
name="name"
required
value={name}
onChange={({ target }: ChangeEvent) => setName(( target as HTMLInputElement ).value)}
/>
<div className={styles.twoInputs}>
<div className={styles.innerInputs}>
<label>Email</label>
<input
type="email"
name="email"
pattern=".+@.+\..+"
value={email}
onChange={({ target }: ChangeEvent) => setEmail(( target as HTMLInputElement ).value)}
/>
</div>
<div className={styles.innerInputs}>
<label>Mobile<span className={styles.required}>*</span></label>
<input
type="tel"
name="tel"
required
value={mobile}
onChange={({ target }: ChangeEvent) => setMobile((target as HTMLInputElement ).value)} />
</div>
</div>
<label>Message<span className={styles.required}>*</span></label>
<textarea
name="message"
rows={6}
required
value={message}
maxLength={1000}
onChange={({ target }: ChangeEvent) => setMessage(( target as HTMLInputElement ).value)}
/>
<input type="submit" value="Send" />
<small><span className={styles.required}>*</span>Required</small>
</form>
</div>
</>
)
}
export default Form;
目前我在浏览器网络上遇到错误 500,但是当我打开链接时,错误引用了Nodemailer.ts
处理程序“ Begone ”的 404。 任何帮助都会非常感谢它。
首先,您需要安装@types/nodemailer作为 devDependencies。
在Form.tsx中,您尝试发送常规对象(类)而不是 JSON。 您必须使用JSON.stringify()序列化数据,还可以在此处添加标头。 为简化起见,您可以直接将值(状态)放入 JSON.stringify() 。 并删除所有formData 。
const response = await fetch('/api/nodemailer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, email, mobile, message }), // Serialize JSON
});
我删除了强大的Promise()函数,因为我们从处理函数和req.body 接收和处理所有数据。
import { NextApiResponse, NextApiRequest } from 'next';
import nodemailer from 'nodemailer';
type Fields = {
name: string;
message: string;
mobile: string;
email: string;
};
type Response = {
error?: string;
status?: string;
message?: string;
};
const transporter = nodemailer.createTransport({
service: 'hotmail',
auth: {
user: process.env.NEXT_PUBLIC_EMAIL_ADDRESS,
pass: process.env.NEXT_PUBLIC_PASSWORD,
},
});
//export const config = {
// api: {
// bodyParser: false,
// },
//};
const handler = async (req: NextApiRequest, res: NextApiResponse<Response>) => {
const { name, email, message } = req.body as Fields;
if (req.method !== 'POST') {
return res.status(404).send({ status: 'fail', error: 'Begone.' });
}
try {
if (!name || !name.trim()) {
throw new Error('Please provide a valid name.');
}
if (!email || !email.trim()) {
throw new Error('Please provide a valid email address.');
}
if (!message || !message.trim()) {
throw new Error('Please provide a valid email message.');
}
await transporter.sendMail({
to: 'info@someemail.com.au',
from: 'info@someemail.com.au',
replyTo: email,
subject: `Hello from ${name}`,
text: message,
html: `<p>${message.replace(/(?:\r\n|\r|\n)/g, '<br>')}</p>`,
});
res.status(200).send({ status: 'done', message: 'message has been sent' });
} catch (error) {
res.status(500).send({ status: 'fail', error: `${error}` });
}
};
export default handler;
这适用于我的 nodemailer Gmail选项。
export const config = {api: {bodyParser: false}}
我有LOGIN而不是PLAIN因为我的.env中有其他值,你需要检查你的.env 。 如果没问题,在第二步中,创建一个应用密码,因为您不能使用与登录相同的密码。
此外,您可以在此处找到有关“PLAIN”缺少凭据的答案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.