/src/Ombi.Notifications/Agents/EmailNotification.cs

https://github.com/tidusjar/Ombi · C# · 299 lines · 247 code · 46 blank · 6 comment · 35 complexity · e66d5add7c186b22c5dd8e08724628e7 MD5 · raw file

  1. using System;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4. using MailKit.Net.Smtp;
  5. using Microsoft.AspNetCore.Identity;
  6. using Microsoft.EntityFrameworkCore;
  7. using Microsoft.Extensions.Logging;
  8. using MimeKit;
  9. using Ombi.Core.Settings;
  10. using Ombi.Helpers;
  11. using Ombi.Notifications.Models;
  12. using Ombi.Notifications.Templates;
  13. using Ombi.Settings.Settings.Models;
  14. using Ombi.Settings.Settings.Models.Notifications;
  15. using Ombi.Store.Entities;
  16. using Ombi.Store.Repository;
  17. using Ombi.Store.Repository.Requests;
  18. namespace Ombi.Notifications.Agents
  19. {
  20. public class EmailNotification : BaseNotification<EmailNotificationSettings>, IEmailNotification
  21. {
  22. public EmailNotification(ISettingsService<EmailNotificationSettings> settings, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, IEmailProvider prov, ISettingsService<CustomizationSettings> c,
  23. ILogger<EmailNotification> log, UserManager<OmbiUser> um, IRepository<RequestSubscription> sub, IMusicRequestRepository music,
  24. IRepository<UserNotificationPreferences> userPref) : base(settings, r, m, t, c, log, sub, music, userPref)
  25. {
  26. EmailProvider = prov;
  27. Logger = log;
  28. _userManager = um;
  29. }
  30. private IEmailProvider EmailProvider { get; }
  31. private ILogger<EmailNotification> Logger { get; }
  32. public override string NotificationName => nameof(EmailNotification);
  33. private readonly UserManager<OmbiUser> _userManager;
  34. protected override bool ValidateConfiguration(EmailNotificationSettings settings)
  35. {
  36. if (!settings.Enabled)
  37. {
  38. return false;
  39. }
  40. if (settings.Authentication)
  41. {
  42. if (string.IsNullOrEmpty(settings.Username) || string.IsNullOrEmpty(settings.Password))
  43. {
  44. return false;
  45. }
  46. }
  47. if (string.IsNullOrEmpty(settings.Host) || string.IsNullOrEmpty(settings.AdminEmail) || string.IsNullOrEmpty(settings.Port.ToString()))
  48. {
  49. return false;
  50. }
  51. return true;
  52. }
  53. private async Task<NotificationMessage> LoadTemplate(NotificationType type, NotificationOptions model, EmailNotificationSettings settings)
  54. {
  55. var parsed = await LoadTemplate(NotificationAgent.Email, type, model);
  56. if (parsed.Disabled)
  57. {
  58. Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Email}");
  59. return null;
  60. }
  61. var email = new EmailBasicTemplate();
  62. var html = email.LoadTemplate(parsed.Subject, parsed.Message, parsed.Image, Customization.Logo);
  63. var message = new NotificationMessage
  64. {
  65. Message = html,
  66. Subject = parsed.Subject,
  67. };
  68. if (model.Substitutes.TryGetValue("AdminComment", out var isAdminString))
  69. {
  70. var isAdmin = bool.Parse(isAdminString);
  71. if (isAdmin)
  72. {
  73. var user = _userManager.Users.FirstOrDefault(x => x.Id == model.UserId);
  74. // Send to user
  75. message.To = user.Email;
  76. }
  77. else
  78. {
  79. // Send to admin
  80. message.To = settings.AdminEmail;
  81. }
  82. }
  83. else
  84. {
  85. // Send to admin
  86. message.To = settings.AdminEmail;
  87. }
  88. return message;
  89. }
  90. private async Task<string> LoadPlainTextMessage(NotificationType type, NotificationOptions model, EmailNotificationSettings settings)
  91. {
  92. var parsed = await LoadTemplate(NotificationAgent.Email, type, model);
  93. return parsed.Message;
  94. }
  95. protected override async Task NewRequest(NotificationOptions model, EmailNotificationSettings settings)
  96. {
  97. var message = await LoadTemplate(NotificationType.NewRequest, model, settings);
  98. if (message == null)
  99. {
  100. return;
  101. }
  102. var plaintext = await LoadPlainTextMessage(NotificationType.NewRequest, model, settings);
  103. message.Other.Add("PlainTextBody", plaintext);
  104. await Send(message, settings);
  105. }
  106. protected override async Task NewIssue(NotificationOptions model, EmailNotificationSettings settings)
  107. {
  108. var message = await LoadTemplate(NotificationType.Issue, model, settings);
  109. if (message == null)
  110. {
  111. return;
  112. }
  113. var plaintext = await LoadPlainTextMessage(NotificationType.Issue, model, settings);
  114. message.Other.Add("PlainTextBody", plaintext);
  115. // Issues should be sent to admin
  116. message.To = settings.AdminEmail;
  117. await Send(message, settings);
  118. }
  119. protected override async Task IssueComment(NotificationOptions model, EmailNotificationSettings settings)
  120. {
  121. var message = await LoadTemplate(NotificationType.IssueComment, model, settings);
  122. if (message == null)
  123. {
  124. return;
  125. }
  126. var plaintext = await LoadPlainTextMessage(NotificationType.IssueComment, model, settings);
  127. message.Other.Add("PlainTextBody", plaintext);
  128. if (model.Substitutes.TryGetValue("AdminComment", out var isAdminString))
  129. {
  130. var isAdmin = bool.Parse(isAdminString);
  131. message.To = isAdmin ? model.Recipient : settings.AdminEmail;
  132. }
  133. else
  134. {
  135. message.To = model.Recipient;
  136. }
  137. await Send(message, settings);
  138. }
  139. protected override async Task IssueResolved(NotificationOptions model, EmailNotificationSettings settings)
  140. {
  141. if (!model.Recipient.HasValue())
  142. {
  143. return;
  144. }
  145. var message = await LoadTemplate(NotificationType.IssueResolved, model, settings);
  146. if (message == null)
  147. {
  148. return;
  149. }
  150. var plaintext = await LoadPlainTextMessage(NotificationType.IssueResolved, model, settings);
  151. message.Other.Add("PlainTextBody", plaintext);
  152. // Issues resolved should be sent to the user
  153. message.To = model.Recipient;
  154. await Send(message, settings);
  155. }
  156. protected override async Task AddedToRequestQueue(NotificationOptions model, EmailNotificationSettings settings)
  157. {
  158. if (!model.Recipient.HasValue())
  159. {
  160. return;
  161. }
  162. var message = await LoadTemplate(NotificationType.ItemAddedToFaultQueue, model, settings);
  163. if (message == null)
  164. {
  165. return;
  166. }
  167. var plaintext = await LoadPlainTextMessage(NotificationType.ItemAddedToFaultQueue, model, settings);
  168. message.Other.Add("PlainTextBody", plaintext);
  169. // Issues resolved should be sent to the user
  170. message.To = settings.AdminEmail;
  171. await Send(message, settings);
  172. }
  173. protected override async Task RequestDeclined(NotificationOptions model, EmailNotificationSettings settings)
  174. {
  175. var message = await LoadTemplate(NotificationType.RequestDeclined, model, settings);
  176. if (message == null)
  177. {
  178. return;
  179. }
  180. var plaintext = await LoadPlainTextMessage(NotificationType.RequestDeclined, model, settings);
  181. message.Other.Add("PlainTextBody", plaintext);
  182. await SendToSubscribers(settings, message);
  183. message.To = model.RequestType == RequestType.Movie
  184. ? MovieRequest.RequestedUser.Email
  185. : TvRequest.RequestedUser.Email;
  186. await Send(message, settings);
  187. }
  188. protected override async Task RequestApproved(NotificationOptions model, EmailNotificationSettings settings)
  189. {
  190. var message = await LoadTemplate(NotificationType.RequestApproved, model, settings);
  191. if (message == null)
  192. {
  193. return;
  194. }
  195. var plaintext = await LoadPlainTextMessage(NotificationType.RequestApproved, model, settings);
  196. message.Other.Add("PlainTextBody", plaintext);
  197. await SendToSubscribers(settings, message);
  198. message.To = model.RequestType == RequestType.Movie
  199. ? MovieRequest.RequestedUser.Email
  200. : TvRequest.RequestedUser.Email;
  201. await Send(message, settings);
  202. }
  203. private async Task SendToSubscribers(EmailNotificationSettings settings, NotificationMessage message)
  204. {
  205. if (await SubsribedUsers.AnyAsync())
  206. {
  207. foreach (var user in SubsribedUsers)
  208. {
  209. if (user.Email.IsNullOrEmpty())
  210. {
  211. continue;
  212. }
  213. message.To = user.Email;
  214. await Send(message, settings);
  215. }
  216. }
  217. }
  218. protected override async Task AvailableRequest(NotificationOptions model, EmailNotificationSettings settings)
  219. {
  220. var message = await LoadTemplate(NotificationType.RequestAvailable, model, settings);
  221. if (message == null)
  222. {
  223. return;
  224. }
  225. var plaintext = await LoadPlainTextMessage(NotificationType.RequestAvailable, model, settings);
  226. message.Other.Add("PlainTextBody", plaintext);
  227. await SendToSubscribers(settings, message);
  228. message.To = model.RequestType == RequestType.Movie
  229. ? MovieRequest.RequestedUser.Email
  230. : TvRequest.RequestedUser.Email;
  231. await Send(message, settings);
  232. }
  233. protected override async Task Send(NotificationMessage model, EmailNotificationSettings settings)
  234. {
  235. await EmailProvider.Send(model, settings);
  236. }
  237. protected override async Task Test(NotificationOptions model, EmailNotificationSettings settings)
  238. {
  239. var email = new EmailBasicTemplate();
  240. var html = email.LoadTemplate(
  241. "Test Message",
  242. "This is just a test! Success!", "", Customization.Logo);
  243. var message = new NotificationMessage
  244. {
  245. Message = html,
  246. Subject = $"Ombi: Test",
  247. To = settings.AdminEmail,
  248. };
  249. message.Other.Add("PlainTextBody", "This is just a test! Success!");
  250. await Send(message, settings);
  251. }
  252. }
  253. }