如何通过Microsoft Graph API检索itemAttachment的内容

10
我正在开发一个解决方案,通过Microsoft Graph API检索电子邮件。2015年11月,微软宣布该API已准备好投入生产,并且在另一个论坛帖子中我读到,如果你现在开始使用Microsoft API进行开发,应该使用Graph API,因为它是未来。除了一个问题,一切都很顺利。

我的任务是检索电子邮件。这些电子邮件中当然包含附件,这些附件有多种形式:fileAttachment(图像、文档等)、referenceAttachments和itemAttachments(outlook-item)。问题在于itemAttachments。itemAttachment可以是任何东西,从约会到另一条消息。问题是我无法以与fileAttachment相同的方式获取和检索contentBytes。itemAttachment的相关对象是outlookItem。也有一个为此outlookItem制作的描述页面,但其中缺少示例和细节。

用户权限设置为Mail.Read和Mail.ReadWrite。

链接: 概述: http://graph.microsoft.io/docs/overview/overview 获取outlookItem(为空?):

我收到的示例调用和响应,请注意附件的类型。 https://graph.microsoft.com/v1.0 /users/ /messages/ /attachments

{
  "@odata.context": "link",
  "value": [
    {
      "@odata.type": "#microsoft.graph.fileAttachment",
      "id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAGhN_vm1RlBPt7V4N9a89UY=",
      "lastModifiedDateTime": "2016-01-13T14:25:33Z",
      "name": "image001.png",
      "contentType": "image/png",
      "size": 5077,
      "isInline": true,
      "contentId": "image001.png@01D14E16.A3A32480",
      "contentLocation": null,
      "contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAKAAAACCCAIAAABOyVRHAAAAAXNSR0IArs4c6QAAEndJREFUeF7tXQ1QFFe2bkbU... (truncated)"
    },
    {
      "@odata.type": "#microsoft.graph.fileAttachment",
      "id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAFnSLgIC5wZOosmLtBWK8gE=",
      "lastModifiedDateTime": "2016-01-13T14:25:34Z",
      "name": "image002.png",
      "contentType": "image/png",
      "size": 3722,
      "isInline": true,
      "contentId": "image002.png@01D14E16.A3A32480",
      "contentLocation": null,
      "contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAPoAAABSCAYAAAB9o8m+AAAAGXRFWHRTb... (truncated)"
    },
    {
      "@odata.type": "#microsoft.graph.fileAttachment",
      "id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQANOuw7m8sW1Ot3MivYQ5OYU=",
      "lastModifiedDateTime": "2016-01-13T14:25:24Z",
      "name": "Knipsel.PNG",
      "contentType": null,
      "size": 7641,
      "isInline": false,
      "contentId": null,
      "contentLocation": null,
      "contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAKAAAACCCAYAAADBq8MQAAA... (truncated)"
    },
    {
      "@odata.type": "#microsoft.graph.itemAttachment",
      "id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAPEUC740tjtAlNTe8NpopUI=",
      "lastModifiedDateTime": "2016-01-14T15:55:07Z",
      "name": "RE: Test met plaatje",
      "contentType": null,
      "size": 36972,
      "isInline": false
    }
  ]
}

我尝试通过粘贴带或不带消息路径和仅支持一级深度的展开功能的附加文件ID来更改GET语句,但似乎找不到解决方案。 我找到的东西是这个问题,有点相同,但它是针对office365统一API的。 如何从Office 365 REST API检索ItemAttachment内容?
所以问题是:如何通过Microsoft Graph API检索outlookItem的内容?我怎样知道可以预期什么?是否有人可以帮助我克服这个障碍。

