This commit is contained in:
@@ -19,9 +19,6 @@ namespace AyaNova.Biz
|
|||||||
{
|
{
|
||||||
private static bool NotifyIsRunning = false;
|
private static bool NotifyIsRunning = false;
|
||||||
private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("CoreJobNotify");
|
private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("CoreJobNotify");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static DateTime lastRun = DateTime.MinValue;
|
private static DateTime lastRun = DateTime.MinValue;
|
||||||
private static DateTime lastNotifyHealthCheckSentLocal = DateTime.MinValue;
|
private static DateTime lastNotifyHealthCheckSentLocal = DateTime.MinValue;
|
||||||
private static TimeSpan TS_24_HOURS = new TimeSpan(24, 0, 0);//used to ensure daily ops happen no more than that
|
private static TimeSpan TS_24_HOURS = new TimeSpan(24, 0, 0);//used to ensure daily ops happen no more than that
|
||||||
@@ -32,12 +29,6 @@ namespace AyaNova.Biz
|
|||||||
private static TimeSpan RUN_EVERY_INTERVAL = new TimeSpan(0, 2, 0);//no more frequently than once every 2 minutes
|
private static TimeSpan RUN_EVERY_INTERVAL = new TimeSpan(0, 2, 0);//no more frequently than once every 2 minutes
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//temporary list to hold translations as required during delivery
|
|
||||||
private static Dictionary<long, List<NameIdItem>> _NotifyEventTypeTransCache = new Dictionary<long, List<NameIdItem>>();
|
|
||||||
private static Dictionary<long, List<NameIdItem>> _AyaTypeTypeTransCache = new Dictionary<long, List<NameIdItem>>();
|
|
||||||
private static Dictionary<long, long> _UserTranslationIdCache = new Dictionary<long, long>();
|
|
||||||
private static Dictionary<long, string> _ServerTheWordTranslations = new Dictionary<long, string>();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// DoSweep
|
// DoSweep
|
||||||
//
|
//
|
||||||
@@ -52,7 +43,7 @@ namespace AyaNova.Biz
|
|||||||
//This will get triggered roughly every minute, but we don't want to deliver that frequently
|
//This will get triggered roughly every minute, but we don't want to deliver that frequently
|
||||||
if (DateTime.UtcNow - lastRun < RUN_EVERY_INTERVAL)
|
if (DateTime.UtcNow - lastRun < RUN_EVERY_INTERVAL)
|
||||||
{
|
{
|
||||||
log.LogTrace($"Notify ran less than {RUN_EVERY_INTERVAL}, exiting this cycle");
|
log.LogTrace($"Notify ran less than {RUN_EVERY_INTERVAL} ago, exiting this cycle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
@@ -79,29 +70,10 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
|
|
||||||
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||||
{
|
{
|
||||||
var events = await ct.NotifyEvent.AsNoTracking().ToListAsync();
|
var events = await ct.NotifyEvent.AsNoTracking().ToListAsync();
|
||||||
log.LogTrace($"Found {events.Count} NotifyEvents to examine for potential delivery");
|
log.LogTrace($"Found {events.Count} NotifyEvents to examine for potential delivery");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//###########################
|
|
||||||
//TODO: All this needs to be moved into smtp delivery and cache populated on demand rather than up front
|
|
||||||
// //cache translations
|
|
||||||
// //Get all subscription unique userId's that aren't inapp deliveries
|
|
||||||
// var usersNeedingTranslations = events.Where(z => z.NotifySubscription.DeliveryMethod != NotifyDeliveryMethod.App && z.User.Active).Select(z => z.NotifySubscription.UserId).ToList().Distinct();
|
|
||||||
// foreach (long userid in usersNeedingTranslations)
|
|
||||||
// {
|
|
||||||
// var usr = await ct.User.AsNoTracking().Include(z => z.UserOptions).SingleAsync(z => z.Id == userid);
|
|
||||||
// long transId = usr.UserOptions.TranslationId;
|
|
||||||
|
|
||||||
// _UserTranslationIdCache.Add(userid, transId);
|
|
||||||
// await CacheTranslations(transId, usr.Roles);
|
|
||||||
// }
|
|
||||||
// //cache all translations of the word "Server" for server notifications
|
|
||||||
// _ServerTheWordTranslations = await TranslationBiz.GetAllTranslationsForKey("Server");
|
|
||||||
//################################
|
|
||||||
|
|
||||||
//iterate and deliver
|
//iterate and deliver
|
||||||
foreach (var notifyevent in events)
|
foreach (var notifyevent in events)
|
||||||
{
|
{
|
||||||
@@ -140,10 +112,7 @@ namespace AyaNova.Biz
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
log.LogTrace("Notify is done setting to not running state and tagging lastRun timestamp");
|
log.LogTrace("Notify is done setting to not running state and tagging lastRun timestamp");
|
||||||
_UserTranslationIdCache.Clear();
|
|
||||||
_NotifyEventTypeTransCache.Clear();
|
|
||||||
_AyaTypeTypeTransCache.Clear();
|
|
||||||
lastRun = DateTime.UtcNow;
|
lastRun = DateTime.UtcNow;
|
||||||
NotifyIsRunning = false;
|
NotifyIsRunning = false;
|
||||||
|
|
||||||
@@ -151,36 +120,6 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//cache any translations required for email notification
|
|
||||||
private static async Task CacheTranslations(long translationId, AuthorizationRoles roles)
|
|
||||||
{
|
|
||||||
if (!_NotifyEventTypeTransCache.ContainsKey(translationId))
|
|
||||||
_NotifyEventTypeTransCache.Add(translationId, await AyaNova.Api.Controllers.EnumListController.GetEnumList(
|
|
||||||
"NotifyEventType",
|
|
||||||
translationId,
|
|
||||||
roles));
|
|
||||||
|
|
||||||
if (!_AyaTypeTypeTransCache.ContainsKey(translationId))
|
|
||||||
_AyaTypeTypeTransCache.Add(
|
|
||||||
translationId,
|
|
||||||
await AyaNova.Api.Controllers.EnumListController.GetEnumList(
|
|
||||||
"AyaType",
|
|
||||||
translationId,
|
|
||||||
roles));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//Used for subject of email and message deliveries
|
|
||||||
private static string GetTranslatedNotifyEventName(NotifyEventType net, long translationId)
|
|
||||||
{
|
|
||||||
return _NotifyEventTypeTransCache.First(z => z.Key == translationId).Value.First(z => z.Id == (int)net).Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetTranslatedAyaTypeName(AyaType at, long translationId)
|
|
||||||
{
|
|
||||||
return _AyaTypeTypeTransCache.First(z => z.Key == translationId).Value.First(z => z.Id == (int)at).Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task DeliverInApp(NotifyEvent ne, AyContext ct)
|
private static async Task DeliverInApp(NotifyEvent ne, AyContext ct)
|
||||||
{
|
{
|
||||||
log.LogTrace($"DeliverInApp notify event: {ne}");
|
log.LogTrace($"DeliverInApp notify event: {ne}");
|
||||||
@@ -188,65 +127,72 @@ namespace AyaNova.Biz
|
|||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
ct.NotifyEvent.Remove(ne);
|
ct.NotifyEvent.Remove(ne);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static async Task DeliverSMTP(NotifyEvent ne, NotifySubscription sub, AyContext ct)
|
private static async Task DeliverSMTP(NotifyEvent ne, NotifySubscription sub, AyContext ct)
|
||||||
{
|
{
|
||||||
|
|
||||||
//TODO: UNCOMMENT THE FOLLOWING AND ADD CACHING AS PER ABOVE
|
|
||||||
log.LogTrace($"DeliverSMTP delivering notify event: {ne}");
|
|
||||||
if (string.IsNullOrWhiteSpace(sub.DeliveryAddress))
|
|
||||||
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"No email address is set in subscription to deliver email notification for this event:{ne}", "Error", null, ne.UserId);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var transid = _UserTranslationIdCache[sub.UserId];
|
|
||||||
var name = ne.Name;
|
|
||||||
if (name == "~SERVER~")
|
|
||||||
name = _ServerTheWordTranslations.First(z => z.Key == transid).Value;
|
|
||||||
|
|
||||||
|
|
||||||
//AyaType translation
|
|
||||||
var AyaTypeTranslated = string.Empty;
|
|
||||||
if (ne.AyaType != AyaType.NoType)
|
|
||||||
AyaTypeTranslated = $":{GetTranslatedAyaTypeName(ne.AyaType, transid)}";
|
|
||||||
|
|
||||||
var subject = $"AY{AyaTypeTranslated}:{GetTranslatedNotifyEventName(ne.EventType, transid)}:{name}";
|
|
||||||
|
|
||||||
//subscription link translation
|
|
||||||
var SubscriptionTypeName = GetTranslatedAyaTypeName(AyaType.NotifySubscription, transid);
|
|
||||||
|
|
||||||
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var body = "";
|
log.LogTrace($"DeliverSMTP delivering notify event: {ne}");
|
||||||
//NOTE: if need any other exemptions besides backup status make a separate static function "CanOpen(NotifyEventType)"
|
if (string.IsNullOrWhiteSpace(sub.DeliveryAddress))
|
||||||
|
|
||||||
if (ne.ObjectId != 0 || ne.EventType == NotifyEventType.BackupStatus)
|
|
||||||
{
|
{
|
||||||
body = OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId, ne.EventType) + "\n";
|
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"No email address is set in subscription to deliver email notification. This event will be removed from the delivery queue as undeliverable: {ne}", "Error", null, ne.UserId);
|
||||||
}
|
|
||||||
body += ne.Message;
|
|
||||||
|
|
||||||
//Add link to subscription
|
|
||||||
//http://localhost:8080/open/51/1 //add subscription link, notifysub is object type 51
|
|
||||||
if (!body.EndsWith('\n'))
|
|
||||||
body += "\n";
|
|
||||||
|
|
||||||
body += $"-----\n({SubscriptionTypeName}: {OpenSubscriptionUrlBuilder(ne.NotifySubscriptionId)} )\n";
|
|
||||||
|
|
||||||
if (!ServerGlobalOpsSettingsCache.Notify.SmtpDeliveryActive)
|
|
||||||
{
|
|
||||||
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"Email notifications are set to OFF at server, unable to send email notification for this event:{ne}", "Error", null, ne.UserId);
|
|
||||||
log.LogInformation($"** WARNING: SMTP notification is currently set to Active=False; unable to deliver email notification, re-routed to in-app notification instead [UserId={ne.UserId}, Notify subscription={ne.NotifySubscriptionId}]. Change this setting or have users remove email delivery notifications if this is permanent **");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await m.SendEmailAsync(sub.DeliveryAddress, subject, body, ServerGlobalOpsSettingsCache.Notify);
|
//Email notification requires pre-translated values
|
||||||
|
List<string> TranslationKeysToFetch = new List<string>();
|
||||||
|
TranslationKeysToFetch.Add(ne.AyaType.ToString());
|
||||||
|
if (ne.Name == "~SERVER~")
|
||||||
|
TranslationKeysToFetch.Add("Server");
|
||||||
|
var EventTypeTranslationKey = "NotifyEvent" + ne.EventType.ToString();
|
||||||
|
TranslationKeysToFetch.Add(EventTypeTranslationKey);
|
||||||
|
var transid = await ct.UserOptions.AsNoTracking().Where(x => x.UserId == sub.UserId).Select(x => x.TranslationId).FirstOrDefaultAsync();
|
||||||
|
var LT = await TranslationBiz.GetSubsetStaticAsync(TranslationKeysToFetch, transid);
|
||||||
|
|
||||||
|
var name = ne.Name;
|
||||||
|
if (name == "~SERVER~")
|
||||||
|
name = LT["Server"];
|
||||||
|
|
||||||
|
//AyaType translation
|
||||||
|
var AyaTypeTranslated = string.Empty;
|
||||||
|
if (ne.AyaType != AyaType.NoType)
|
||||||
|
AyaTypeTranslated = $":{LT[ne.AyaType.ToString()]}";
|
||||||
|
|
||||||
|
var subject = $"AY{AyaTypeTranslated}:{LT[EventTypeTranslationKey]}:{name}";
|
||||||
|
|
||||||
|
//subscription link translation
|
||||||
|
var SubscriptionTypeName = AyaTypeTranslated;
|
||||||
|
|
||||||
|
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
||||||
|
|
||||||
|
var body = "";
|
||||||
|
//NOTE: if need any other exemptions besides backup status make a separate static function "CanOpen(NotifyEventType)"
|
||||||
|
|
||||||
|
if (ne.ObjectId != 0 || ne.EventType == NotifyEventType.BackupStatus)
|
||||||
|
{
|
||||||
|
body = OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId, ne.EventType) + "\n";
|
||||||
|
}
|
||||||
|
body += ne.Message;
|
||||||
|
|
||||||
|
//Add link to subscription
|
||||||
|
//http://localhost:8080/open/51/1 //add subscription link, notifysub is object type 51
|
||||||
|
if (!body.EndsWith('\n'))
|
||||||
|
body += "\n";
|
||||||
|
|
||||||
|
body += $"-----\n({SubscriptionTypeName}: {OpenSubscriptionUrlBuilder(ne.NotifySubscriptionId)} )\n";
|
||||||
|
|
||||||
|
if (!ServerGlobalOpsSettingsCache.Notify.SmtpDeliveryActive)
|
||||||
|
{
|
||||||
|
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"Email notifications are set to OFF at server, unable to send email notification for this event:{ne}", "Error", null, ne.UserId);
|
||||||
|
log.LogInformation($"** WARNING: SMTP notification is currently set to Active=False; unable to deliver email notification, re-routed to in-app notification instead [UserId={ne.UserId}, Notify subscription={ne.NotifySubscriptionId}]. Change this setting or have users remove email delivery notifications if this is permanent **");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await m.SendEmailAsync(sub.DeliveryAddress, subject, body, ServerGlobalOpsSettingsCache.Notify);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
Reference in New Issue
Block a user