You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已解决:从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:33:17