有没有人对我有任何线索,暗示或解决方案? - Bart Poelmans
很抱歉,目前没有解决方案。 - Semen Shekhovtsov
哼,我仍然不敢相信微软声称它已经准备好生产了(!) :-( - Bart Poelmans
要获取附件列表,您需要知道消息ID。当您拥有消息ID时,可以轻松调用https://graph.microsoft.com/beta/me/messages/[message Id]/attachments,并使用有效的Bearer身份验证和访问代码。此外,请确保您已在Azure管理门户上分配了足够的权限以执行此操作。附件的内容是base64编码的字符串,位于contentBytes字段中。如果您有attachmentId,则可以使用它。请查看此文档:https://graph.microsoft.io/en-us/docs/api-reference/beta/api/attachment_get.htm。它运行良好。 - Semen Shekhovtsov
3个回答

5

使用$expand选项:

GET https://graph.microsoft.com/v1.0/me/messages('AAMkADA1M-zAAA=')/attachments('AAMkADA1M-CJKtzmnlcqVgqI=')/?$expand=microsoft.graph.itemattachment/item 

响应:

HTTP/1.1 200 OK
Content-type: application/json

{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('d1a2fae9-db66-4cc9-8133-2184c77af1b8')/messages('AAMkADA1M-zAAA%3D')/attachments/$entity",
  "@odata.type":"#microsoft.graph.itemAttachment",
  "id":"AAMkADA1MCJKtzmnlcqVgqI=",
  "lastModifiedDateTime":"2017-07-21T00:20:34Z",
  "name":"Reminder - please bring laptop",
  "contentType":null,
  "size":32005,
  "isInline":false,
  "item@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('d1a2fae9-db66-4cc9-8133-2184c77af1b8')/messages('AAMkADA1M-zAAA%3D')/attachments('AAMkADA1M-CJKtzmnlcqVgqI%3D')/microsoft.graph.itemAttachment/item/$entity",
  "item":{
    "@odata.type":"#microsoft.graph.message",
    "id":"",
    "createdDateTime":"2017-07-21T00:20:41Z",
    "lastModifiedDateTime":"2017-07-21T00:20:34Z",
    "receivedDateTime":"2017-07-21T00:19:55Z",
    "sentDateTime":"2017-07-21T00:19:52Z",
    "hasAttachments":false,
    "internetMessageId":"<BY2PR15MB05189A084C01F466709E414F9CA40@BY2PR15MB0518.namprd15.prod.outlook.com>",
    "subject":"Reminder - please bring laptop",
    "importance":"normal",
    "conversationId":"AAQkADA1MzMyOGI4LTlkZDctNDkzYy05M2RiLTdiN2E1NDE3MTRkOQAQAMG_NSCMBqdKrLa2EmR-lO0=",
    "isDeliveryReceiptRequested":false,
    "isReadReceiptRequested":false,
    "isRead":false,
    "isDraft":false,
    "webLink":"https://outlook.office365.com/owa/?ItemID=AAMkADA1M3MTRkOQAAAA%3D%3D&exvsurl=1&viewmodel=ReadMessageItem",
    "body":{
      "contentType":"html",
      "content":"<html><head>\r\n</head>\r\n<body>\r\n</body>\r\n</html>"
    },
    "sender":{
      "emailAddress":{
        "name":"Adele Vance",
        "address":"AdeleV@contoso.onmicrosoft.com"
      }
    },
    "from":{
      "emailAddress":{
        "name":"Adele Vance",
        "address":"AdeleV@contoso.onmicrosoft.com"
      }
    },
    "toRecipients":[
      {
        "emailAddress":{
          "name":"Alex Wilbur",
          "address":"AlexW@contoso.onmicrosoft.com"
        }
      }
    ],
    "ccRecipients":[
      {
        "emailAddress":{
          "name":"Adele Vance",
          "address":"AdeleV@contoso.onmicrosoft.com"
        }
      }
    ]
  }
}

来源: https://developer.microsoft.com/zh-cn/graph/docs/api-reference/v1.0/api/attachment_get#request-2

该文档介绍了获取附件的API请求。附件是邮件、事件、联系人或群组中的文件或项。可以使用此API请求来检索特定附件的元数据,例如名称和大小,并下载附件内容。要执行此操作,需要读取邮件、事件、联系人或群组的权限。


1
嗨,戴夫, 感谢您的回答!那正是我在寻找的。现在我可以创建完整的电子邮件导入功能,让客户非常满意。 再次感谢,我一定会尝试这个方法!! 问候, 巴特 - Bart Poelmans
2
是的,它已经完成了大部分。对我来说,一个未解决的问题就是如何获取itemAttachment的字节。我怀疑graph是否也支持该itemAttachment中的嵌套附件。 - Dave Moten
我已经测试和尝试过了,现在非常高兴它能够正常工作。再次感谢! - Bart Poelmans
我为了这个答案寻找了很久。谢谢 @DaveMoten。参考一下,一旦你有了contentID,你需要对其进行解码。在PowerShell中:[System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($attachID.contentBytes))。 - felixmc
从Microsoft Graph版本5.34.0开始,它不再需要解码。在Java中,我检查.oDataType是否等于“#microsoft.graph.itemAttachment”,然后将响应强制转换为((ItemAttachment) responseObject,或者更深入地转换为((Message)((ItemAttachment) responseObject.item)。 - Paul

0

使用 MS Graph API for Java 获取附件:
首先构建图形客户端。示例代码如下:

ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
                .clientId(yourClientId).clientSecret(yourClientSecret)
                .tenantId(yourTenantId).build();

TokenCredentialAuthProvider tokenCredAuthProvider = new TokenCredentialAuthProvider(clientSecretCredential);
GraphServiceClient<Request> gClient = GraphServiceClient.builder().authenticationProvider(tokenCredAuthProvider)
                .buildClient();

获取一条消息的所有附件。
FileAttachment fa = (FileAttachment) graphClient.users(id).messages(messageId).attachments().buildRequest().get();

或者通过传递附件ID来获取特定的附件:

FileAttachment fa = (FileAttachment) graphClient.users(id).messages(messageId).attachments(attachmentId).buildRequest().get();

//Copy file attachment into a File from byte stream using FileUtils.
FileUtils.writeByteArrayToFile(new File(yourFileLocation), fa.contentBytes);

您也可以类似地获取所有用户、消息或附件,或传递特定的ID以获取这些实体的唯一结果。


不回答问题:OP问的是_ItemAttachment_ - 这些不是FileAttachments。 - Quango

0
官方文档:https://graph.microsoft.io/en-us/docs/api-reference/beta/api/attachment_get.htm。使用有效的Bearer身份验证访问代码,并在Azure管理门户上检查适当的Graph API权限。附件是基于64位编码的字符串,存储在contentBytes字段中。加载消息附件列表的正确Uri为:https://graph.microsoft.com/beta/me/messages/[ message Id ]/attachments。调用附件终结点的示例代码如下:

using (var client = new HttpClient())
{
    using (var request = new HttpRequestMessage(HttpMethod.Get, 
        "https://graph.microsoft.com/beta/me/messages/..id../attachments"))
    {
        request.Headers.Authorization = 
            new AuthenticationHeaderValue("Bearer", "...valid access token...");

        using (HttpResponseMessage response = await client.SendAsync(request))
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                result = await response.Content.ReadAsStringAsync();
                var json = JObject.Parse(result);
            }
        }
    }
}

嗨Semen,感谢您关注此问题。但是,您的答案涉及附件一般情况,并非此处的问题。问题是如何获取itemAttachment的内容。要模拟此操作,您可以使用Outlook客户端将电子邮件消息作为附件转发到另一个电子邮件消息。您会注意到Outlook客户端将其标识为Outlook-Item。我无法从这种类型的附件中获取contentBytes。您是否成功了?现在API版本1.0更加功能强大吗?PS:不要在生产解决方案中使用Beta。 - Bart Poelmans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接