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

示例代码:

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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/84491.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/84491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【同声传译】RealtimeSTT:超低延迟语音转文字,支持唤醒词与中译英

把你说的话实时变成文字&#xff1a;RealtimeSTT 上手体验 想找一个真正好用的语音转文字工具吗&#xff1f;不用等说完一整段才出结果&#xff0c;也不用反复点击按钮。RealtimeSTT 这个开源项目能做到​​实时​​转录&#xff0c;你说一句&#xff0c;屏幕上几乎同时出现文…

【大模型lora微调】关于推理时如何使用 LoRA Adapter

假设你有两部分&#xff1a; 一个是原始大模型&#xff08;base model&#xff09; 一个是保存的 LoRA Adapter&#xff08;adapter_config.json adapter_model.bin&#xff09; 不合并的情况下推理方法 你可以用 peft 的方式加载 LoRA Adapter&#xff0c;推理时这样写&a…

谷歌时间序列算法:零样本预测如何重塑行业决策?

谷歌时间序列算法&#xff1a;零样本预测如何重塑行业决策&#xff1f; TimesFM 你是否曾面临这样的困境&#xff1f;—— ▸ 需要预测新产品销量&#xff0c;却苦于缺乏历史数据&#xff1b; ▸ 依赖传统模型&#xff08;如ARIMA&#xff09;&#xff0c;但调参耗时且泛化能力…

国产服务器【银河麒麟v10】【CPU鲲鹏920】部署Minio文件服务器

目录 准备工作操作步骤1. 确认挂载点状态2. 创建专用用户和目录3. 下载ARM版Minio到挂在盘4. 环境变量配置5. 更新Systemd服务配置6. 启动、重启7. 防火墙8. 访问验证9. 故障排查&#xff08;如服务未启动&#xff09;​ 结束 准备工作 环境要求&#xff1a;Linux虚拟机 操作…

解决: React Native android webview 空白页

Android react-native-webview 之前是正常的, 升级了 react-native / react-native-webview 等 之后, 就变成了空白页. 通过下面的修改, 可以修复, 回到正常的状态. 来源: https://github.com/react-native-webview/react-native-webview/issues/3697 注意 ts 文件一定要改,…

高中编程教学中教师专业发展的困境与突破:基于实践与理论的双重审视

一、引言 1.1 研究背景 在数字化时代&#xff0c;编程已成为一项基本技能&#xff0c;其重要性日益凸显。编程不仅是计算机科学领域的核心能力&#xff0c;更是培养学生逻辑思维、创新能力和问题解决能力的有效途径。高中阶段作为学生成长和发展的关键时期&#xff0c;开展编…

最小化联邦平均(FedAvg)的算法开销

一、通信开销最小化 FedAvg中服务器与客户端间的频繁参数传输是主要瓶颈&#xff0c;可通过以下方法优化&#xff1a; 1. 模型压缩技术 稀疏化&#xff1a;仅上传重要参数更新&#xff08;如Top-k梯度&#xff09; 实现&#xff1a;客户端本地训练后&#xff0c;保留绝对值最…

准备开始适配高德Flutter的鸿蒙版了

我们的Flutter项目在编译为鸿蒙的过程中&#xff0c; 遇到了各种插件不支持的问题。 大部分都能解决&#xff0c;或者用别的方式代替。 这个高德我真的是无语&#xff0c; 我们只能用高德 &#xff0c; 目前还没看到网上有人适配了鸿蒙。 那就我来干吧&#xff0c; 第一…

webpack到vite的改造之路

前言 随着前端项目的持续迭代与功能扩展&#xff0c;当前基于 Webpack 构建的项目在启动速度、构建速度和首屏加载性能方面逐渐暴露出一些瓶颈。 一方面&#xff0c;Webpack 的打包机制导致本地开发环境的启动时间显著增加&#xff0c;严重影响了开发效率&#xff1b;另一方面…

【重构】如果发现提取的方法不再通用,如何重构

