如何在TypeScript开发的Outlook插件中使用MSGraphClient上传附件至SharePoint
问题根因
- 你引入的
MSGraphClient来自@microsoft/sp-http包,这个类是仅用于SharePoint Framework(SPFx)项目的专属类,你开发的是Outlook外接程序,运行环境不支持这个类,所以必然返回未定义 - 你在
saveAttachment函数中只声明了graphClient变量,没有做任何初始化操作,调用时当然是undefined状态
解决方案
直接用你已经引入的@microsoft/microsoft-graph-client包的Client类,搭配SSO拿到的访问令牌初始化即可,步骤如下:
1. 补充安装依赖(如果未安装)
npm install @microsoft/microsoft-graph-client
2. 修正代码逻辑
你之前调用的getGraphData已经通过SSO拿到了Graph访问令牌,直接复用令牌初始化Graph客户端即可,如果你的ssoauthhelper中的getGraphData没有返回访问令牌,修改该方法直接返回拿到的access_token即可,修正后的完整代码如下:
/* * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. * See LICENSE in the project root for license information. */ // images references in the manifest import "../../assets/icon-16.png"; import "../../assets/icon-32.png"; import "../../assets/icon-80.png"; /* global $, document, Office */ // 删掉无用的MSGraphClient引入 import { Client } from "@microsoft/microsoft-graph-client"; import { getGraphData } from "./../helpers/ssoauthhelper"; // 全局存储Graph客户端实例 let graphClient: Client; Office.onReady((info) => { if (info.host === Office.HostType.Outlook) { $(function () { // 初始化时拿到SSO令牌,直接初始化Graph客户端 getGraphData().then(token => { graphClient = Client.initWithMiddleware({ authProvider: { getAccessToken: async () => token } }); }); $("#saveAttachments").on("click", async function() { const checkedAttachments = $(".atchCheckBoxes > input[type=checkbox]:checked"); for (const checkbox of checkedAttachments) { const attachmentId = $(checkbox).val(); const attachment = Office.context.mailbox.item.attachments.find(a => a.id === attachmentId); if (!attachment) continue; Office.context.mailbox.item.getAttachmentContentAsync(attachment.id, async (asyncResult) => { if (asyncResult.status === Office.AsyncResultStatus.Succeeded) { // base64内容转Uint8Array,避免上传后文件损坏 const byteCharacters = atob(asyncResult.value.content); const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const contentBuffer = new Uint8Array(byteNumbers); await saveAttachment(contentBuffer, attachment.name); } }); } }); }); } }); async function saveAttachment(content: Uint8Array, fileName: string): Promise<string> { // 替换为你实际的SharePoint站点ID和目标文档库ID const siteId = "你的SharePoint站点ID"; const driveId = "目标文档库ID"; // SharePoint文档库上传API路径 const uploadApi = `/sites/${siteId}/drives/${driveId}/root:/${fileName}:/content`; // 小于4MB的文件直接上传 const saveResult = await graphClient.api(uploadApi).put(content); console.log(`Save Attachment result for ${fileName}: `, saveResult); return saveResult.id; }
3. 配置注意事项
- 先确认你的Outlook插件manifest中已经正确配置了SSO,并且申请了上传需要的Graph权限,比如
Files.ReadWrite.All、Sites.ReadWrite.All - 附件大小超过4MB时,需要用Graph的分片上传接口
createUploadSession处理,不能直接用put方法上传 - 如果不需要固定传到指定SharePoint文档库,也可以直接用用户OneDrive的路径
/me/drive/root:/${fileName}:/content上传
内容的提问来源于stack exchange,提问作者Umair Aslam
相关产品推荐
相关产品推荐

