已解决:从MongoDB取邮箱并通过Nodemailer自动发邮件
问题已解决:已成功从MongoDB中获取邮箱地址,并向指定邮箱发送邮件。
我出于兴趣开发一个项目时,遇到了如下技术问题,曾寻求支持:从MongoDB中获取员工邮箱地址,并将其传递给Nodemailer以实现邮件自动触发。以下是相关代码文件内容:
数据模型(Schema)
const mongoose = require("mongoose"); const empschema = new mongoose.Schema({ FIRSTNAME :{ type: String, required : true }, LASTNAME :{ type: String, required : true }, EMAILADDRESS : { type: String, required : true }, EMPID : { type: Number, required : true, unique: true }, DEPARTMENT : { type: String, required : true }, DOB : { type : Date }, }) module.exports = mongoose.model("EmployeeData", empschema)
路由配置(Route)
//从MongoDB中获取当日过生日的员工数据 router.get("/getBirthday", getBirthday) //向员工发送生日邮件 router.post("/sendEmail/:id", sendEmail)
控制器(Controller)
//获取当日过生日的员工 async function getBirthday(req,res,next){ try { const employees = await EmployeeData.aggregate([ { $match: { $expr: { $and: [ { $eq: [{ $dayOfMonth: '$DOB' }, { $dayOfMonth: new Date() }] }, { $eq: [{ $month: '$DOB' }, { $month: new Date() }] }, ], }, } } ]).exec(function(error, items){ if(error){return next(error);} res.send(items) }) } catch(err){ throw err; } } //发送生日邮件 async function sendEmail(req, res) { const id = req.params.id const name = req.body.name; const email = req.body.email; sendEmailFunction(name, email) .then((result) => res.json(result)) .catch((error) => res.json(error.message)); }; //邮件发送函数 async function sendEmailFunction(name, email) { const CLIENT_EMAIL = process.env.MAIL_USERNAME; const CLIENT_ID = process.env.OAUTH_CLIENTID; const CLIENT_SECRET = process.env.OAUTH_CLIENT_SECRET; const REDIRECT_URI = process.env.REACT_APP_EMAIL_CLIENT_REDIRECT_URI; const REFRESH_TOKEN = process.env.OAUTH_REFRESH_TOKEN; const OAuth2Client = new google.auth.OAuth2( CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, ); OAuth2Client.setCredentials({ refresh_token: REFRESH_TOKEN }); try { //动态生成accessToken const accessToken = await OAuth2Client.getAccessToken(); //创建邮件传输对象 const transport = nodemailer.createTransport({ service: 'gmail', auth: { type: 'OAuth2', user: CLIENT_EMAIL, clientId: CLIENT_ID, clientSecret: CLIENT_SECRET, refreshToken: REFRESH_TOKEN, accessToken: accessToken, }, }); //配置邮件选项与内容 const mailOptions = { from: `<${CLIENT_EMAIL}>`, to: email, subject: `Sending email from code`, html: `${name} Enjoy learning!`, attachments: [ { filename: 'happyBirthday.png', //path: path.join(__dirname, `e-books-path/${name}.pdf`), //contentType: 'application/pdf', }, ], }; //发送邮件 const result = await transport.sendMail(mailOptions); return result; } catch (error) { return error; } }
前端组件(Birthday.js)
import React, { useState, useEffect } from 'react' import Swal from 'sweetalert2'; import BirthdayList from './BirthdayList'; import client from './axioscalls/api'; import {useAuthContext} from '../hooks/useAuthContext'; function Birthday() { const [employees, setEmployees] = useState([]); const {user} = useAuthContext(); function getUsers() { client.get('/api/employee/getBirthday', { headers : { 'Authorization' : `Bearer ${user.token}` } }) .then((response) => { setEmployees(response.data); }); } useEffect(() => { if(user){ getUsers(); } },[]); const handleBirthdayEmail = (id) => { if(!user){ return } try{ Swal.fire({ icon: 'warning', title: '确定要发送吗?', text: "此操作无法撤销!", showCancelButton: true, confirmButtonText: '是,发送!', cancelButtonText: '否,取消!', }) .then(result => { if (result.value) { const [employee] = employees.filter(employee => employee._id === id) const birthdayEmployee = { name : employee.FIRSTNAME, email : employee.EMAILADDRESS, } console.log(employee.EMAILADDRESS) client.post(`/api/employee/sendEmail/${id}`, birthdayEmployee, { headers : { 'Authorization' : `Bearer ${user.token}` } }) .then((response) => { Swal.fire({ icon: 'success', title: '发送成功!', text: `已向${employee.FIRSTNAME} ${employee.LASTNAME}发送生日祝福。`, showConfirmButton: true, //timer: 1500, }); }); }}) } catch(err) { console.log("无法向员工发送生日祝福:" +err.response) } } return ( <div className='container'> {/* 生日列表 */} {( <> <BirthdayList employees={employees} handleBirthdayEmail={handleBirthdayEmail} /> </> )} </div> ) } export default Birthday;
前端列表组件(BirthdayList.js)
import React from 'react' function BirthdayList({ employees, handleBirthdayEmail}) { return ( <div className='contain-table'> <table className='striped-table'> <thead> <tr> <th>序号</th> <th>MONGODBID</th> <th>名字</th> <th>姓氏</th> <th>邮箱地址</th> <th>员工ID</th> <th>部门</th> <th>出生日期</th> <th colSpan={3} className="text-center"> 操作 </th> </tr> </thead> <tbody> {employees.length > 0 ? ( employees.map((employee, i) => ( <tr key={i}> <td>{i+1}</td> <td>{employee._id}</td> <td>{employee.FIRSTNAME}</td> <td>{employee.LASTNAME}</td> <td>{employee.EMAILADDRESS}</td> <td>{employee.EMPID}</td> <td>{employee.DEPARTMENT} </td> <td>{employee.DOB} </td> <td className="text-left"> <button onClick={() => handleBirthdayEmail(employee._id)} className="button muted-button" > 发送生日祝福 </button> </td> </tr> )) ) : ( <tr> <td colSpan={10}>暂无员工数据</td> </tr> )} </tbody> </table> </div> ) } export default BirthdayList
内容的提问来源于stack exchange,提问作者Priyanka
相关产品推荐
相关产品推荐

