示例#1
0
        ///<summary>Helper method that creates a new MIME message based on the parameters (to, cc, bcc, from, and body)</summary>
        private static MimeMessage CreateMIMEMsg(BasicEmailAddress emailAddress, BasicEmailMessage emailMessage)
        {
            MimeMessage mimeMsg   = new MimeMessage();
            Multipart   multipart = new Multipart();

            mimeMsg.From.Add(new MailboxAddress(emailAddress.EmailUsername));
            if (!emailMessage.Subject.IsNullOrEmpty())
            {
                mimeMsg.Subject = emailMessage.Subject;
            }
            //Create MailAddress objects for all addresses.
            //MailAddress will automatically parse out "DisplayName" <*****@*****.**> and every variation
            MailAddress toAddress = new MailAddress(emailMessage.ToAddress.Trim());

            mimeMsg.To.Add(new MailboxAddress(toAddress.DisplayName, toAddress.Address));
            if (!emailMessage.CcAddress.IsNullOrEmpty())
            {
                MailAddress ccAddress = new MailAddress(emailMessage.CcAddress.Trim());
                mimeMsg.Cc.Add(new MailboxAddress(ccAddress.DisplayName, ccAddress.Address));
            }
            if (!emailMessage.BccAddress.IsNullOrEmpty())
            {
                MailAddress bccAddress = new MailAddress(emailMessage.BccAddress.Trim());
                mimeMsg.Cc.Add(new MailboxAddress(bccAddress.DisplayName, bccAddress.Address));
            }
            if (emailMessage.ListAttachments != null)
            {
                foreach (Tuple <string, string> attachmentPath in emailMessage.ListAttachments)
                {
                    multipart.Add(new MimePart()
                    {
                        Content                 = new MimeContent(File.OpenRead(attachmentPath.Item1)),
                        ContentDisposition      = new ContentDisposition(ContentDisposition.Attachment),
                        ContentTransferEncoding = ContentEncoding.Base64,
                        FileName                = Path.GetFileName(attachmentPath.Item1)
                    });
                }
            }
            if (emailMessage.IsHtml)
            {
                multipart.Add(new TextPart(MimeKit.Text.TextFormat.Html)
                {
                    Text = emailMessage.HtmlBody
                });
            }
            else
            {
                multipart.Add(new TextPart()
                {
                    Text = emailMessage.BodyText
                });
            }
            mimeMsg.Body = multipart;
            return(mimeMsg);
        }
示例#2
0
        ///<summary>Helper method that returns a ready-to-send Gmail Message</summary>
        private static GmailApi.Data.Message CreateGmailMsg(BasicEmailAddress emailAddress, BasicEmailMessage emailMessage)
        {
            MimeKit.MimeMessage mimeMsg = CreateMIMEMsg(emailAddress, emailMessage);
            using Stream stream = new MemoryStream();
            mimeMsg.WriteTo(stream);
            stream.Position       = 0;
            using StreamReader sr = new StreamReader(stream);
            GmailApi.Data.Message gMsg = new GmailApi.Data.Message();
            string rawString           = sr.ReadToEnd();

            byte[] raw = System.Text.Encoding.UTF8.GetBytes(rawString);
            gMsg.Raw = System.Convert.ToBase64String(raw);
            //What we send to Gmail must be a Base64 File/URL safe string.  We must convert our base64 to be URL safe. (replace - and _ with + and / respectively)
            gMsg.Raw = gMsg.Raw.Replace("+", "-");
            gMsg.Raw = gMsg.Raw.Replace("/", "_");
            return(gMsg);
        }
示例#3
0
 ///<summary>Throws exceptions if failing to send emails or authenticate with Google.</summary>
 private static void SendEmailOAuth(BasicEmailAddress address, BasicEmailMessage message)
 {
     using GmailApi.GmailService gService = GoogleApiConnector.CreateGmailService(address);
     try {
         GmailApi.Data.Message gmailMessage = CreateGmailMsg(address, message);
         gService.Users.Messages.Send(gmailMessage, address.EmailUsername).Execute();
     }
     catch (GoogleApiException gae) {
         gae.DoNothing();
         //This will bubble up to the UI level and be caught in a copypaste box.
         throw new Exception("Unable to authenticate with Google: " + gae.Message);
     }
     catch (Exception ex) {
         //This will bubble up to the UI level and be caught in a copypaste box.
         throw new Exception($"Error sending email with OAuth authorization: {ex.Message}");
     }
 }
