Commonly Occurring Errors in Microsoft Graph Integrations and How To Troubleshoot Them (Part 5)
The last article of this series covers two use cases of reading attachment content as to the resource type Microsoft To-Do Tasks and Events via MS Graph APIs.
Join the DZone community and get the full member experience.
Join For FreeMicrosoft Graph is a powerful tool that allows developers to access various Microsoft services, including OneDrive, SharePoint, Outlook, and more. One feature of Microsoft Graph that is particularly useful for productivity is the ability to read attachment content of To-Do task and event attachments. This allows users to access important information and files directly from their To-Do tasks and events, without having to switch between different applications.
If you haven’t read the first parts of this series, here they are:
- “Commonly Occurring Errors in Microsoft Graph Integrations and How To Troubleshoot Them"
For both use cases below, I have used MS Graph Java SDK 5.42.0.
Read MS To-Do Tasks Attachment Content Such as Pictures
It's quite easy to get the content bytes of the attachment. Just send a GET
request to the following URL:
https://graph.microsoft.com/v1.0/me/todo/lists/{list_id}/tasks/{task_id}/attachments/{attachment_id}/$value
Replace {list_id}
, {task_id}
, and {attachment_id}
with the IDs of the list, task, and attachment that you want to retrieve. If you have a picture as an attachment, the response of the GET
request would be the picture itself. If you remove the keyword $value
, then the response looks like as in the following example:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('...')/attachments/$entity",
"@odata.type": "#microsoft.graph.taskFileAttachment",
"contentBytes": "AAAAKGZ0eXBoZWljAAAAAG1pZjFNaUhFT ... ",
"id": "...",
"name": "IMG_1022(1).HEIC",
"size": 2281219,
"lastModifiedDateTime": "2023-05-05T06:59:21Z",
"contentType": "image/heic"
}
Hint: The attachment content is displayed as content bytes.
How to read attachment content via the MS Graph Java SDK is shown in the next sample:
String accessToken = "YOUR_ACCESS_TOKEN_HERE";
GraphServiceClient graphClient = GraphServiceClient
.builder()
.authenticationProvider(request -> {
request.addHeader("Authorization", "Bearer " + accessToken);
})
.buildClient();
String taskId = "TASK_ID_HERE";
List<Attachment> attachments = graphClient
.me()
.tasks(taskId)
.attachments()
.buildRequest()
.get();
for (Attachment attachment : attachments) {
InputStream attachmentStream = graphClient
.me()
.tasks(taskId)
.attachments(attachment.id)
.content()
.buildRequest()
.get();
// Do something with the attachment stream
}
Use the getAttachments()
method to get a list of attachments associated with the task. For each attachment, you can use the getContent()
method to read the content of the attachment. Note that you should handle any exceptions that may occur during this process. Additionally, this code assumes that you have the necessary permissions to access the task and its attachments.
Read MS Event Attachment Content Such as Pictures
As the use case of To-Do tasks above, you can get the attachment content via a GET
request:
GET /me/events/{event-id}/attachments/{attachment-id}/$value
By making a GET
request to the events endpoint, including the event ID
and attachment ID
in the request URL, the response will include the raw binary content of the attachment. As before, you may need to include an access token or other authentication credentials in your API request.
If you remove $value
from the request, q.e., the response will include metadata about the attachment, such as its content type and size, in addition to the raw binary content as content bytes. Once you have obtained the attachment content, you can use it as needed in your application. For example, if the attachment is a picture, you can get the picture using the request below.
GET /me/events/{event-id}/attachments/{attachment-id}
Check out the next example of how to read attachment content via the MS Graph Java SDK for MS Events:
String accessToken = "YOUR_ACCESS_TOKEN_HERE";
GraphServiceClient graphClient = GraphServiceClient
.builder()
.authenticationProvider(request -> {
request.addHeader("Authorization", "Bearer " + accessToken);
})
.buildClient();
String eventId = "EVENT_ID_HERE";
List<Attachment> attachments = graphClient
.me()
.events(eventId)
.attachments()
.buildRequest()
.get();
for (Attachment attachment : attachments) {
InputStream attachmentStream = graphClient
.me()
.events(eventId)
.attachments(attachment.id)
.content()
.buildRequest()
.get();
// Do something with the attachment stream
}
Similar to the use case of To-Do tasks, first, we have to authenticate ourselves and create a GraphServiceClient
. Afterward, we use the getAttachments()
method to get a list of attachments associated with the event. For each attachment, you can use the getContent()
method to read the content of the attachment. Let me note: you should handle any exceptions that may occur during this process. Additionally, this code assumes that you have the necessary permissions to access the event and its attachments as we already have seen at To-Do tasks.
Read Content Bytes From Attachments Such as Pictures
Let's assume you have to process attachment content of To-Do tasks or events within your application and your application has no user interface and runs only in the background. Your attachment is a picture. In this case, you can't process the return value that you get from the requests:
/me/todo/lists/{list_id}/tasks/{task_id}/attachments/{attachment_id}/$value
Or
/me/events/{event-id}/attachments/{attachment-id}/$value
To get the content bytes of the picture, you can use the following requests for example:
/me/events/{event-id}/attachments/{attachment-id}
Or
/me/todo/lists/{list_id}/tasks/{task_id}/attachments/{attachment_id}
In case a resource type is an event, your response will look like this:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('dfb74...D')/attachments/$entity",
"@odata.type": "#microsoft.graph.fileAttachment",
"@odata.mediaContentType": "image/heic",
"id": "AAMkADg4ZTk4NTQ5LTEyMWYtNDg5OC1hZjcxLWMzZT ...",
"lastModifiedDateTime": "2023-05-05T07:46:39Z",
"name": "IMG_1022.HEIC",
"contentType": "image/heic",
"size": 2281207,
"isInline": false,
"contentId": null,
"contentLocation": null,
"contentBytes": "AAAAKGZ0eXBoZWljAAAAAG1pZjFNaUh ..."
}
To optimize the response to avoid the other properties such as contentType
, size
, and so on, you can modify the request as follows:
https://graph.microsoft.com/v1.0/me/events/AAMkADg4ZTk4NTQ5LTEyMWYtNDg5OC1hZjcxLWMzZTh[…]NT93Oo=?$select=microsoft.graph.fileAttachment/contentBytes
Via the request parameter select
, you only will get back the property contentBytes
. Your response is supposed to look as follows:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('...ea5')/events('AAMk...A%3D')/attachments(microsoft.graph.fileAttachment/contentBytes)/$entity",
"@odata.type": "#microsoft.graph.fileAttachment",
"@odata.mediaContentType": "image/heic",
"id": "AAMkADg4ZTk4NTQ5LTEyMWYtNDg5O ... ",
"contentBytes": "AAAAKGZ0eXBoZWljAAAAAG1pZjFNaUhFTWl ..."
}
Within the MS Graph Java SDK, we have seen in both use cases above, we get an object from object type Inputstream
as return from the client graphClient
.
To get the byte array from the input stream you can use Google package com.google.common.io
to write the byte array. The code line may look like the following:
ByteStreams.toByteArray(getInputStreamOfAttachmentContent(userID, listID, taskID, attachmentID));
With the method:
private InputStream getInputStreamOfAttachmentContent(userID, listID, taskID, attachmentID) {
return getGraphService(user).getGraphServiceClient()
.users(userID)
.todo()
.lists(listID)
.tasks(taskID)
.attachments(attachmentID)
.content()
.buildRequest()
.get();
}
Conclusion
We can see that in both use cases, the attachment content can be read very easily. Microsoft has implemented a very uniform way to read the attachment content for To-Do tasks and events. We do not have always consistency if we use the MS Graph APIs and SDKs. Take a look at the approach of reading attachment content of messages or uploading large attachments of To-Do tasks and events.
Opinions expressed by DZone contributors are their own.
Comments