前言 所谓重构&#xff08;refactoring&#xff09;&#xff1a; 在不改变代码外在行为的前提下&#xff0c;对代码做出修改&#xff0c;以改进程序的内部结构。 – Martin Fowler背景 最近在做需求&#xff0c;需要对方法加权限控制&#xff0c;发现旧方法不再适用&#xff0…

REST接口/RPC

REST接口(RESTful API)是一种基于HTTP协议的API设计风格,遵循REST(Representational State Transfer表述性状态转移)架构原则,用于在不同系统之间进行数据交互。它具有简洁、灵活、无状态等特点,广泛应用于Web服务和移动应用开发中。 核心概念 资源导向 将数据或服务抽…

JS入门——事件与事件绑定

JS入门——事件与事件绑定 一、事件的分类 二、事件的绑定方式 实现代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title>JS事件绑定</title></head><body><!-- 修复后的按钮1 -->&…

pyspark 处理字符串函数

pyspark 要处理数据&#xff0c;没有&#xff0c;那就伪造数据 faker 真是个好东西 from faker import Faker import pandas as pd gender ["None","Man","Woman"]fake Faker() names [(fake.first_name(),fake.last_name(),fake.date_of_bi…

五大经典语音芯片型号及应用场景

在语音芯片领域&#xff0c;这五大语音芯片凭借丰富多样的产品和卓越的性能&#xff0c;占据了重要地位。以下为您详细介绍其五款经典语音芯片型号及其对应的应用场景。​ WTN6170-8S​ WTN6170-8S 属于 OTP 一次性语音芯片。它采用 OTP 工艺&#xff0c;成本能够控制在 1 元以…

机器学习管道:构建高效可靠的AI工作流

在当今数据驱动的世界中&#xff0c;机器学习(ML)已成为推动创新和决策的核心技术。然而&#xff0c;将ML模型从实验环境成功部署到生产环境并非易事。机器学习管道(ML Pipelines)作为一种系统化的解决方案&#xff0c;通过自动化工作流程&#xff0c;显著提高了ML项目的可重复…

浏览器调试核心技术指南:从基础到高级的完全掌握

引言​​ 在现代前端开发中,浏览器调试工具已成为开发者最强大的技术伙伴。根据State of JS 2023的统计数据,​​92.7%的专业开发者​​每天使用浏览器DevTools进行问题诊断和性能优化。然而,多数初级开发者仅能使用不到35%的调试功能。本文将系统解析Chrome/Firefox浏览器…

OpenCV 图像翻转

一、知识点 1、void flip(InputArray src, OutputArray dst, int flipCode); (1)、围绕x轴、y轴或两者同时翻转图像。 (2)、参数说明: src: 输入图像。 dst: 输出图像&#xff0c;大小与类型和src相同。 flipCode: 翻转标志。 0表示绕x轴翻转(上下翻转);…

【动手学深度学习】4.2~4.3 多层感知机的实现

目录 4.2. 多层感知机的从零开始实现1&#xff09;初始化模型参数2&#xff09;激活函数3&#xff09;模型4&#xff09;损失函数5&#xff09;训练 4.3. 多层感知机的简洁实现1&#xff09;模型2&#xff09;小结 . 4.2. 多层感知机的从零开始实现 现在让我们实现一个多层感…

54-Oracle 23 ai DBMS_HCHECK新改变-从前的hcheck.sql

Oracle Hcheck&#xff08;Health Check&#xff09;是Oracle数据库内置的健康监测工具&#xff0c;自动化检查数据库的核心问题&#xff0c;包括数据字典一致性、性能瓶颈、空间使用及安全隐患。本质是数据字典的CT扫描仪&#xff0c;其核心价值在于将“字典逻辑错误”这类灰色…

AI 产品的“嵌点”(Embedded Touchpoints)

核心主题&#xff1a; AI 产品的成功不在于功能的强大与独立&#xff0c;而在于其能否作为“嵌点”&#xff08;Embedded Touchpoints&#xff09;无缝融入用户现有的行为流&#xff08;Flow&#xff09;&#xff0c;消除微小摩擦&#xff0c;在用户真正需要的时机和场景中“无…