Reputation: 11
Here is how i am getting list of attachment objects attached to a message:
IAttachmentCollectionRequest attachmentsPage = graphClient
.users(emailServer.getEmailAddress())
.mailFolders("Inbox")
.messages(mail.id)
.attachments()
.buildRequest();
List<Attachment> attachmentsData = attachmentsPage.get().getCurrentPage();
List<AttachmentData> attachmentDataToStore = new java.util.ArrayList<AttachmentData>();
for(Attachment attachment : attachmentsData)
{
attachmentData.setInputStream(
new ByteArrayInputStream(
attachment.getRawObject()
.get("contentBytes")
.getAsString()
.getBytes()));
}
Now, I believe the conversion of content bytes to input stream is not happening properly and eventually data(image.png) is getting corrupted. Any suggestions?
Upvotes: 0
Views: 1408
Reputation: 1170
as of microsoft-graph version 5.34.0 several things are no longer needed, like decoding, and you'll be ably to simply cast your object.
A convoluted way to get File/ItemAttachments:
List<Attachment> attachments = new ArrayList<>();
try {
AttachmentCollectionPage mgAttachmentList =
graphClient.users(emailAddress)
.messages(mail.id)
.attachments()
.buildRequest()
.get();
do {
attachments.addAll(mgAttachmentList.getCurrentPage());
// Check for next page
if (mgAttachmentList.getNextPage() != null) {
mgAttachmentList = mgAttachmentList.getNextPage().buildRequest().get();
} else {
mgAttachmentList = null;
}
} while (mgAttachmentList != null);
attachments.stream()
.filter(Objects::nonNull)
.forEach(attachment -> {
try {
// attachment equals a FileAttachment
if ("#microsoft.graph.fileAttachment".equalsIgnoreCase(attachment.oDataType)) {
byte[] attachmentContentBytes = ((FileAttachment) attachment).contentBytes;
if (attachmentContentBytes != null) {
// your own logic here
}
} else if ("#microsoft.graph.itemAttachment".equalsIgnoreCase(attachment.oDataType)) {
/*
* We need to convert each Attachment.
* If it's an ItemAttachment, we need to do another call to retrieve the item-object.
*
* The standard call with expand option gives us an Attachment (again)
*/
if (StringUtils.isNotBlank(attachment.contentType)) {
Attachment attachment = graphClient.users(emailAddress)
.messages(mail.id)
.attachments(attachment.id)
.buildRequest()
.expand("microsoft.graph.itemattachment/item")
.get();
if (attachment != null) {
// cast the object to whatever you need, in this example I retrieve the webLink
String linkToMessage = ((Message) ((ItemAttachment) attachment).item).webLink;
// your own logic here
}
} else {
log.info("Unknown attachment contentType for an ItemAttachment - Could not read attachment.");
}
} else {
log.error("Unable to read an attachment for mail.");
}
} catch (Exception e) {
log.error("Could not read attachment: '" + attachment.name + "' for message: '" + message.subject + ". " + e.getMessage(), e);
}
});
} catch (Exception e) {
log.error("Something went wrong while receiving attachments for message: '" + message.subject + "'. " + e.getMessage(), e);
}
Upvotes: 0
Reputation: 121
Your method of reading contentBytes from the rawObject JSON will work. You just need to use a Base64 decoder instead of String.getBytes()
because contentBytes is base64-encoded. This was a bit faster on my network than requesting the attachment again using FileAttachmentRequestBuilder.
IAttachmentCollectionRequest attachmentsPage = graphClient
.users(emailServer.getEmailAddress())
.mailFolders("Inbox")
.messages(mail.id)
.attachments()
.buildRequest();
List<Attachment> attachmentsData = attachmentsPage.get().getCurrentPage();
List<AttachmentData> attachmentDataToStore = new java.util.ArrayList<AttachmentData>();
for(Attachment attachment : attachmentsData)
{
attachmentData.setInputStream(
new ByteArrayInputStream(
Base64.getDecoder().decode(attachment.getRawObject()
.get("contentBytes")
.getAsString());
}
Upvotes: 0
Reputation: 17702
Use the FileAttachment
class to handle all of this for you. Unfortunately the SDK doesn't handle this in the most "clean" manner - you have to request the attachment a second time.
public static void saveAttachments(String accessToken) {
ensureGraphClient(accessToken);
final String mailId = "message-id";
// Get the list of attachments
List<Attachment> attachments = graphClient
.me()
.messages(mailId)
.attachments()
.buildRequest()
// Use select here to avoid getting the content in this first request
.select("id,contentType,size")
.get()
.getCurrentPage();
for(Attachment attachment : attachments) {
// Attachment is a base type - need to re-get the attachment as a fileattachment
if (attachment.oDataType.equals("#microsoft.graph.fileAttachment")) {
// Use the client to generate the request URL
String requestUrl = graphClient
.me()
.messages(mailId)
.attachments(attachment.id)
.buildRequest()
.getRequestUrl()
.toString();
// Build a new file attachment request
FileAttachmentRequestBuilder requestBuilder =
new FileAttachmentRequestBuilder(requestUrl, graphClient, null);
FileAttachment fileAttachment = requestBuilder.buildRequest().get();
// Get the content directly from the FileAttachment
byte[] content = fileAttachment.contentBytes;
try (FileOutputStream stream = new FileOutputStream("C:\\Source\\test.png")) {
stream.write(content);
} catch (IOException exception) {
// Handle it
}
}
}
}
Upvotes: 1