This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
@@ -133,21 +134,21 @@ namespace AyaNova.Api.Controllers
|
|||||||
return BadRequest(new ApiErrorResponse(ModelState));
|
return BadRequest(new ApiErrorResponse(ModelState));
|
||||||
}
|
}
|
||||||
|
|
||||||
var ret = await ct.NotifyEvent.AsNoTracking().Include(z => z.NotifySubscription).Include(z=>z.User).Select(z => new
|
var ret = new List<NotifyEventQueueItem>();
|
||||||
|
var NotifyEvents = await ct.NotifyEvent.AsNoTracking().ToListAsync();
|
||||||
|
foreach (NotifyEvent ne in NotifyEvents)
|
||||||
{
|
{
|
||||||
z.Id,
|
var UserInfo = await ct.User.AsNoTracking().Where(x => x.Id == ne.UserId).Select(x => new { Active = x.Active, Name = x.Name }).FirstOrDefaultAsync();
|
||||||
z.Created,
|
var Subscription = await ct.NotifySubscription.AsNoTracking().FirstOrDefaultAsync(x => x.Id == ne.NotifySubscriptionId);
|
||||||
z.EventDate,
|
|
||||||
DeliverAfter = (z.EventDate + z.NotifySubscription.AgeValue - z.NotifySubscription.AdvanceNotice),
|
ret.Add(new NotifyEventQueueItem(ne.Id, ne.Created, ne.EventDate, (ne.EventDate + Subscription.AgeValue - Subscription.AdvanceNotice), ne.UserId, UserInfo.Name, ne.EventType, ne.AyaType, ne.Name));
|
||||||
z.UserId,
|
}
|
||||||
user=z.User.Name,
|
|
||||||
z.EventType,
|
|
||||||
z.AyaType,
|
|
||||||
z.Name
|
|
||||||
}).ToListAsync();
|
|
||||||
return Ok(ApiOkResponse.Response(ret));
|
return Ok(ApiOkResponse.Response(ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record NotifyEventQueueItem(long Id, DateTime Created, DateTime EventDate, DateTime DeliverAfter, long UserId, string User, NotifyEventType EventType, AyaType AyaType, string Name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete pending notification event
|
/// Delete pending notification event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -104,36 +104,46 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
//All items have an event date, for non time delayed events it's just the moment it was created
|
//All items have an event date, for non time delayed events it's just the moment it was created
|
||||||
//which will predate this moment now if it's pre-existing
|
//which will predate this moment now if it's pre-existing
|
||||||
var events = await ct.NotifyEvent.Include(z => z.User).Include(z => z.NotifySubscription).AsNoTracking().ToListAsync();
|
//var events = await ct.NotifyEvent.AsNoTracking().Include(z => z.User).Include(z => z.NotifySubscription).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");
|
||||||
|
|
||||||
//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);
|
//###########################
|
||||||
}
|
//TODO: All this needs to be moved into smtp delivery and cache populated on demand rather than up front
|
||||||
//cache all translations of the word "Server" for server notifications
|
// //cache translations
|
||||||
_ServerTheWordTranslations = await TranslationBiz.GetAllTranslationsForKey("Server");
|
// //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)
|
||||||
{
|
{
|
||||||
//no notifications for inactive users, just delete it as if it was delivered
|
//no notifications for inactive users, just delete it as if it was delivered
|
||||||
if (!notifyevent.User.Active)
|
// if (!notifyevent.User.Active)
|
||||||
|
var UserInfo = await ct.User.AsNoTracking().Where(x => x.Id == notifyevent.UserId).Select(x => new { Active = x.Active, Name = x.Name }).FirstOrDefaultAsync();
|
||||||
|
if (!UserInfo.Active)
|
||||||
{
|
{
|
||||||
log.LogTrace($"Inactive user {notifyevent.User.Name}, removing notify rather than delivering it: {notifyevent}");
|
log.LogTrace($"Inactive user {UserInfo.Name}, removing notify rather than delivering it: {notifyevent}");
|
||||||
ct.NotifyEvent.Remove(notifyevent);
|
ct.NotifyEvent.Remove(notifyevent);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Get subscription for delivery
|
||||||
|
var Subscription = await ct.NotifySubscription.AsNoTracking().FirstOrDefaultAsync(x => x.Id == notifyevent.NotifySubscriptionId);
|
||||||
|
|
||||||
//TIME DELAYED AGED EVENT?
|
//TIME DELAYED AGED EVENT?
|
||||||
//when to time delay deliver formula:If sub.agevalue!= timespan.zero then deliver on =
|
//when to time delay deliver formula:If sub.agevalue!= timespan.zero then deliver on =
|
||||||
@@ -147,36 +157,17 @@ namespace AyaNova.Biz
|
|||||||
// All events have an event date, it's either immediate upon creation or it's future
|
// All events have an event date, it's either immediate upon creation or it's future
|
||||||
//but not all events ahve an age value including ones with future event dates,
|
//but not all events ahve an age value including ones with future event dates,
|
||||||
// and the default agevalue and advancenotice are both zero regardless so the block below works for either future or immediate deliveries
|
// and the default agevalue and advancenotice are both zero regardless so the block below works for either future or immediate deliveries
|
||||||
// if (notifyevent.NotifySubscription.AgeValue != TimeSpan.Zero)
|
|
||||||
// {
|
|
||||||
var deliverAfter = notifyevent.EventDate + notifyevent.NotifySubscription.AgeValue - notifyevent.NotifySubscription.AdvanceNotice;
|
|
||||||
if (deliverAfter < DateTime.UtcNow)
|
|
||||||
{
|
|
||||||
if (notifyevent.NotifySubscription.DeliveryMethod == NotifyDeliveryMethod.App)
|
|
||||||
{
|
|
||||||
await DeliverInApp(notifyevent, ct);
|
|
||||||
}
|
|
||||||
if (notifyevent.NotifySubscription.DeliveryMethod == NotifyDeliveryMethod.SMTP)
|
|
||||||
{
|
|
||||||
await DeliverSMTP(notifyevent, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
|
|
||||||
// //COULD BE TIME DELAYED BUT WITHOUT AGE, i.e. EventDate takes precedence?
|
var deliverAfter = notifyevent.EventDate + Subscription.AgeValue - Subscription.AdvanceNotice;
|
||||||
|
if (deliverAfter < DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
if (Subscription.DeliveryMethod == NotifyDeliveryMethod.App)
|
||||||
|
await DeliverInApp(notifyevent, ct);
|
||||||
|
else if (Subscription.DeliveryMethod == NotifyDeliveryMethod.SMTP)
|
||||||
|
await DeliverSMTP(notifyevent, ct);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// //NORMAL IMMEDIATE DELIVERY EVENT
|
|
||||||
// if (notifyevent.NotifySubscription.DeliveryMethod == NotifyDeliveryMethod.App)
|
|
||||||
// {
|
|
||||||
// await DeliverInApp(notifyevent, ct);
|
|
||||||
// }
|
|
||||||
// if (notifyevent.NotifySubscription.DeliveryMethod == NotifyDeliveryMethod.SMTP)
|
|
||||||
// {
|
|
||||||
// await DeliverSMTP(notifyevent, ct);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -230,79 +221,88 @@ namespace AyaNova.Biz
|
|||||||
|
|
||||||
private static async Task DeliverInApp(NotifyEvent ne, AyContext ct)
|
private static async Task DeliverInApp(NotifyEvent ne, AyContext ct)
|
||||||
{
|
{
|
||||||
log.LogTrace($"DeliverInApp deliving notify event: {ne}");
|
log.LogTrace($"DeliverInApp notify event: {ne}");
|
||||||
|
#if (DEBUG)
|
||||||
|
log.LogInformation($"DeliverInApp notify event: {ne}");
|
||||||
|
#endif
|
||||||
await ct.Notification.AddAsync(new Notification() { UserId = ne.UserId, AyaType = ne.AyaType, ObjectId = ne.ObjectId, EventType = ne.EventType, NotifySubscriptionId = ne.NotifySubscriptionId, Message = ne.Message, Name = ne.Name });
|
await ct.Notification.AddAsync(new Notification() { UserId = ne.UserId, AyaType = ne.AyaType, ObjectId = ne.ObjectId, EventType = ne.EventType, NotifySubscriptionId = ne.NotifySubscriptionId, Message = ne.Message, Name = ne.Name });
|
||||||
|
await ct.SaveChangesAsync();
|
||||||
ct.NotifyEvent.Remove(ne);
|
ct.NotifyEvent.Remove(ne);
|
||||||
await ct.SaveChangesAsync();
|
await ct.SaveChangesAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static async Task DeliverSMTP(NotifyEvent ne, AyContext ct)
|
private static async Task DeliverSMTP(NotifyEvent ne, AyContext ct)
|
||||||
{
|
{
|
||||||
log.LogTrace($"DeliverSMTP delivering notify event: {ne}");
|
await Task.CompletedTask;
|
||||||
if (string.IsNullOrWhiteSpace(ne.NotifySubscription.DeliveryAddress))
|
throw new NotSupportedException("NEW CACHING CODE NEEDS TO BE ADDED BEFORE SMTP DELIVERIES CAN RESUME TESTING");
|
||||||
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"No email address is set in subscription to deliver email notification for this event:{ne}", "Error", null, ne.UserId);
|
|
||||||
|
//TODO: UNCOMMENT THE FOLLOWING AND ADD CACHING AS PER ABOVE
|
||||||
|
// log.LogTrace($"DeliverSMTP delivering notify event: {ne}");
|
||||||
|
// if (string.IsNullOrWhiteSpace(ne.NotifySubscription.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[ne.NotifySubscription.UserId];
|
// var transid = _UserTranslationIdCache[ne.NotifySubscription.UserId];
|
||||||
var name = ne.Name;
|
// var name = ne.Name;
|
||||||
if (name == "~SERVER~")
|
// if (name == "~SERVER~")
|
||||||
name = _ServerTheWordTranslations.First(z => z.Key == transid).Value;
|
// name = _ServerTheWordTranslations.First(z => z.Key == transid).Value;
|
||||||
|
|
||||||
|
|
||||||
//AyaType translation
|
// //AyaType translation
|
||||||
var AyaTypeTranslated = string.Empty;
|
// var AyaTypeTranslated = string.Empty;
|
||||||
if (ne.AyaType != AyaType.NoType)
|
// if (ne.AyaType != AyaType.NoType)
|
||||||
AyaTypeTranslated = $":{GetTranslatedAyaTypeName(ne.AyaType, transid)}";
|
// AyaTypeTranslated = $":{GetTranslatedAyaTypeName(ne.AyaType, transid)}";
|
||||||
|
|
||||||
var subject = $"AY{AyaTypeTranslated}:{GetTranslatedNotifyEventName(ne.EventType, transid)}:{name}";
|
// var subject = $"AY{AyaTypeTranslated}:{GetTranslatedNotifyEventName(ne.EventType, transid)}:{name}";
|
||||||
|
|
||||||
//subscription link translation
|
// //subscription link translation
|
||||||
var SubscriptionTypeName = GetTranslatedAyaTypeName(AyaType.NotifySubscription, transid);
|
// var SubscriptionTypeName = GetTranslatedAyaTypeName(AyaType.NotifySubscription, transid);
|
||||||
|
|
||||||
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
// IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
var body = "";
|
// var body = "";
|
||||||
//NOTE: if need any other exemptions besides backup status make a separate static function "CanOpen(NotifyEventType)"
|
// //NOTE: if need any other exemptions besides backup status make a separate static function "CanOpen(NotifyEventType)"
|
||||||
|
|
||||||
if (ne.ObjectId != 0 || ne.EventType == NotifyEventType.BackupStatus)
|
// if (ne.ObjectId != 0 || ne.EventType == NotifyEventType.BackupStatus)
|
||||||
{
|
// {
|
||||||
body = OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId, ne.EventType) + "\n";
|
// body = OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId, ne.EventType) + "\n";
|
||||||
}
|
// }
|
||||||
body += ne.Message;
|
// body += ne.Message;
|
||||||
|
|
||||||
//Add link to subscription
|
// //Add link to subscription
|
||||||
//http://localhost:8080/open/51/1 //add subscription link, notifysub is object type 51
|
// //http://localhost:8080/open/51/1 //add subscription link, notifysub is object type 51
|
||||||
if (!body.EndsWith('\n'))
|
// if (!body.EndsWith('\n'))
|
||||||
body += "\n";
|
// body += "\n";
|
||||||
|
|
||||||
body += $"-----\n({SubscriptionTypeName}: {OpenSubscriptionUrlBuilder(ne.NotifySubscriptionId)} )\n";
|
// body += $"-----\n({SubscriptionTypeName}: {OpenSubscriptionUrlBuilder(ne.NotifySubscriptionId)} )\n";
|
||||||
|
|
||||||
if (!ServerGlobalOpsSettingsCache.Notify.SmtpDeliveryActive)
|
// 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);
|
// 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 **");
|
// 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(ne.NotifySubscription.DeliveryAddress, subject, body, ServerGlobalOpsSettingsCache.Notify);
|
// await m.SendEmailAsync(ne.NotifySubscription.DeliveryAddress, subject, body, ServerGlobalOpsSettingsCache.Notify);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
catch (Exception ex)
|
// catch (Exception ex)
|
||||||
{
|
// {
|
||||||
await NotifyEventHelper.AddOpsProblemEvent("SMTP Notification failed", ex);
|
// await NotifyEventHelper.AddOpsProblemEvent("SMTP Notification failed", ex);
|
||||||
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"An error prevented delivering the following notification via email. System operator users have been notified:{ne}", "Error", null, ne.UserId);
|
// await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"An error prevented delivering the following notification via email. System operator users have been notified:{ne}", "Error", null, ne.UserId);
|
||||||
}
|
// }
|
||||||
finally
|
// finally
|
||||||
{
|
// {
|
||||||
//remove event no matter what
|
// //remove event no matter what
|
||||||
ct.NotifyEvent.Remove(ne);
|
// ct.NotifyEvent.Remove(ne);
|
||||||
await ct.SaveChangesAsync();
|
// await ct.SaveChangesAsync();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
//Called from ops notification settings to test smtp setup by delivering to address of choosing
|
//Called from ops notification settings to test smtp setup by delivering to address of choosing
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ namespace AyaNova.Models
|
|||||||
}
|
}
|
||||||
|
|
||||||
//linked entity
|
//linked entity
|
||||||
public NotifySubscription NotifySubscription { get; set; }
|
// public NotifySubscription NotifySubscription { get; set; }
|
||||||
public User User { get; set; }
|
// public User User { get; set; }
|
||||||
|
|
||||||
}//eoc
|
}//eoc
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user