Download .eml file with Microsoft Graph C#

6.8k views Asked by At

I have some problem with Microsoft Graph.I would like to download the attachments present in a specific email. I have verified that the type of object returned after this:

 var attachments = graphClient.Me.Messages[msg.Id].Attachments.Request().GetAsync().Result;
 foreach(var item in attachments) {
         var current_attachment = graphClient.Me.Messages[msg.Id].Attachments[item.Id].Request().GetAsync().Result;
}

is an object of type Attachment. Now, I would like to download this object (current_attachment) but I saw that the property ContentBytes isn't available. I have tried to cast the object to FileAttachment, but it throw an exception.

Thank you.

2

There are 2 answers

2
paulsm4 On

This should be fairly straightforward. Specifically:

https://learn.microsoft.com/en-us/graph/outlook-get-mime-message

Even though Outlook does not save messages in MIME format, there are two ways you can get an Outlook message body in MIME format:

You can append a $value segment to a get-message operation on that message. If the message is attached to an Outlook item or group post, you can append a $value segment to a get-attachment operation on that item or group post. In either case, your app must have the appropriate permissions to access the Outlook item or group post in order to apply the get-message or get-attachment operation.

You can then save the message body content in a .EML file and attach the file to records in business systems, such as those for CRM, ERP, and bug tracking.

Here is an example:

https://learn.microsoft.com/en-us/graph/api/message-get?view=graph-rest-1.0&tabs=csharp

Gets the MIME content of a message in the signed-in user's mailbox.

GraphServiceClient graphClient = new GraphServiceClient( authProvider );

var stream = await graphClient.Me.Messages["4aade2547798441eab5188a7a2436bc1"].Content
  .Request()
  .GetAsync();

You can write "stream" to a disk file like this:

string path = @"\my\path\myfile.eml";
using(FileStream outputFileStream = new FileStream(path, FileMode.Create)) 
{  
    stream.CopyTo(outputFileStream);  
}  

The resulting .eml file will be the complete email, including all attachments.

0
Darren Thompson On

You can do a similar call to get an InputStream for the ItemAttachment as you would do to get the InputStream for a Message. See code below in java but will be similar for c#. The java API is missing the .content() option on Attachments but you can build the url and append $value instead.

URL requestUrl = graphClient.users("user@***.com").messages("*****").attachments("****").buildRequest().getRequestUrl();
InputStream is = new FileAttachmentStreamRequestBuilder(requestUrl.toString() + "/$value", graphClient, null).buildRequest().get();
// save the file
Files.copy(is, Paths.get(fileName + extension), StandardCopyOption.REPLACE_EXISTING);