Files
rockfish/util/RfMail.cs
2022-09-06 16:04:17 +00:00

867 lines
35 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.IO;
using System.Text.RegularExpressions;
using MailKit.Net.Smtp;
using MailKit.Net.Imap;
using MailKit.Search;
using MailKit;
using MimeKit;
using MimeKit.Utils;
namespace rockfishCore.Util
{
/*
HOW TO DIAGNOSE ISSUES:
Get a protocol log:
https://github.com/jstedfast/MailKit/blob/master/FAQ.md#ProtocolLog
docs http://www.mimekit.net/docs/html/Introduction.htm
*/
//http://www.mimekit.net/
public static class RfMail
{
// public const string MAIL_MIRROR_SMPT_ADDRESS = "mail2.ayanova.com";
// public const string MAIL_MIRROR_IMAP_ADDRESS = "mail2.ayanova.com";
public const string MAIL_SMPT_ADDRESS = "smtp.fastmail.com";
public const int MAIL_SMPT_PORT = 465;
public const string MAIL_IMAP_ADDRESS = "imap.fastmail.com";
public const int MAIL_IMAP_PORT = 993;
public const string FASTMAIL_ACCOUNT_SUPPORT = "support@onayanova.com";
public const string FASTMAIL_ACCOUNT_PASSWORD_SUPPORT = "rxwdlv4dm6kz3mhr";
// public const string MAIL_ACCOUNT_SALES = "sales@ayanova.com";
// public const string MAIL_ACCOUNT_PASSWORD_SALES = "6edbae5eb616a975abf86bcd9f45616f5c70c4f05189af60a1caaa62b406149d";
public enum rfMailAccount
{
support = 1,
sales = 2
}
public class rfMailMessage
{
public MimeMessage message { get; set; }
public uint uid { get; set; }
}
class DeliverStatusSmtpClient : SmtpClient
{
protected override DeliveryStatusNotification? GetDeliveryStatusNotifications(MimeMessage message, MailboxAddress mailbox)
{
return DeliveryStatusNotification.Delay |
DeliveryStatusNotification.Failure |
DeliveryStatusNotification.Success;
}
}
/////////////////////////////////////////////////////////
//
// Do the sending with optional deliver status receipt
//
public static void DoSend(MimeMessage message, string MailAccount, string MailAccountPassword, bool trackDeliveryStatus)
{
if (trackDeliveryStatus)
{
//set the return receipt and disposition to headers
message.Headers.Add("Return-Receipt-To", "<" + MailAccount + ">");
message.Headers.Add("Disposition-Notification-To", "<" + MailAccount + ">");
using (var client = new DeliverStatusSmtpClient())
{
//Accept all SSL certificates (in case the server supports STARTTLS)
//(we have a funky cert on the mail server)
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(MAIL_SMPT_ADDRESS, MAIL_SMPT_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// Note: only needed if the SMTP server requires authentication
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
client.Send(message);
client.Disconnect(true);
}
}
else
{
using (var client = new SmtpClient())
{
//Accept all SSL certificates (in case the server supports STARTTLS)
//(we have a funky cert on the mail server)
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(MAIL_SMPT_ADDRESS, MAIL_SMPT_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// Note: only needed if the SMTP server requires authentication
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
client.Send(message);
client.Disconnect(true);
}
}
}
public static void SendMessage(string MessageFrom, string MessageTo, string MessageSubject, string MessageBody,
bool trackDeliveryStatus = false, string CustomHeader = "", string CustomHeaderValue = "")
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("", MessageFrom));
message.To.Add(new MailboxAddress("", MessageTo));
message.Subject = MessageSubject;
message.Body = new TextPart("plain")
{
Text = MessageBody
};
message.Headers["X-Mailer"] = RfVersion.Full;
if (CustomHeader != "" && CustomHeaderValue != "")
{
message.Headers["X-Rockfish-" + CustomHeader] = CustomHeaderValue;
}
//send with optional tracking
DoSend(message, FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT, trackDeliveryStatus);
// using (var client = new SmtpClient())
// {
// //Accept all SSL certificates (in case the server supports STARTTLS)
// //(we have a funky cert on the mail server)
// client.ServerCertificateValidationCallback = (s, c, h, e) => true;
// client.Connect(MAIL_SMPT_ADDRESS, MAIL_SMPT_PORT, true);
// // Note: since we don't have an OAuth2 token, disable
// // the XOAUTH2 authentication mechanism.
// client.AuthenticationMechanisms.Remove("XOAUTH2");
// // Note: only needed if the SMTP server requires authentication
// client.Authenticate(MAIL_ACCOUNT_SUPPORT, MAIL_ACCOUNT_PASSWORD_SUPPORT);
// client.Send(message);
// client.Disconnect(true);
// }
}//send message
#region handle spam message
// /// <summary>
// /// Forward a message to the isspam@ayanova.com address and then erase it
// /// </summary>
// /// <param name="spamMessageId"></param>
// /// <param name="replyFromAccount"></param>
// public static void HandleSpamMessage(uint spamMessageId, rfMailAccount replyFromAccount)
// {
// using (var client = new ImapClient())
// {
// // Accept all SSL certificates
// client.ServerCertificateValidationCallback = (s, c, h, e) => true;
// client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// // Note: since we don't have an OAuth2 token, disable
// // the XOAUTH2 authentication mechanism.
// client.AuthenticationMechanisms.Remove("XOAUTH2");
// if (replyFromAccount == rfMailAccount.support)
// {
// client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
// }
// else
// {
// client.Authenticate(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES);
// }
// var spamFolder = client.GetFolder("Spam");
// if (spamFolder != null)
// {
// client.Inbox.Open(FolderAccess.ReadWrite);
// client.Inbox.MoveTo(new UniqueId(spamMessageId), spamFolder);
// }
// client.Disconnect(true);
// }
// }//spaminator
#endregion
#region handle read and move message
// /// <summary>
// /// Move to sub or unsub mail folder and mark as read
// /// </summary>
// /// <param name="moveMessageId"></param>
// /// <param name="replyFromAccount"></param>
// public static void MoveAndMarkRead(uint moveMessageId, rfMailAccount replyFromAccount, bool toSubscribed)
// {
// using (var client = new ImapClient())
// {
// // Accept all SSL certificates
// client.ServerCertificateValidationCallback = (s, c, h, e) => true;
// client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// // Note: since we don't have an OAuth2 token, disable
// // the XOAUTH2 authentication mechanism.
// client.AuthenticationMechanisms.Remove("XOAUTH2");
// if (replyFromAccount == rfMailAccount.support)
// {
// client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
// }
// else
// {
// client.Authenticate(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES);
// }
// //AyaNovaReceivedNOTSUB
// //AyaNovaReceivedSubscribed
// //Flag as read
// //flag the message as having been replied to
// FlagMessageSeen(moveMessageId, replyFromAccount);
// var newFolder = client.GetFolder(toSubscribed ? "AyaNovaReceivedSubscribed" : "AyaNovaReceivedNOTSUB");
// if (newFolder != null)
// {
// client.Inbox.Open(FolderAccess.ReadWrite);
// client.Inbox.MoveTo(new UniqueId(moveMessageId), newFolder);
// }
// client.Disconnect(true);
// }
// }//spaminator
#endregion
public static void ReplyMessage(uint replyToMessageId, rfMailAccount replyFromAccount, string replyBody,
bool replyToAll, bool trackDeliveryStatus = false, string CustomHeader = "", string CustomHeaderValue = "")
{
//get the original to reply to it:
MimeMessage message = GetMessage(replyToMessageId, replyFromAccount);
if (message == null)
{
throw new System.ArgumentException("RfMail:ReplyMessage->source message not found (id=" + replyToMessageId.ToString() + ")");
}
//construct the new message
var reply = new MimeMessage();
MailboxAddress from = null;
string from_account = "";
string from_account_password = "";
// switch (replyFromAccount)
// {
// case rfMailAccount.sales:
// from_account = MAIL_ACCOUNT_SALES;
// from_account_password = MAIL_ACCOUNT_PASSWORD_SALES;
// from = new MailboxAddress("", from_account);
// break;
// default:
from_account = FASTMAIL_ACCOUNT_SUPPORT;
from_account_password = FASTMAIL_ACCOUNT_PASSWORD_SUPPORT;
from = new MailboxAddress("", from_account);
// break;
// }
reply.From.Add(from);
// reply to the sender of the message
if (message.ReplyTo.Count > 0)
{
reply.To.AddRange(message.ReplyTo);
}
else if (message.From.Count > 0)
{
reply.To.AddRange(message.From);
}
else if (message.Sender != null)
{
reply.To.Add(message.Sender);
}
if (replyToAll)
{
// include all of the other original recipients (removing ourselves from the list)
reply.To.AddRange(message.To.Mailboxes.Where(x => x.Address != from.Address));
reply.Cc.AddRange(message.Cc.Mailboxes.Where(x => x.Address != from.Address));
}
// set the reply subject
if (!message.Subject.StartsWith("Re:", StringComparison.OrdinalIgnoreCase))
reply.Subject = "Re: " + message.Subject;
else
reply.Subject = message.Subject;
// construct the In-Reply-To and References headers
if (!string.IsNullOrEmpty(message.MessageId))
{
reply.InReplyTo = message.MessageId;
foreach (var id in message.References)
reply.References.Add(id);
reply.References.Add(message.MessageId);
}
// quote the original message text
using (var quoted = new StringWriter())
{
var sender = message.Sender ?? message.From.Mailboxes.FirstOrDefault();
var name = sender != null ? (!string.IsNullOrEmpty(sender.Name) ? sender.Name : sender.Address) : "someone";
quoted.WriteLine("On {0}, {1} wrote:", message.Date.ToString("f"), name);
//Try to get the original message text and format it as > quoted
var theBody = message.GetTextBody(MimeKit.Text.TextFormat.Plain);
if (theBody == null)
{
//No text body so go with the new method to extract the text part
// might be an html email, try to get the text anyway
var ht = message.HtmlBody;
if (!string.IsNullOrWhiteSpace(ht))
{
theBody = StripHTML(ht, true);
theBody += "> ";
theBody = theBody.Replace("\r\n", "\r\n> ").Trim().TrimEnd('>');
theBody = "\r\n" + theBody;//descend the first line under the On you wrote bit
}
else
{
theBody = "> Source Message Empty";
}
quoted.WriteLine(theBody);
}
else
{
//has a text body so go with old method
using (var reader = new StringReader(message.TextBody))
{
string line;
while ((line = reader.ReadLine()) != null)
{
quoted.Write("> ");
quoted.WriteLine(line);
}
}
}
reply.Body = new TextPart("plain")
{
Text = replyBody + "\r\n\r\n\r\n" + quoted.ToString()
};
}
reply.Headers["X-Mailer"] = RfVersion.Full;
if (CustomHeader != "" && CustomHeaderValue != "")
{
reply.Headers["X-Rockfish-" + CustomHeader] = CustomHeaderValue;
}
//send with optional tracking
DoSend(reply, from_account, from_account_password, trackDeliveryStatus);
//flag the message as having been replied to
FlagInboxMessageSeenReplied(replyToMessageId, replyFromAccount);
}//send message
//Fetch message by UID
public static MimeMessage GetMessage(uint uid, rfMailAccount fromAccount = rfMailAccount.support)
{
using (var client = new ImapClient())
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// if (fromAccount == rfMailAccount.support)
// {
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
// }
// else
// {
// client.Authenticate(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES);
// }
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
var m = inbox.GetMessage(new UniqueId(uid));
client.Disconnect(true);
return m;
}
}//get message
//Fetch messages by Search query
public static List<rfMailMessage> GetMessages(SearchQuery query)
{
List<rfMailMessage> ret = new List<rfMailMessage>();
using (var client = new ImapClient())
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
foreach (var uid in inbox.Search(query))
{
ret.Add(new rfMailMessage { message = inbox.GetMessage(uid), uid = uid.Id });
}
client.Disconnect(true);
}
return ret;
}//get message
//Flag message as seen and replied by UID
public static bool FlagInboxMessageSeenReplied(uint uid, rfMailAccount inAccount = rfMailAccount.support)
{
using (var client = new ImapClient())
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// if (inAccount == rfMailAccount.support)
// {
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
// }
// else
// {
// client.Authenticate(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES);
// }
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadWrite);
inbox.AddFlags(new UniqueId(uid), MessageFlags.Seen, true);
inbox.AddFlags(new UniqueId(uid), MessageFlags.Answered, true);
client.Disconnect(true);
return true;
}
}//get message
//Flag message as seen
public static bool FlagMessageSeen(uint uid, rfMailAccount inAccount = rfMailAccount.support)
{
using (var client = new ImapClient())
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// if (inAccount == rfMailAccount.support)
// {
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
// }
// else
// {
// client.Authenticate(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES);
// }
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadWrite);
inbox.AddFlags(new UniqueId(uid), MessageFlags.Seen, true);
// inbox.AddFlags(new UniqueId(uid), MessageFlags.Answered, true);
client.Disconnect(true);
return true;
}
}//get message
////////////////////////////////////////////////////
//Put a message in the drafts folder of support
//
public static void DraftMessage(string MessageFrom, string MessageTo, string MessageSubject, string MessageBody,
string CustomHeader = "", string CustomHeaderValue = "")
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("", MessageFrom));
//case 3512 handle more than one email in the address
if (MessageTo.Contains(","))
{
List<MailboxAddress> mbAll = new List<MailboxAddress>();
var addrs = MessageTo.Split(',');
foreach (string addr in addrs)
{
mbAll.Add(new MailboxAddress("", addr.Trim()));
}
message.To.AddRange(mbAll);
}
else
{
message.To.Add(new MailboxAddress("", MessageTo));
}
message.Subject = MessageSubject;
message.Body = new TextPart("plain")
{
Text = MessageBody
};
if (CustomHeader != "" && CustomHeaderValue != "")
{
message.Headers["X-Rockfish-" + CustomHeader] = CustomHeaderValue;
}
//adapted from https://stackoverflow.com/questions/33365072/mailkit-sending-drafts
using (var client = new ImapClient())
{
try
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
var draftFolder = client.GetFolder("Drafts");//Our surgemail server works with this other servers in future might not
if (draftFolder != null)
{
draftFolder.Open(FolderAccess.ReadWrite);
draftFolder.Append(message, MessageFlags.Draft);
//draftFolder.Expunge();
}
}
catch (Exception ex)
{
throw new System.Exception("RfMail->DraftMessage() - Exception has occured: " + ex.Message);
}
client.Disconnect(true);
}
}//draft message
/////////////////////////////////////////////////////////////////
//Fetch summaries of unread messages in sales and support
//inboxes
//
public static List<rfMessageSummary> GetSalesAndSupportSummaries()
{
List<rfMessageSummary> ret = new List<rfMessageSummary>();
ret.AddRange(getInboxSummariesFor(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT));
// ret.AddRange(getInboxSummariesFor(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES));
return ret;
}
private static List<rfMessageSummary> getInboxSummariesFor(string sourceAccount, string sourcePassword)
{
//Console.WriteLine($"getInboxSummariesFor {sourceAccount}");
List<rfMessageSummary> ret = new List<rfMessageSummary>();
using (var client = new ImapClient())
// using (var client = new ImapClient(new ProtocolLogger(Console.OpenStandardOutput())))
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
//Console.WriteLine($"connecting to {MAIL_IMAP_ADDRESS} on {MAIL_IMAP_PORT}");
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
//Console.WriteLine($"removing XOAUTH2");
client.AuthenticationMechanisms.Remove("XOAUTH2");
//Console.WriteLine($"authenticating...");
client.Authenticate(sourceAccount, sourcePassword);
var inbox = client.Inbox;
//Console.WriteLine($"opening inbox...");
inbox.Open(FolderAccess.ReadOnly);
for (int i = 0; i < inbox.Count; i++)
{
var message = inbox.GetMessage(i);
//Sometimes bad hombres don't set a from address so don't expect one
string sFrom = "UNKNOWN / NOT SET";
if (message.From.Count > 0)
{
sFrom = message.From[0].ToString().Replace("\"", "").Replace("<", "").Replace(">", "").Trim();
}
//get flags
var summ = inbox.Fetch(new[] { i }, MessageSummaryItems.Flags | MessageSummaryItems.UniqueId);
ret.Add(new rfMessageSummary
{
account = sourceAccount,
id = summ[0].UniqueId.Id,
subject = message.Subject,
sent = DateUtil.DateTimeOffSetNullableToEpoch(message.Date),
from = sFrom,
flags = summ[0].Flags.ToString().ToLowerInvariant()
});
//Console.WriteLine("Subject: {0}", message.Subject);
}
//This was failing with an exception
//re-wrote from an example on the mailkit page and it works fine
//so going with the new method now
// //Console.WriteLine($"fetching summaries...");
// var summaries = inbox.Fetch(0, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId);
// //Console.WriteLine($"disconnecting...");
// client.Disconnect(true);
// foreach (var summary in summaries)
// {
// //Sometimes bad hombres don't set a from address so don't expect one
// string sFrom = "UNKNOWN / NOT SET";
// if (summary.Envelope.From.Count > 0)
// {
// sFrom = summary.Envelope.From[0].ToString().Replace("\"", "").Replace("<", "").Replace(">", "").Trim();
// }
// ret.Add(new rfMessageSummary
// {
// account = sourceAccount,
// id = summary.UniqueId.Id,
// subject = summary.Envelope.Subject,
// sent = DateUtil.DateTimeOffSetNullableToEpoch(summary.Envelope.Date),
// from = sFrom,
// flags = summary.Flags.ToString().ToLowerInvariant()
// });
// }
}
//reverse the results array as emails come in oldest first order but we want oldest last
ret.Reverse();
return ret;
}
public class rfMessageSummary
{
public string account { get; set; }
public uint id { get; set; }
public string from { get; set; }
public string subject { get; set; }
public long? sent { get; set; }
public string flags { get; set; }
}
//Fetch a single string preview of message by Account / folder / UID
public static rfMessagePreview GetMessagePreview(string mailAccount, string mailFolder, uint uid)
{
using (var client = new ImapClient())
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
//client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT, true);
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
//TODO: make accounts reside in dictionary in future
// if (mailAccount == "support@ayanova.com")
// {
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
// }
// if (mailAccount == "sales@ayanova.com")
// {
// client.Authenticate(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES);
// }
var fldr = client.GetFolder(mailFolder);
fldr.Open(FolderAccess.ReadOnly);
var m = fldr.GetMessage(new UniqueId(uid));
client.Disconnect(true);
StringBuilder sb = new StringBuilder();
sb.Append("From: ");
sb.AppendLine(m.From[0].ToString().Replace("\"", "").Replace("<", "").Replace(">", "").Trim());
sb.Append("To: ");
sb.AppendLine(mailAccount);
sb.Append("Subject: ");
sb.AppendLine(m.Subject);
sb.AppendLine();
sb.AppendLine();
// sb.AppendLine(m.GetTextBody(MimeKit.Text.TextFormat.Plain));
//TODO: if it's an all html email then body will be empty, so attempt to co-erce it into some readable text because the above is not working for that
var theBody = m.GetTextBody(MimeKit.Text.TextFormat.Plain);
if (theBody == null)
{
//might be an html email, try to get the text anyway
var ht = m.HtmlBody;
if (!string.IsNullOrWhiteSpace(ht))
{
theBody = "**** HTML-ONLY MESSAGE ****";
theBody += "\r\n=-=-=-=- TEXT CONVERSION =-=-=-=-\r\n";
theBody += StripHTML(ht, true);
theBody += "\r\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
theBody += "\r\n=-=-=-=- SOURCE HTML =-=-=-=-\r\n";
theBody += ht;
theBody += "\r\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
theBody += "\r\n******* END MESSAGE *******";
}
else
{
theBody = "NO MESSAGE BODY WAS FOUND NEITHER HTML NOR TEXT";
}
}
sb.AppendLine(theBody);
rfMessagePreview preview = new rfMessagePreview();
preview.id = uid;
preview.preview = sb.ToString();
preview.isKeyRequest = m.Subject.StartsWith("Request for 30 day temporary");
return preview;
}
}//get message
public class rfMessagePreview
{
public bool isKeyRequest { get; set; }
public string preview { get; set; }
public uint id { get; set; }
}
//convert html to text
public static string StripHTML(string HTMLText, bool decode = true)
{
Regex reg = new Regex("<[^>]+>", RegexOptions.IgnoreCase);
var stripped = reg.Replace(HTMLText, "");
var ret = decode ? System.Web.HttpUtility.HtmlDecode(stripped) : stripped;
return ret.Trim();
}
/// <summary>
///
/// </summary>
/// <param name="mailAccount"></param>
/// <param name="mailFolder"></param>
/// <param name="mirrorServer"></param>
/// <returns></returns>
public static IMessageSummary GetMostRecentMessageSummary(string mailAccount, string mailFolder, bool mirrorServer)
{
using (var client = new ImapClient())
{
// Accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
//case 3667 fix for intermittent cert issue hopefully
//https://github.com/jstedfast/MailKit/issues/515#issuecomment-439438242
client.CheckCertificateRevocation = false;
//client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT, true);
// if (mirrorServer)
// client.Connect(MAIL_MIRROR_IMAP_ADDRESS, MAIL_IMAP_PORT);
// else
client.Connect(MAIL_IMAP_ADDRESS, MAIL_IMAP_PORT);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// if (mailAccount == "support@ayanova.com")
// {
client.Authenticate(FASTMAIL_ACCOUNT_SUPPORT, FASTMAIL_ACCOUNT_PASSWORD_SUPPORT);
// }
// if (mailAccount == "sales@ayanova.com")
// {
// client.Authenticate(MAIL_ACCOUNT_SALES, MAIL_ACCOUNT_PASSWORD_SALES);
// }
var fldr = client.GetFolder(mailFolder);
fldr.Open(FolderAccess.ReadOnly);
//---------------
int Count = fldr.Count;
var messages = fldr.Fetch(Count - 1, Count, MessageSummaryItems.Envelope).ToList();
//--------------
client.Disconnect(true);
if (messages.Count > 0)
return messages[0];
else
return null;
}
}//get message
/////////////////////////////////////////////////////////////////
//Validate mirroring is working
//
//
public static bool MailIsMirroringProperly()
{
//check that the mirror and master contain the same most recent message in
//Sent
//AyaNovaReceivedSubscribed
//
var SentMasterSummary = GetMostRecentMessageSummary("support@ayanova.com", "Sent", false);
var AyaNovaReceivedSubscribedSummary = GetMostRecentMessageSummary("support@ayanova.com", "AyaNovaReceivedSubscribed", false);
var SentMirrorSummary = GetMostRecentMessageSummary("support@ayanova.com", "Sent", true);
var AyaNovaReceivedSubscribedMirrorSummary = GetMostRecentMessageSummary("support@ayanova.com", "AyaNovaReceivedSubscribed", true);
return SentMasterSummary.UniqueId.Id == SentMirrorSummary.UniqueId.Id && AyaNovaReceivedSubscribedSummary.UniqueId.Id == AyaNovaReceivedSubscribedMirrorSummary.UniqueId.Id;
}
//----------------
}//eoc
}//eons