NodeJS 对接 Outlook 发信服务器实现发信功能

发布于:2025-06-20 ⋅ 阅读:(21) ⋅ 点赞:(0)

示例代码:

const express = require('express');
const nodemailer = require('nodemailer');
const querystring = require('querystring');
const axios = require('axios');

const app = express();
app.use(express.json());

const transporter = nodemailer.createTransport({
    service: 'Outlook365', // 也可以用 'hotmail'
    auth: {
        type: 'OAuth2',
        user: 'sdkflja_ggg@outlook.com',
        clientId: '21f97687-903e-4806-903f-7c3162f73cea',
        clientSecret: 'Brp8Q~qBdngo.SLNfJbc83YgtPqnKnrgHuBq.c8f',
        refreshToken: 'M.C543_BL2.0.U.-CkdUriBwl1MEcv2WRP5ZLo2tVbmA0Lhgzn18IVcqhM8ZBrzEDTHng8FhWoByDcQpYyskZVKdRFjAzqAx5qjjx5NKpsahbm5P12VD9cPcX2f30ckbxTXeCmbcngguSbxx6SX7uumH2iPWZxS0HVsLXMhnxgnkNEW8dixb90jgc7uHQC!*lV1y8QjZbQNxzBucCSTDOIFuNIjM7k6UYC2lgjZPjvaQl66S1xXJp2YRoJ6w4KPwQ0zlOOUMLS7jpwLYEyUOHnzYPY5bCpk2bBhoE0xE6c0k*THxGsfN5xF2xJXyEVIJNUn!JRcsnpsQcPB1N1ggVpkf8fWVzeMgUECC7So!UKhLJbVZBNQldjUwoTH*yDMuGvo8SnIdmMELE1Wmlpb0JlSlTpgvTV*v*YTyesA$',
        accessToken: 'EwAIBOl3BAAUcDnR9grBJokeAHaUV8R3+rVHX+IAAf5LCOGj2z3+BP5D2doOw+E2jHHTT6tpaipG3TaJWxypwgJM68oAQ+t2441dbub+DUmJYTjRCAFSrxDSlVyapKUNRcknLCZEvfJ4dVCTK9IEksaY5MFq/3YlEU4FyJivTh8aLiUXKppmRQLPBPVhQF9ypsbwcWCLrcHLvaT0WJM2JW5Uq0nWA/KVwzcZSKymn8qNiiU1bt5KlkogbDNMzegjvTOPoKSCPok/R46IoJzBMoENRQlCt+W60HT94XF0hATWMl9kXUCqknuHORnZevGC1H4ECX9aTPS3qsmS182ZaigRx6rntfMrh1BaY2x5OlSbW/VUyfKlxvInCMBjMmEQZgAAEJKxntheAOYGkeSTC51dDVDQArKGCk757MKV9hFX8z0Sw8A6IQmh/Zxghe2PNL+q2JiX7wup/U1NvjoRaRESIlpToB8x+GZ+zzW4KNj7mUFM96Rb4ae1Vh19tqjLr0SP3kIv3g6+ybpoj7Xv2vEOav2xA7pPGshkGH7dYapBOYSee5tjV2ZZqIwt5HLz/nPuOpkkaoqx5jRmVK0F5q+Hcd8J7RmQwJKp77ff6dYRo+JZ0zlfPr9pNiYkQ4Q+eH/8ddm8DtGnOI2uWUN1JLEIGJvJ7J3S6d+et7QUPgMIuvXlzJS7G0wZ0xNLMFE9lKl4ugSQH0zCuspFA4tirivbYc74FP+VsI9Y4ZWMb22txcq44C2++O9bxrWXPiAZ0iC4fPtqTyGXAqeQkW/kDjEc+insAF8p/MLfH+JnhH1dhPijRXCI3bD3Mj9w4yySwBAvPeqEv3CYX/FsXQoSZbbUaVv1+0RRgHUWGPsCurBAjo+TK2a936CLe7KfXm0TbflLLPbrbCOJABDJ2JGQ3LiurJ8HpPlL1Xz7xtUOlvLooh4VINAGlGq7Kp1Dkj26ZN4ZGcjisWIHTTfVcon1VzCSn5e5xnqplWyexYlQwjwu/taXYdbzG4CZV8ENI8ppEN6rqIhmAfob+dwr7wvitDx9T/AzPtXEw6z5wFSUUnexedb0uB9sQEOll9KBPbyi6z0vv1lIpHJ+CM9cUTJe45zPcarhvGwktmwJjtUq893VxmXah/UFCWMFm7xxet7dUSLMOVsS3byjq0Aru212Q9DaWccH1iKeeUrGgBiIB+TeqydwOOSbZYBAT+5KFPYZBdttEaIsFd5QfahEU8HFeiqRgwZI4tNnmYK2DpoxCZnQJtE0oEJvCyAqOIaOF2a8HP/iYzPc/JV6RHhZCnW12JvLwojAxcCq0rul3OV+q8JJBQrlQcdh/9+R+ZZjke7bYjUnQvG3FnlJl/jMoJvkfEALvr70GQID'
    },
    host: 'smtp.office365.com',
    port: 587,
    secure: false,
});

