Handling of OutlookSynchronizer alias.
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Graph.Models;
|
||||
using MimeKit;
|
||||
using Wino.Core.Domain.Entities;
|
||||
using Wino.Core.Domain.Enums;
|
||||
|
||||
@@ -61,5 +65,143 @@ namespace Wino.Core.Extensions
|
||||
|
||||
return mailCopy;
|
||||
}
|
||||
|
||||
public static Message AsOutlookMessage(this MimeMessage mime, string threadId)
|
||||
{
|
||||
var fromAddress = GetRecipients(mime.From).ElementAt(0);
|
||||
var toAddresses = GetRecipients(mime.To).ToList();
|
||||
var ccAddresses = GetRecipients(mime.Cc).ToList();
|
||||
var bccAddresses = GetRecipients(mime.Bcc).ToList();
|
||||
var replyToAddresses = GetRecipients(mime.ReplyTo).ToList();
|
||||
|
||||
var message = new Message()
|
||||
{
|
||||
Subject = mime.Subject,
|
||||
Importance = GetImportance(mime.Importance),
|
||||
Body = new ItemBody() { ContentType = BodyType.Html, Content = mime.HtmlBody },
|
||||
IsDraft = false,
|
||||
IsRead = true, // Sent messages are always read.
|
||||
ToRecipients = toAddresses,
|
||||
CcRecipients = ccAddresses,
|
||||
BccRecipients = bccAddresses,
|
||||
From = fromAddress,
|
||||
InternetMessageId = GetMessageIdHeader(mime.MessageId),
|
||||
ConversationId = threadId,
|
||||
InternetMessageHeaders = GetHeaderList(mime),
|
||||
ReplyTo = replyToAddresses,
|
||||
Attachments = []
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#region Mime to Outlook Message Helpers
|
||||
|
||||
private static IEnumerable<Recipient> GetRecipients(this InternetAddressList internetAddresses)
|
||||
{
|
||||
foreach (var address in internetAddresses)
|
||||
{
|
||||
if (address is MailboxAddress mailboxAddress)
|
||||
yield return new Recipient() { EmailAddress = new EmailAddress() { Address = mailboxAddress.Address, Name = mailboxAddress.Name } };
|
||||
else if (address is GroupAddress groupAddress)
|
||||
{
|
||||
// TODO: Group addresses are not directly supported.
|
||||
// It'll be individually added.
|
||||
|
||||
foreach (var mailbox in groupAddress.Members)
|
||||
if (mailbox is MailboxAddress groupMemberMailAddress)
|
||||
yield return new Recipient() { EmailAddress = new EmailAddress() { Address = groupMemberMailAddress.Address, Name = groupMemberMailAddress.Name } };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Importance? GetImportance(MessageImportance importance)
|
||||
{
|
||||
return importance switch
|
||||
{
|
||||
MessageImportance.Low => Importance.Low,
|
||||
MessageImportance.Normal => Importance.Normal,
|
||||
MessageImportance.High => Importance.High,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
private static List<InternetMessageHeader> GetHeaderList(this MimeMessage mime)
|
||||
{
|
||||
// Graph API only allows max of 5 headers.
|
||||
// Here we'll try to ignore some headers that are not neccessary.
|
||||
// Outlook API will generate them automatically.
|
||||
|
||||
string[] headersToIgnore = ["Date", "To", "MIME-Version", "From", "Subject", "Message-Id"];
|
||||
|
||||
var headers = new List<InternetMessageHeader>();
|
||||
|
||||
int includedHeaderCount = 0;
|
||||
|
||||
foreach (var header in mime.Headers)
|
||||
{
|
||||
if (!headersToIgnore.Contains(header.Field))
|
||||
{
|
||||
headers.Add(new InternetMessageHeader() { Name = header.Field, Value = header.Value });
|
||||
includedHeaderCount++;
|
||||
}
|
||||
|
||||
if (includedHeaderCount >= 5) break;
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
private static string GetMessageIdHeader(string messageId)
|
||||
{
|
||||
// Message-Id header must always start with "X-" or "x-".
|
||||
if (string.IsNullOrEmpty(messageId)) return string.Empty;
|
||||
|
||||
if (!messageId.StartsWith("x-") || !messageId.StartsWith("X-"))
|
||||
return $"X-{messageId}";
|
||||
|
||||
return messageId;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user