示例#4
0
 ///<summary>Throws exceptions. Attempts to physically send the message over the network wire. This is used from wherever email needs to be
 ///sent throughout the program. If a message must be encrypted, then encrypt it before calling this function. nameValueCollectionHeaders can
 ///be null.</summary>
 public static void WireEmailUnsecure(BasicEmailAddress address, BasicEmailMessage emailMessage, NameValueCollection nameValueCollectionHeaders,
                                      params AlternateView[] arrayAlternateViews)
 {
     //For now we only support OAuth for Gmail but this may change in the future.
     if (!address.AccessToken.IsNullOrEmpty() && address.SMTPserver == "smtp.gmail.com")
     {
         SendEmailOAuth(address, emailMessage);
     }
     else
     {
         bool isImplicitSsl = (address.ServerPort == 465);
         if (isImplicitSsl)                 //Microsoft CDO supports implicit SSL, System.Net.Mail.SmtpClient only supports explicit SSL.
         {
             var cdo = new Message();
             var cfg = cdo.Configuration;
             cfg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"].Value       = address.SMTPserver;
             cfg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"].Value   = address.ServerPort;
             cfg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"].Value        = "2";           //sendusing: 1=pickup, 2=port, 3=using microsoft exchange
             cfg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"].Value = "1";           //0=anonymous,1=clear text auth,2=context (NTLM)
             cfg.Fields["http://schemas.microsoft.com/cdo/configuration/sendusername"].Value     = address.EmailUsername.Trim();
             cfg.Fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"].Value     = address.EmailPassword;
             cfg.Fields["http://schemas.microsoft.com/cdo/configuration/smtpusessl"].Value       = true;            //false was also tested and does not work
             if (nameValueCollectionHeaders != null)
             {
                 //How to add headers which do not have formal fields - https://msdn.microsoft.com/en-us/library/ms526317(v=exchg.10).aspx
                 string[] arrayHeaderKeys = nameValueCollectionHeaders.AllKeys;
                 for (int i = 0; i < arrayHeaderKeys.Length; i++)                     //Needed for Direct Acks to work.
                 {
                     string headerName  = arrayHeaderKeys[i];
                     string headerValue = nameValueCollectionHeaders[headerName];
                     cfg.Fields["urn:schemas:mailheader:" + headerName].Value = headerValue;
                 }
             }
             cfg.Fields.Update();
             cdo.From = emailMessage.FromAddress.Trim();
             if (!string.IsNullOrWhiteSpace(emailMessage.ToAddress))
             {
                 cdo.To = emailMessage.ToAddress.Trim();
             }
             if (!string.IsNullOrWhiteSpace(emailMessage.CcAddress))
             {
                 cdo.CC = emailMessage.CcAddress.Trim();
             }
             if (!string.IsNullOrWhiteSpace(emailMessage.BccAddress))
             {
                 cdo.BCC = emailMessage.BccAddress.Trim();
             }
             cdo.Subject = emailMessage.Subject;
             if (emailMessage.IsHtml)
             {
                 cdo.HTMLBody = emailMessage.HtmlBody;
                 if (!emailMessage.ListHtmlImages.IsNullOrEmpty())
                 {
                     foreach (string imagePath in emailMessage.ListHtmlImages)
                     {
                         var imgAttach = cdo.AddAttachment(imagePath);
                         imgAttach.Fields["urn:schemas:mailheader:content-id"].Value = HttpUtility.UrlEncode(Path.GetFileName(imagePath));
                         imgAttach.Fields.Update();
                     }
                 }
             }
             else
             {
                 cdo.TextBody = emailMessage.BodyText;
             }
             if (!emailMessage.ListAttachments.IsNullOrEmpty())
             {
                 foreach (Tuple <string, string> attachmentPath in emailMessage.ListAttachments)
                 {
                     var cdoatt = cdo.AddAttachment(attachmentPath.Item1);
                     //Use actual file name for this field.
                     cdoatt.Fields["urn:schemas:mailheader:content-id"].Value = Path.GetFileName(attachmentPath.Item1);
                     cdoatt.Fields.Update();
                 }
             }
             cdo.Send();
         }
         else                  //No SSL or explicit SSL on port 587
         {
             SmtpClient  client  = null;
             MailMessage message = null;
             try {
                 client = new SmtpClient(address.SMTPserver, address.ServerPort);
                 //The default credentials are not used by default, according to:
                 //http://msdn2.microsoft.com/en-us/library/system.net.mail.smtpclient.usedefaultcredentials.aspx
                 client.Credentials    = new NetworkCredential(address.EmailUsername.Trim(), address.EmailPassword);
                 client.DeliveryMethod = SmtpDeliveryMethod.Network;
                 client.EnableSsl      = address.UseSSL;
                 client.Timeout        = 180000;               //3 minutes
                 message = BasicEmailMessageToMailMessage(emailMessage, nameValueCollectionHeaders, arrayAlternateViews);
                 client.Send(message);
             }
             finally {
                 //Dispose of the client and messages here. For large customers, sending thousands of emails will start to fail until they restart the
                 //app. Freeing memory here can prevent OutOfMemoryExceptions.
                 client?.Dispose();
                 if (message != null)
                 {
                     if (message.Attachments != null)
                     {
                         message.Attachments.ForEach(x => x.Dispose());
                     }
                     message.Dispose();
                 }
             }
         }
     }
 }