// OAuth2 授权参数
const oauth2Config = {
    clientId: '21f97687-903e-4806-903f-7c3162f73cea',
    redirectUri: 'http://localhost:3000/oauth2/callback',
    scope: 'https://outlook.office.com/SMTP.Send offline_access',
    authUrl: 'https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize',
    tokenUrl: 'https://login.microsoftonline.com/consumers/oauth2/v2.0/token'
};

// 获取授权链接
app.get('/oauth2/authorize', (req, res) => {
    const params = querystring.stringify({
        client_id: oauth2Config.clientId,
        response_type: 'code',
        redirect_uri: oauth2Config.redirectUri,
        response_mode: 'query',
        scope: oauth2Config.scope,
        state: '12345' // 可自定义
    });
    const url = `${oauth2Config.authUrl}?${params}`;
    res.json({ url });
});

// 处理授权回调,获取refresh_token
app.get('/oauth2/callback', async (req, res) => {
    const code = req.query.code;
    if (!code) return res.status(400).send('缺少code参数');
    try {
        const params = new URLSearchParams({
            client_id: oauth2Config.clientId,
            scope: oauth2Config.scope,
            code,
            redirect_uri: oauth2Config.redirectUri,
            grant_type: 'authorization_code',
            client_secret: 'Brp8Q~qBdngo.SLNfJbc83YgtPqnKnrgHuBq.c8f'
        });
        const tokenRes = await axios.post(oauth2Config.tokenUrl, params, {
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
        });
        res.json({ refresh_token: tokenRes.data.refresh_token, access_token: tokenRes.data.access_token });
    } catch (err) {
        res.status(500).json({ error: err.message, detail: err.response?.data });
    }
});

app.get('/send', async (req, res) => {
    const { to, subject, text } = req.query;
    try {
        let info = await transporter.sendMail({
            from: '"TaxPlus" <sdkflja_ggg@outlook.com>',
            to,
            subject,
            text
        });
        res.json({ success: true, messageId: info.messageId });
    } catch (err) {
        res.status(500).json({ success: false, error: err.message  });
    }
});

app.listen(3000, () => {
    console.log('邮件服务器已启动,端口3000');
});

流程:

第一步、 用 node 执行这个 js 文件
访问 http://localhost:3000/oauth2/authorize   获取授权链接

 

 复制链接到浏览器登录账号进行授权,等待回调:

拿到 refresh_token 和 access_token 后,复制粘贴至图中此处:

第二步:

 访问 http://localhost:3000/send?to=to@example.com&subject=666&text=666  发送邮件

返回  messageId  就是成功了

主要是  OAuth2  的验证比较麻烦 

Outlook邮箱开通发信服务及OAuth2验证开通参考下面这个帖子:

Outlook邮箱开通发信服务及OAuth2验证开通-CSDN博客


网站公告

今日签到

点亮在社区的每一天
去签到