文章目录
- ⭐前言
- ⭐注册azure应用
- 💖添加权限
- ⭐调用npm 实现收发邮件
- 💖安装依赖
- 💖创建appSettings.js 放置密钥
- 💖创建graphHelper.js封装功能
- 💖主文件index.js 对外暴露
- 💖效果
- ⭐结束
⭐前言
大家好,我是yma16,本文分享 调用azure的npm实现outlook_api模拟查看邮件、发送邮件。
背景:
模拟outlook邮件客户端收发邮件
该系列往期文章:
前端笔记_OAuth规则机制下实现个人站点接入qq三方登录
OAuth机制_web站点接入微软azure账号进行三方登录
官网教程:
https://learn.microsoft.com/zh-cn/graph/tutorials/javascript?context=outlook%2Fcontext&tabs=aad
⭐注册azure应用
记住客户端id和租户id,验证使用
💖添加权限
身份验证打开允许客户端流
添加email api
⭐调用npm 实现收发邮件
💖安装依赖
安装官方身份验证库 @azure/identity
npm install @azure/identity @microsoft/microsoft-graph-client isomorphic-fetch readline-sync
💖创建appSettings.js 放置密钥
管理密钥文件appSettings.js
const settings = {'clientId': '应用客户端id','tenantId': '应用租户id','graphUserScopes': ['user.read','mail.read','mail.send']
};module.exports = settings;
💖创建graphHelper.js封装功能
graphHelper.js放置功能
require('isomorphic-fetch');
const azure = require('@azure/identity');
const graph = require('@microsoft/microsoft-graph-client');
const authProviders =require('@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials');let _settings = undefined;
let _deviceCodeCredential = undefined;
let _userClient = undefined;function initializeGraphForUserAuth(settings, deviceCodePrompt) {// Ensure settings isn't nullif (!settings) {throw new Error('Settings cannot be undefined');}_settings = settings;_deviceCodeCredential = new azure.DeviceCodeCredential({clientId: settings.clientId,tenantId: settings.tenantId,userPromptCallback: deviceCodePrompt});const authProvider = new authProviders.TokenCredentialAuthenticationProvider(_deviceCodeCredential, {scopes: settings.graphUserScopes});_userClient = graph.Client.initWithMiddleware({authProvider: authProvider});
}
async function getUserTokenAsync() {// Ensure credential isn't undefinedif (!_deviceCodeCredential) {throw new Error('Graph has not been initialized for user auth');}// Ensure scopes isn't undefinedif (!_settings?.graphUserScopes) {throw new Error('Setting "scopes" cannot be undefined');}// Request token with given scopesconst response = await _deviceCodeCredential.getToken(_settings?.graphUserScopes);return response.token;
}
async function getUserAsync() {// Ensure client isn't undefinedif (!_userClient) {throw new Error('Graph has not been initialized for user auth');}return _userClient.api('/me')// Only request specific properties.select(['displayName', 'mail', 'userPrincipalName']).get();
}
async function getInboxAsync() {// Ensure client isn't undefinedif (!_userClient) {throw new Error('Graph has not been initialized for user auth');}return _userClient.api('/me/mailFolders/inbox/messages').select(['from', 'isRead', 'receivedDateTime', 'subject']).top(25).orderby('receivedDateTime DESC').get();
}
async function sendMailAsync(subject, body, recipient) {// Ensure client isn't undefinedif (!_userClient) {throw new Error('Graph has not been initialized for user auth');}// Create a new messageconst message = {subject: subject,body: {content: body,contentType: 'text'},toRecipients: [{emailAddress: {address: recipient}}]};// Send the messagereturn _userClient.api('me/sendMail').post({message: message});
}
// This function serves as a playground for testing Graph snippets
// or other code
async function makeGraphCallAsync() {// INSERT YOUR CODE HERE
}
module.exports.makeGraphCallAsync = makeGraphCallAsync;
module.exports.sendMailAsync = sendMailAsync;
module.exports.getInboxAsync = getInboxAsync;
module.exports.getUserAsync = getUserAsync;
module.exports.getUserTokenAsync = getUserTokenAsync;
module.exports.initializeGraphForUserAuth = initializeGraphForUserAuth;
💖主文件index.js 对外暴露
index.js 功能
const readline = require('readline-sync');const settings = require('./appSettings');
const graphHelper = require('./graphHelper');async function main() {console.log('JavaScript Graph Tutorial');let choice = 0;// Initialize GraphinitializeGraph(settings);// Greet the user by nameawait greetUserAsync();const choices = ['Display access token','List my inbox','Send mail','Make a Graph call'];while (choice != -1) {choice = readline.keyInSelect(choices, 'Select an option', { cancel: 'Exit' });switch (choice) {case -1:// Exitconsole.log('Goodbye...');break;case 0:// Display access tokenawait displayAccessTokenAsync();break;case 1:// List emails from user's inboxawait listInboxAsync();break;case 2:// Send an email messageawait sendMailAsync();break;case 3:// Run any Graph codeawait makeGraphCallAsync();break;default:console.log('Invalid choice! Please try again.');}}
}
function initializeGraph(settings) {// TODOgraphHelper.initializeGraphForUserAuth(settings, (info) => {// Display the device code message to// the user. This tells them// where to go to sign in and provides the// code to use.console.log(info.message);});
}async function greetUserAsync() {// TODOtry {const user = await graphHelper.getUserAsync();console.log(`Hello, ${user?.displayName}!`);// For Work/school accounts, email is in mail property// Personal accounts, email is in userPrincipalNameconsole.log(`Email: ${user?.mail ?? user?.userPrincipalName ?? ''}`);} catch (err) {console.log(`Error getting user: ${err}`);}
}async function displayAccessTokenAsync() {// TODOtry {const userToken = await graphHelper.getUserTokenAsync();console.log(`User token: ${userToken}`);} catch (err) {console.log(`Error getting user access token: ${err}`);}}async function listInboxAsync() {// TODOtry {const messagePage = await graphHelper.getInboxAsync();const messages = messagePage.value;// Output each message's detailsfor (const message of messages) {console.log(`Message: ${message.subject ?? 'NO SUBJECT'}`);console.log(` From: ${message.from?.emailAddress?.name ?? 'UNKNOWN'}`);console.log(` Status: ${message.isRead ? 'Read' : 'Unread'}`);console.log(` Received: ${message.receivedDateTime}`);}// If @odata.nextLink is not undefined, there are more messages// available on the serverconst moreAvailable = messagePage['@odata.nextLink'] != undefined;console.log(`\nMore messages available? ${moreAvailable}`);} catch (err) {console.log(`Error getting user's inbox: ${err}`);}
}async function sendMailAsync() {// TODOtry {// Send mail to the signed-in user// Get the user for their email addressconst user = await graphHelper.getUserAsync();const userEmail = user?.mail ?? user?.userPrincipalName;if (!userEmail) {console.log('Couldn\'t get your email address, canceling...');return;}await graphHelper.sendMailAsync('Testing Microsoft Graph','Hello world!', userEmail);console.log('Mail sent.');} catch (err) {console.log(`Error sending mail: ${err}`);}
}async function makeGraphCallAsync() {// TODOtry {await graphHelper.makeGraphCallAsync();} catch (err) {console.log(`Error making Graph call: ${err}`);}
}main();
💖效果
运行首先需要授权
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code S6HDWLLQ3 to authenticate.
手动授权输入返回的验证码
登录outlook
登录成功
可以打印token
后续把这个放在koa暴露接口可以实现web简陋版的邮箱登录
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 感谢你的阅读!