コード例 #1
0
        public async Task SendEmail(string email, string subject, string htmlMessage)
        {
            try {
                using MailKit.IMailTransport mailTransport = await CreateTransport();

                InternetAddressList fromList = new InternetAddressList();
                fromList.Add(new MailboxAddress(_Settings.SenderDisplayName, _Settings.SenderEmail));
                InternetAddressList toList = new InternetAddressList();
                toList.AddRange(email.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(ma => new MailboxAddress(ma, ma)));
                BodyBuilder bodyBuilder = new BodyBuilder();
                bodyBuilder.HtmlBody = htmlMessage;
                bodyBuilder.TextBody = htmlMessage;
                MimeMessage mimeMessage = new MimeMessage(fromList, toList, subject, bodyBuilder.ToMessageBody());
                await mailTransport.SendAsync(mimeMessage);
            }
            catch (AggregateException ae) {
                _Logger.LogError($"Aggregate exception when sending email. Email host {_Settings.SmtpMailServer}:{_Settings.SmtpPort}", ae.Flatten());
                throw;
            }
            catch (AuthenticationException authe) {
                _Logger.LogError($"Authentification failed.\n {authe.Message}\n Email host {_Settings.SmtpMailServer}:{_Settings.SmtpPort}", authe);
                throw;
            }
            catch (Exception e) {
                _Logger.LogError($"Exception of type '{e.GetType().Name}' when sending email. Email host {_Settings.SmtpMailServer}:{_Settings.SmtpPort}", e);
                throw;
            }
        }
コード例 #2
0
        private void SetRecipientsEmailAddresses(InternetAddressList list, IEnumerable <string>?addresses)
        {
            if (addresses == null)
            {
                return;
            }

            list.AddRange(addresses.Select(MailboxAddress.Parse));
        }
コード例 #3
0
        private static void CopyAddressList(MailAddressCollection sourceList, InternetAddressList targetList,
                                            MimeMessage message, HeaderId headerId)
        {
            if (sourceList == null || sourceList.Count == 0)
            {
                return;
            }

            message.Headers.Replace(headerId, string.Empty);
            targetList.AddRange(sourceList.Select(ToMailboxAddress).Where(t => t != null));
        }
コード例 #4
0
        public virtual async Task RunAsync(CancellationToken cancellationToken)
        {
            var to  = new InternetAddressList();
            var cc  = new InternetAddressList();
            var bcc = new InternetAddressList();

            var mailSender = MailMergeService.Sender; // there's always a new instance returned!

            var onBeforeSend = new EventHandler <MailSenderBeforeSendEventArgs>((sender, args) =>
            {
                to.AddRange(args.MimeMessage.To);
                cc.AddRange(args.MimeMessage.Cc);
                bcc.AddRange(args.MimeMessage.Bcc);
            });

            mailSender.OnBeforeSend += onBeforeSend;

            try
            {
                if (MailData is IEnumerable <object> mailData)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await mailSender.SendAsync <object>(MailMessage, mailData);
                }
                else
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await mailSender.SendAsync(MailMessage, MailData);
                }

                Logger.LogInformation($"Mail sent. TO: {to} - CC: {cc} - BCC: {bcc}");
            }
            catch (Exception e) when(e is TaskCanceledException || e is OperationCanceledException)
            {
                Logger.LogError(e, "Mail failure. TO: {to} - CC: {cc} - BCC: {bcc}\nSubject: {subject}\nMessage: {message}", to, cc, bcc, MailMessage.Subject, MailMessage.PlainText);
                mailSender.SendCancel();
                throw;
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Mail failure. TO: {to} - CC: {cc} - BCC: {bcc}\nSubject: {subject}\nMessage: {message}", to, cc, bcc, MailMessage.Subject, MailMessage.PlainText);
                throw;
            }
            finally
            {
                MailMergeService.Sender.OnBeforeSend -= onBeforeSend;
                to.Clear();
                cc.Clear();
                bcc.Clear();
            }
        }
