Fixing Outlook attachment issues.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Graph.Models;
|
||||
using MimeKit;
|
||||
@@ -98,45 +97,6 @@ namespace Wino.Core.Extensions
|
||||
message.InternetMessageHeaders = GetHeaderList(mime);
|
||||
}
|
||||
|
||||
foreach (var part in mime.BodyParts)
|
||||
{
|
||||
if (part.IsAttachment)
|
||||
{
|
||||
// File attachment.
|
||||
|
||||
using var memory = new MemoryStream();
|
||||
((MimePart)part).Content.DecodeTo(memory);
|
||||
|
||||
var bytes = memory.ToArray();
|
||||
|
||||
var fileAttachment = new FileAttachment()
|
||||
{
|
||||
ContentId = part.ContentId,
|
||||
Name = part.ContentDisposition?.FileName ?? part.ContentType.Name,
|
||||
ContentBytes = bytes,
|
||||
};
|
||||
|
||||
message.Attachments.Add(fileAttachment);
|
||||
}
|
||||
else if (part.ContentDisposition != null && part.ContentDisposition.Disposition == "inline")
|
||||
{
|
||||
// Inline attachment.
|
||||
|
||||
using var memory = new MemoryStream();
|
||||
((MimePart)part).Content.DecodeTo(memory);
|
||||
|
||||
var bytes = memory.ToArray();
|
||||
var inlineAttachment = new FileAttachment()
|
||||
{
|
||||
IsInline = true,
|
||||
ContentId = part.ContentId,
|
||||
Name = part.ContentDisposition?.FileName ?? part.ContentType.Name,
|
||||
ContentBytes = bytes
|
||||
};
|
||||
|
||||
message.Attachments.Add(inlineAttachment);
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
25
Wino.Core/Misc/OutlookFileAttachment.cs
Normal file
25
Wino.Core/Misc/OutlookFileAttachment.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Wino.Core.Misc
|
||||
{
|
||||
public class OutlookFileAttachment
|
||||
{
|
||||
[JsonPropertyName("@odata.type")]
|
||||
public string OdataType { get; } = "#microsoft.graph.fileAttachment";
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string FileName { get; set; }
|
||||
|
||||
[JsonPropertyName("contentBytes")]
|
||||
public string Base64EncodedContentBytes { get; set; }
|
||||
|
||||
[JsonPropertyName("contentType")]
|
||||
public string ContentType { get; set; }
|
||||
|
||||
[JsonPropertyName("contentId")]
|
||||
public string ContentId { get; set; }
|
||||
|
||||
[JsonPropertyName("isInline")]
|
||||
public bool IsInline { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
@@ -236,7 +235,6 @@ namespace Wino.Core.Synchronizers
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex, "Synchronization failed for {Name}", Account.Name);
|
||||
Debugger.Break();
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Extensions;
|
||||
using Wino.Core.Http;
|
||||
using Wino.Core.Integration.Processors;
|
||||
using Wino.Core.Misc;
|
||||
using Wino.Core.Requests;
|
||||
|
||||
namespace Wino.Core.Synchronizers
|
||||
@@ -689,6 +690,11 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
var outlookMessage = mimeMessage.AsOutlookMessage(false);
|
||||
|
||||
// Create attachment requests.
|
||||
// TODO: We need to support large file attachments with sessioned upload at some point.
|
||||
|
||||
var attachmentRequestList = CreateAttachmentUploadBundles(mimeMessage, mailCopyId, request).ToList();
|
||||
|
||||
// Update draft.
|
||||
|
||||
var patchDraftRequest = _graphClient.Me.Messages[mailCopyId].ToPatchRequestInformation(outlookMessage);
|
||||
@@ -696,12 +702,60 @@ namespace Wino.Core.Synchronizers
|
||||
|
||||
// Send draft.
|
||||
|
||||
|
||||
var sendDraftRequest = PreparePostRequestInformation(_graphClient.Me.Messages[mailCopyId].Send.ToPostRequestInformation());
|
||||
|
||||
var sendDraftRequestBundle = new HttpRequestBundle<RequestInformation>(sendDraftRequest, request);
|
||||
|
||||
return [patchDraftRequestBundle, sendDraftRequestBundle];
|
||||
return [.. attachmentRequestList, patchDraftRequestBundle, sendDraftRequestBundle];
|
||||
}
|
||||
|
||||
private IEnumerable<IRequestBundle<RequestInformation>> CreateAttachmentUploadBundles(MimeMessage mime, string mailCopyId, IRequestBase sourceRequest)
|
||||
{
|
||||
var allAttachments = new List<OutlookFileAttachment>();
|
||||
|
||||
foreach (var part in mime.BodyParts)
|
||||
{
|
||||
var isAttachmentOrInline = part.IsAttachment ? true : part.ContentDisposition?.Disposition == "inline";
|
||||
|
||||
if (!isAttachmentOrInline) continue;
|
||||
|
||||
using var memory = new MemoryStream();
|
||||
((MimePart)part).Content.DecodeTo(memory);
|
||||
|
||||
var base64String = Convert.ToBase64String(memory.ToArray());
|
||||
|
||||
var attachment = new OutlookFileAttachment()
|
||||
{
|
||||
Base64EncodedContentBytes = base64String,
|
||||
FileName = part.ContentDisposition?.FileName ?? part.ContentType.Name,
|
||||
ContentId = part.ContentId,
|
||||
ContentType = part.ContentType.MimeType,
|
||||
IsInline = part.ContentDisposition?.Disposition == "inline"
|
||||
};
|
||||
|
||||
allAttachments.Add(attachment);
|
||||
}
|
||||
|
||||
RequestInformation PrepareUploadAttachmentRequest(RequestInformation requestInformation, OutlookFileAttachment outlookFileAttachment)
|
||||
{
|
||||
requestInformation.Headers.Clear();
|
||||
|
||||
string contentJson = JsonSerializer.Serialize(outlookFileAttachment);
|
||||
|
||||
requestInformation.Content = new MemoryStream(Encoding.UTF8.GetBytes(contentJson));
|
||||
requestInformation.HttpMethod = Method.POST;
|
||||
requestInformation.Headers.Add("Content-Type", "application/json");
|
||||
|
||||
return requestInformation;
|
||||
}
|
||||
|
||||
// Prepare attachment upload requests.
|
||||
return allAttachments.Select(outlookAttachment =>
|
||||
{
|
||||
var emptyPostRequest = _graphClient.Me.Messages[mailCopyId].Attachments.ToPostRequestInformation(new Attachment());
|
||||
var modifiedAttachmentUploadRequest = PrepareUploadAttachmentRequest(emptyPostRequest, outlookAttachment);
|
||||
|
||||
return new HttpRequestBundle<RequestInformation>(modifiedAttachmentUploadRequest, sourceRequest);
|
||||
});
|
||||
}
|
||||
|
||||
public override IEnumerable<IRequestBundle<RequestInformation>> Archive(BatchArchiveRequest request)
|
||||
|
||||
Reference in New Issue
Block a user