| | 486 | |
| | 487 | {{{ |
| | 488 | public class EmailService : IIdentityMessageService |
| | 489 | { |
| | 490 | private readonly string _host; |
| | 491 | private readonly int _port; |
| | 492 | private readonly string _username; |
| | 493 | private readonly string _password; |
| | 494 | private readonly bool _enableSsl; |
| | 495 | private readonly string _from; |
| | 496 | private readonly string _fromDisplay; |
| | 497 | |
| | 498 | public EmailService() |
| | 499 | { |
| | 500 | _host = ConfigurationManager.AppSettings["Smtp:Host"] ?? Environment.GetEnvironmentVariable("SMTP_HOST"); |
| | 501 | _port = ParseInt(ConfigurationManager.AppSettings["Smtp:Port"]) |
| | 502 | ?? ParseInt(Environment.GetEnvironmentVariable("SMTP_PORT")) ?? 587; |
| | 503 | _username = ConfigurationManager.AppSettings["Smtp:Username"] ?? Environment.GetEnvironmentVariable("SMTP_USER"); |
| | 504 | _password = ConfigurationManager.AppSettings["Smtp:Password"] ?? Environment.GetEnvironmentVariable("SMTP_PASS"); |
| | 505 | _enableSsl = ParseBool(ConfigurationManager.AppSettings["Smtp:EnableSsl"]) |
| | 506 | ?? ParseBool(Environment.GetEnvironmentVariable("SMTP_ENABLESSL")) ?? true; |
| | 507 | _from = ConfigurationManager.AppSettings["Email:From"] ?? _username ?? Environment.GetEnvironmentVariable("EMAIL_FROM"); |
| | 508 | _fromDisplay = ConfigurationManager.AppSettings["Email:FromDisplayName"] ?? "Најди Ментор"; |
| | 509 | } |
| | 510 | |
| | 511 | private int? ParseInt(string s) => int.TryParse(s, out var v) ? (int?)v : null; |
| | 512 | private bool? ParseBool(string s) => bool.TryParse(s, out var v) ? (bool?)v : null; |
| | 513 | |
| | 514 | // Called by ASP.NET Identity when it needs to send e-mail (confirmations, password reset, etc.) |
| | 515 | public async Task SendAsync(IdentityMessage message) |
| | 516 | { |
| | 517 | if (message == null) throw new ArgumentNullException(nameof(message)); |
| | 518 | await SendEmailAsync(message.Destination, message.Subject, message.Body, null).ConfigureAwait(false); |
| | 519 | } |
| | 520 | |
| | 521 | public async Task SendEmailAsync(string toEmail, string subject, string htmlBody, string plainBody = null) |
| | 522 | { |
| | 523 | if (string.IsNullOrWhiteSpace(_host)) |
| | 524 | throw new InvalidOperationException("SMTP host is not configured (Smtp:Host)."); |
| | 525 | |
| | 526 | if (string.IsNullOrWhiteSpace(toEmail)) |
| | 527 | throw new ArgumentException("toEmail required", nameof(toEmail)); |
| | 528 | |
| | 529 | var mail = new MailMessage |
| | 530 | { |
| | 531 | From = new MailAddress(_from ?? _username, _fromDisplay), |
| | 532 | Subject = subject ?? string.Empty, |
| | 533 | BodyEncoding = Encoding.UTF8, |
| | 534 | SubjectEncoding = Encoding.UTF8, |
| | 535 | IsBodyHtml = true, |
| | 536 | Body = htmlBody ?? string.Empty |
| | 537 | }; |
| | 538 | |
| | 539 | if (!string.IsNullOrEmpty(plainBody)) |
| | 540 | mail.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(plainBody, null, "text/plain")); |
| | 541 | |
| | 542 | mail.To.Add(toEmail); |
| | 543 | |
| | 544 | using (var client = new SmtpClient(_host, _port)) |
| | 545 | { |
| | 546 | client.EnableSsl = _enableSsl; |
| | 547 | if (!string.IsNullOrEmpty(_username)) |
| | 548 | client.Credentials = new NetworkCredential(_username, _password); |
| | 549 | |
| | 550 | await client.SendMailAsync(mail).ConfigureAwait(false); |
| | 551 | } |
| | 552 | } |
| | 553 | } |
| | 554 | }}} |
| | 555 | |
| | 556 | Пример на имплементација внатре во {{{ public async Task<ActionResult> SendContact(MentorContact model) }}} , односно контролерот за испраќање на контакт кон менторот. |
| | 557 | |
| | 558 | {{{ |
| | 559 | |
| | 560 | // Email mentor |
| | 561 | try |
| | 562 | { |
| | 563 | var mentor = db.Users.OfType<Mentor>().FirstOrDefault(m => m.Id == model.MentorId); |
| | 564 | if (mentor != null && !string.IsNullOrEmpty(mentor.Email)) |
| | 565 | { |
| | 566 | string selectedTopicTitle = null; |
| | 567 | if (model.TopicSuggestionId.HasValue) |
| | 568 | { |
| | 569 | var ts = db.TopicSuggestions.Find(model.TopicSuggestionId.Value); |
| | 570 | if (ts != null) selectedTopicTitle = ts.Title; |
| | 571 | } |
| | 572 | |
| | 573 | var subject = "Ново барање за контакт на NajdiMentor"; |
| | 574 | var body = $@" |
| | 575 | <p>Почитуван/а {HttpUtility.HtmlEncode(mentor.Name)} {HttpUtility.HtmlEncode(mentor.Surname)},</p> |
| | 576 | <p>Добијавте ново барање за менторство од <strong>{HttpUtility.HtmlEncode(student.Name)} {HttpUtility.HtmlEncode(student.Surname)}</strong>.</p> |
| | 577 | <p><strong>Предмет:</strong> {HttpUtility.HtmlEncode(model.SubjectName ?? "—")}</p> |
| | 578 | <p><strong>Тип:</strong> {HttpUtility.HtmlEncode(model.Type ?? "—")}<br/> |
| | 579 | <strong>Големина на тим:</strong> {(model.TeamSize.HasValue ? model.TeamSize.Value.ToString() : "—")}</p> |
| | 580 | " + (selectedTopicTitle != null ? $"<p><strong>Предлог тема:</strong> {HttpUtility.HtmlEncode(selectedTopicTitle)}</p>" : $"<p><strong>Предлог тема:</strong> —</p>") + |
| | 581 | $@" |
| | 582 | <p>Порака:<br/>{HttpUtility.HtmlEncode(model.Message)}</p> |
| | 583 | <p>Прегледајте го барањето: <a href='{Url.Action("Inbox", "Account", null, Request?.Url?.Scheme)}'>Inbox</a></p> |
| | 584 | <hr/><p>Ова е автоматска порака.</p>"; |
| | 585 | |
| | 586 | await _emailService.SendEmailAsync(mentor.Email, subject, body); |
| | 587 | } |
| | 588 | } |
| | 589 | catch (Exception ex) |
| | 590 | { |
| | 591 | System.Diagnostics.Debug.WriteLine("Email send failed (SendContact): " + ex); |
| | 592 | } |
| | 593 | |
| | 594 | }}} |