コード例 #5
0
        public void TestArgumentExceptions()
        {
            var mailbox = new MailboxAddress("MimeKit Unit Tests", "*****@*****.**");
            var list    = new InternetAddressList();

            list.Add(new MailboxAddress("Example User", "*****@*****.**"));

            Assert.Throws <ArgumentNullException> (() => new InternetAddressList(null));
            Assert.Throws <ArgumentNullException> (() => list.Add(null));
            Assert.Throws <ArgumentNullException> (() => list.AddRange(null));
            Assert.Throws <ArgumentNullException> (() => list.CompareTo(null));
            Assert.Throws <ArgumentNullException> (() => list.Contains(null));
            Assert.Throws <ArgumentNullException> (() => list.CopyTo(null, 0));
            Assert.Throws <ArgumentOutOfRangeException> (() => list.CopyTo(new InternetAddress[0], -1));
            Assert.Throws <ArgumentNullException> (() => list.IndexOf(null));
            Assert.Throws <ArgumentOutOfRangeException> (() => list.Insert(-1, mailbox));
            Assert.Throws <ArgumentNullException> (() => list.Insert(0, null));
            Assert.Throws <ArgumentNullException> (() => list.Remove(null));
            Assert.Throws <ArgumentOutOfRangeException> (() => list.RemoveAt(-1));
            Assert.Throws <ArgumentOutOfRangeException> (() => list[-1] = mailbox);
            Assert.Throws <ArgumentNullException> (() => list[0]        = null);
        }
コード例 #6
0
		public void TestArgumentExceptions ()
		{
			var mailbox = new MailboxAddress ("MimeKit Unit Tests", "*****@*****.**");
			var list = new InternetAddressList ();

			list.Add (new MailboxAddress ("Example User", "*****@*****.**"));

			Assert.Throws<ArgumentNullException> (() => new InternetAddressList (null));
			Assert.Throws<ArgumentNullException> (() => list.Add (null));
			Assert.Throws<ArgumentNullException> (() => list.AddRange (null));
			Assert.Throws<ArgumentNullException> (() => list.CompareTo (null));
			Assert.Throws<ArgumentNullException> (() => list.Contains (null));
			Assert.Throws<ArgumentNullException> (() => list.CopyTo (null, 0));
			Assert.Throws<ArgumentOutOfRangeException> (() => list.CopyTo (new InternetAddress[0], -1));
			Assert.Throws<ArgumentNullException> (() => list.IndexOf (null));
			Assert.Throws<ArgumentOutOfRangeException> (() => list.Insert (-1, mailbox));
			Assert.Throws<ArgumentNullException> (() => list.Insert (0, null));
			Assert.Throws<ArgumentNullException> (() => list.Remove (null));
			Assert.Throws<ArgumentOutOfRangeException> (() => list.RemoveAt (-1));
			Assert.Throws<ArgumentOutOfRangeException> (() => list[-1] = mailbox);
			Assert.Throws<ArgumentNullException> (() => list[0] = null);
		}
コード例 #7
0
ファイル: MimeMessage.cs プロジェクト: yukine/MimeKit
		void ReloadAddressList (HeaderId id, InternetAddressList list)
		{
			// clear the address list and reload
			list.Changed -= InternetAddressListChanged;
			list.Clear ();

			foreach (var header in Headers) {
				if (header.Id != id)
					continue;

				int length = header.RawValue.Length;
				List<InternetAddress> parsed;
				int index = 0;

				if (!InternetAddressList.TryParse (Headers.Options, header.RawValue, ref index, length, false, false, out parsed))
					continue;

				list.AddRange (parsed);
			}

			list.Changed += InternetAddressListChanged;
		}
コード例 #8
0
ファイル: MimeMessage.cs プロジェクト: yukine/MimeKit
		void AddAddresses (Header header, InternetAddressList list)
		{
			int length = header.RawValue.Length;
			List<InternetAddress> parsed;
			int index = 0;

			// parse the addresses in the new header and add them to our address list
			if (!InternetAddressList.TryParse (Headers.Options, header.RawValue, ref index, length, false, false, out parsed))
				return;

			list.Changed -= InternetAddressListChanged;
			list.AddRange (parsed);
			list.Changed += InternetAddressListChanged;
		}
コード例 #9
0
        /// <summary>
        /// Asynchronously produces e-mails and notification messages for all intended recipients based on the specified event type.
        /// </summary>
        /// <param name="args">An object that holds issue-related event data.</param>
        /// <param name="cancellationToken">The token used to cancel an ongoing async operation.</param>
        /// <returns></returns>
        public override async Task ProcessAsync(SysEventArgs args, CancellationToken cancellationToken = default(CancellationToken))
        {
            // give a chance to the base message producer to process the event
            await base.ProcessAsync(args, cancellationToken);

            if (!(args is SysEventArgs <Issue> e))
            {
                throw new ArgumentException($"Must be of type {nameof(SysEventArgs<Issue>)}.", nameof(args));
            }

            var issue    = e.Data ?? throw new ArgumentNullException("Data");
            var user     = (e.User as AppUser) ?? throw new ArgumentNullException("User");
            var settings = e.ObjectState as EmailSettingsViewModel ?? throw new ArgumentNullException("ObjectState", $"ObjectState must be of type {nameof(EmailSettingsViewModel)}");

            var notifs = settings.Notifications;

            _emailNotificationsEnabled = notifs.Enabled ?? false;

            try
            {
                if (issue.User == null && e.EventType != SysEventType.IssueDeleted)
                {
                    issue = await _issueRepo.All(q => q.QueryIssues(id: issue.Id, withIncludes: true)).SingleOrDefaultAsync();
                }

                var fullName          = user.FullName();
                var userName          = user.UserName;
                var notify            = false;
                var outgoing          = settings.Outgoing;
                var from              = outgoing.FromDisplay;
                var useFromNameForAll = outgoing.UseFromNameForAll ?? false;
                var replyToAddrList   = new InternetAddressList();

                if (!string.IsNullOrWhiteSpace(outgoing.ReplyTo))
                {
                    replyToAddrList.AddRange(outgoing.ReplyTo);
                }

                EmailTemplate temp;
                var           templates = settings.Templates;

                switch (e.EventType)
                {
                case SysEventType.IssueCreated:
                {
                    // Sent to technicians when a new ticket arrives. All technicians that have permissions to the category get one of these.

                    // Ticket confirmation notification  (the one users get after submitting a new ticket)?
                    notify = notifs.TicketConfirmationNotification ?? false;

                    if (notify && user.SendEmail && user.EmailConfirmed)
                    {
                        // "Ticket confirmation" email template: Sent to the ticket-submitter after the app received his ticket.
                        temp = templates.TicketConfirmation;

                        var m = CreateMessage(
                            temp.ReplaceSubject(issue.Subject).ToString(),
                            temp.ReplaceBody(issue.Body, issue.Subject)
                            .Replace("#Numero_ticket#", $"{issue.Id}")
                            .Replace("#Articles_Base_Connaissances#", string.Empty)
                            //.Replace("#Suggested_KB_articles#", string.Empty)
                            .ToString(),
                            from,
                            to: user.Email
                            );

                        m.ReplyTo.AddRange(replyToAddrList);
                        Enqueue(WrapMessage(m, user.Id));
                    }

                    temp = templates.NewTicket;
                    var subj = temp.ReplaceSubject(issue.Subject).ToString();
                    var body = temp.ReplaceBody(issue.Body, issue.Subject).Replace("#Numero_ticket#", $"{issue.Id}").ToString();

                    from = user.GetEmailAddress();

                    // notify all admins?
                    if (notifs.NotifyAllAdmins ?? false)
                    {
                        var qry = _userRepo.All(q => q.NotDisabled().Admins().Not(user.Id).CanReceiveEmails());
                        await ForUsersAsync(qry, subj, body, from, replyToAddrList, cancellationToken);
                    }

                    // notify techs in their categories?
                    if (notifs.NotifyTechs ?? false)
                    {
                        var qry = _userRepo.All(q => q.NotDisabled().Techs().Not(user.Id).CanReceiveEmails());
                        await ForUsersAsync(qry, subj, body, from, replyToAddrList, cancellationToken);
                    }
                }
                break;

                case SysEventType.IssueAssigned:
                {
                    // Notify ALL technicians in a category when another technician TAKES a ticket
                    temp = await TemplateForUpdate($"{fullName} a pris en charge la résolution du ticket #{issue.Id}.");

                    if (user.IsTech && (notifs.NotifyAllTechsOnTechTakeOver ?? false))
                    {
                        await NotifyTechs(temp);
                    }

                    // notify ticket owner
                    NotifyOwner(temp);
                }
                break;

                case SysEventType.IssueUpdated:
                {
                    // Sent to both technicians and ticket-submitter (and all ticket-subscribers if any) when a new reply is added to the ticket
                    temp = await TemplateForUpdate($"Le ticket #{issue.Id} a été mis à jour par {fullName}.");

                    if (issue.UpdatedByUser)
                    {
                        from = user.GetEmailAddress();
                        var techsNotified = false;

                        // Notify ALL technicians in a category when a customer updates a ticket
                        // (not just the ticket-technician and ticket-subscribers)?
                        if (issue.UpdatedForTechView || (notifs.NotifyAllTechsOnCustomerUpdate ?? false))
                        {
                            await NotifyTechs(temp);

                            techsNotified = true;
                        }

                        await NotifyAssignee(temp);

                        // send to all subscribers but the submitter
                        var qry = _subsRepo.All(q => q.QueryIssueSubscribers(issue.Id).But(user.Id));

                        if (techsNotified)
                        {
                            qry = qry.NotTechs(); // exclude the techs who've been notified previously
                        }
                        await ForSubscribersAsync(qry, temp.Subject, temp.Body, from, replyToAddrList, cancellationToken);
                    }
                    else
                    {
                        // send to submitter
                        NotifyOwner(temp);

                        // send to subscribers except the owner and updater
                        var qry = _subsRepo.All(q => q.QueryIssueSubscribers(issue.Id).But(user.Id).But(issue.User.Id));

                        await ForSubscribersAsync(qry, temp.Subject, temp.Body, from, replyToAddrList, cancellationToken);
                    }
                }
                break;

                case SysEventType.IssueClosed:
                {
                    // Sent to subscribers when a ticket is closed. Note that "Ticket closed notifications" setting has to be on.
                    if (notifs.TicketClosedNotification ?? false)
                    {
                        temp = await TemplateForUpdate($"Le ticket #{issue.Id} a été fermé par {fullName}.");

                        NotifyOwner(temp);
                    }
                }

                break;

                case SysEventType.IssueReopened:
                    // no template for this scenario?
                    break;

                case SysEventType.IssueDeleted:
                    // no template for this scenario?
                    break;

                default:
                    // definitely no template for this scenario!
                    break;
                }

                Consumer.Notify();

                async Task <EmailTemplate> TemplateForUpdate(string whatHappened)
                {
                    var comments = await _commentRepo.GetAsync(q => q.QueryCommentsForIssue(issue.Id).Skip(0).Take(3).ToArray());

                    var recent = string.Empty;

                    if (comments.Length > 0)
                    {
                        try
                        {
                            recent = await _emailTemplatesViewRender.RenderToStringAsync(TEMPLATE_RECENT_COMMENTS, comments);
                        }
                        catch (Exception ex)
                        {
                            Logger.LogWarning(ex, "An error occured while rendering the recent comments e-mail template.");

                            var sb = new StringBuilder("<h3>Messages récents</h3>");

                            foreach (var c in comments)
                            {
                                sb.AppendLine();
                                sb.AppendLine(c.Body);
                            }

                            recent = sb.ReplaceLineBreaks().ToString().Trim();
                        }
                    }

                    temp = templates.TicketUpdated;
                    var subj = temp.ReplaceSubject(issue.Subject).ToString();
                    var body = temp
                               .ReplaceBody(issue.Body, issue.Subject)
                               .Replace("#Quoi_De_Neuf#", whatHappened)
                               .Replace("#Messages_recents#", recent)
                               .Replace("#Categorie#", issue.Category?.Name)
                               .Replace("#Statut#", issue.Status?.Name)
                               .Replace("#Priorite#", UtilExtensions.PriorityName(issue.Priority))
                               //.Replace("#What_Happened#", whatHappened)
                               //.Replace("#Recent_messages#", recent)
                               //.Replace("#Category#", catname)
                               //.Replace("#Status#", statname)
                               //.Replace("#Priority#", priority)
                               .ToString();

                    return(new EmailTemplate {
                        Body = body, Subject = subj
                    });
                }

                async Task NotifyTechs(EmailTemplate et)
                {
                    var qry = _userRepo.All(q => q.NotDisabled().Techs().Not(user.Id).CanReceiveEmails());

                    await ForUsersAsync(qry, et.Subject, et.Body, from, replyToAddrList, cancellationToken);
                }

                async Task NotifyAssignee(EmailTemplate et)
                {
                    if (issue.IsAssigned())
                    {
                        var owner = await _userRepo.GetAsync(q => q.Find(issue.AssignedToUserId));

                        if (owner != null)
                        {
                            EnqueueTemplate(et, owner);
                        }
                    }
                }

                void NotifyOwner(EmailTemplate et)
                {
                    var owner = issue.User;

                    if (owner.SendEmail && owner.Id != user.Id)
                    {
                        EnqueueTemplate(et, owner);
                    }
                }

                void SetFromName(AppUser u)
                {
                    if (!useFromNameForAll)
                    {
                        from = user.GetEmailAddress();
                    }
                }

                void EnqueueTemplate(EmailTemplate et, AppUser owner)
                {
                    SetFromName(owner);
                    Enqueue(WrapMessage(CreateMessage(et.Subject, et.Body, from, owner.Email), owner.Id));
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Error while producing issue e-mails in {nameof(ProcessAsync)}.");
            }
        }
コード例 #10
0
        static void SendMailMime(MailInputs maildata)
        {
            try
            {
                //---------------------
                //  Configuration

                //  User setup
                string User     = maildata.User;
                string UserName = maildata.User;
                string pssw     = maildata.Password;

                //  Server setup
                string server = maildata.Server;
                int    port   = Convert.ToInt32(maildata.Port);

                //  Mail setup
                string attachment  = maildata.Attachment;
                string MailBody    = maildata.Body;
                string MailSubject = maildata.Subject;

                string toAddressString  = maildata.To;
                string ccAddressString  = maildata.Cc;
                string bccAddressString = maildata.Bcc;

                //--------------------

                MimeMessage message = new MimeMessage();

                MailboxAddress from = new MailboxAddress(UserName, User);
                message.From.Add(from);

                if (!string.IsNullOrEmpty(toAddressString))
                {
                    InternetAddressList toList = new InternetAddressList();
                    toList.AddRange(MimeKit.InternetAddressList.Parse(toAddressString));
                    message.To.AddRange(toList);
                }


                if (!string.IsNullOrEmpty(ccAddressString))
                {
                    InternetAddressList ccList = new InternetAddressList();
                    ccList.AddRange(MimeKit.InternetAddressList.Parse(ccAddressString));
                    message.Cc.AddRange(ccList);
                }


                if (!string.IsNullOrEmpty(bccAddressString))
                {
                    InternetAddressList bccList = new InternetAddressList();
                    bccList.AddRange(MimeKit.InternetAddressList.Parse(bccAddressString));
                    message.Bcc.AddRange(bccList);
                }

                //Mail body

                BodyBuilder bodyBuilder = new BodyBuilder();
                //bodyBuilder.HtmlBody = "<h1>This is a mail body</h1>";
                message.Subject = MailSubject;
                if (!string.IsNullOrEmpty(MailBody))
                {
                    bodyBuilder.TextBody = MailBody;
                }


                //
                if (!string.IsNullOrEmpty(attachment))
                {
                    bodyBuilder.Attachments.Add(attachment);
                }

                message.Body = bodyBuilder.ToMessageBody();


                SmtpClient client = new SmtpClient();


                client.Connect(server, port, SecureSocketOptions.None);
                client.Authenticate(User, pssw);


                client.Send(message);
                client.Disconnect(true);
                client.Dispose();



                Console.WriteLine("");
                //Console.ReadLine();

                //............................
            }
            catch (Exception ep)
            {
                Console.WriteLine("failed to send email with the following error:");
                Console.WriteLine(ep.Message);
                Console.ReadLine();
            }
        }