This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -37,6 +38,7 @@ namespace AyaNova.Biz
|
||||
|
||||
//temporary list to hold translations as required during delivery
|
||||
private static Dictionary<long, List<NameIdItem>> _transCache = new Dictionary<long, List<NameIdItem>>();
|
||||
private static Dictionary<long, long> _UserTranslationIdCache = new Dictionary<long, long>();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DoSweep
|
||||
@@ -100,10 +102,22 @@ namespace AyaNova.Biz
|
||||
//todo: create message here if not already set?
|
||||
//todo: generate and attach report here?
|
||||
|
||||
|
||||
//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
|
||||
var events = await ct.NotifyEvent.Include(z => z.NotifySubscription).ToListAsync();
|
||||
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).Select(z => z.NotifySubscription.UserId).ToList().Distinct();
|
||||
foreach (long userid in usersNeedingTranslations)
|
||||
{
|
||||
long transId = (await ct.UserOptions.SingleAsync(z => z.UserId == userid)).TranslationId;
|
||||
_UserTranslationIdCache.Add(userid, transId);
|
||||
await CacheNotifyEventTypeTranslations(transId);
|
||||
}
|
||||
|
||||
//iterate and deliver
|
||||
foreach (var notifyevent in events)
|
||||
{
|
||||
@@ -149,18 +163,29 @@ namespace AyaNova.Biz
|
||||
finally
|
||||
{
|
||||
log.LogTrace("Notify is done setting to not running state and tagging lastRun timestamp");
|
||||
_UserTranslationIdCache.Clear();
|
||||
_transCache.Clear();
|
||||
lastRun = DateTime.UtcNow;
|
||||
NotifyIsRunning = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//cache any translations required for email notification
|
||||
private static async Task CacheNotifyEventTypeTranslations(long translationId){
|
||||
if(_transCache.ContainsKey(translationId)){
|
||||
//cache any translations required for email notification
|
||||
private static async Task CacheNotifyEventTypeTranslations(long translationId)
|
||||
{
|
||||
if (_transCache.ContainsKey(translationId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_transCache.Add(translationId,AyaNova.Api.Controllers.EnumListController.GetEnumList("NotifyEventType",translationId));
|
||||
_transCache.Add(translationId, await AyaNova.Api.Controllers.EnumListController.GetEnumList("NotifyEventType", translationId));
|
||||
}
|
||||
|
||||
//Used for subject of email and message deliveries
|
||||
private static string GetTranslatedNotifyEventName(NotifyEventType net, long translationId)
|
||||
{
|
||||
return _transCache[translationId][(int)net].Name;
|
||||
}
|
||||
|
||||
private static async Task DeliverInApp(NotifyEvent ne, AyContext ct)
|
||||
@@ -171,29 +196,44 @@ namespace AyaNova.Biz
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private static async Task DeliverSMTP(NotifyEvent ne, string toAddress, AyContext ct)
|
||||
|
||||
|
||||
private static async Task DeliverSMTP(NotifyEvent ne, AyContext ct)
|
||||
{
|
||||
log.LogTrace($"DeliverSMTP deliving notify event: {ne}");
|
||||
if (string.IsNullOrWhiteSpace(ne.NotifySubscription.DeliveryAddress))
|
||||
{
|
||||
await NotifyEventProcessor.AddGeneralNotifyEvent(NotifyEventType.DefaultNotification, $"Error: no email address is set in subscription to deliver email notification for this event:{ne}", null, ne.UserId);
|
||||
|
||||
var subject = $"Notification: {ne.EventType.ToString()}";
|
||||
}
|
||||
|
||||
var transid = _UserTranslationIdCache[ne.NotifySubscription.UserId];
|
||||
var subject = $"AY:{GetTranslatedNotifyEventName(ne.EventType, transid)}:{ne.Name}";
|
||||
|
||||
IMailer m = AyaNova.Util.ServiceProviderProvider.Mailer;
|
||||
try
|
||||
{
|
||||
await m.SendEmailAsync(toAddress, subject, "This is a test to confirm notification system is working", ServerGlobalOpsSettingsCache.Notify);
|
||||
return "ok";
|
||||
var body = "";
|
||||
if (ne.ObjectId != 0)
|
||||
{
|
||||
body = OpenObjectUrlBuilder(ne.AyaType, ne.ObjectId) + "\n";
|
||||
}
|
||||
body += ne.Message;
|
||||
|
||||
await m.SendEmailAsync(ne.NotifySubscription.DeliveryAddress, subject, body, ServerGlobalOpsSettingsCache.Notify);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ExceptionUtil.ExtractAllExceptionMessages(ex);
|
||||
await NotifyEventProcessor.AddOpsProblemEvent("SMTP Notification failed", ex);
|
||||
await NotifyEventProcessor.AddGeneralNotifyEvent(NotifyEventType.DefaultNotification, $"Error: an error prevented delivering the following notification via email. System operator users have been notified:{ne}", null, ne.UserId);
|
||||
}
|
||||
finally
|
||||
{
|
||||
//remove event no matter what
|
||||
ct.NotifyEvent.Remove(ne);
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
//todo: //Open question: what to do with failed deliveries?
|
||||
//we dont' want them piling up but we don't want to just dump them do we?
|
||||
//it should be only mail ones that fail, not app ones, there's no way for an app delivery to fail as it's just put in a table
|
||||
//### PLAN if it's an smtp delivery that fails and it's to someone who can be delivered in app then it should send an inapp notification of
|
||||
//delivery failure and still delete the smtp delivery
|
||||
//If it's not possible to notify the person via in app of the failed smtp then perhaps it notifies OPS personnel and biz admin personnel
|
||||
}
|
||||
|
||||
//Called from ops notification settings to test smtp setup by delivering to address of choosing
|
||||
@@ -218,6 +258,20 @@ namespace AyaNova.Biz
|
||||
}
|
||||
|
||||
|
||||
//Open object url
|
||||
//### NOTE: If this is required anywhere else, move it to a central BizUtils class in Biz folder callable from here and there
|
||||
private static string OpenObjectUrlBuilder(AyaType otype, long id)
|
||||
{
|
||||
var ServerUrl = ServerGlobalOpsSettingsCache.Notify.AyaNovaServerURL;
|
||||
if (string.IsNullOrWhiteSpace(ServerUrl))
|
||||
{
|
||||
NotifyEventProcessor.AddOpsProblemEvent("Notification system: The OPS Notification setting is empty for AyaNova Server URL. This prevents Notification system from linking events to openable objects.").Wait();
|
||||
return "OPS ERROR NO SERVER URL CONFIGURED";
|
||||
}
|
||||
ServerUrl = ServerUrl.Trim().TrimEnd('/');
|
||||
return $"{ServerUrl}?type={otype}&id={id}";
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
}//eoc
|
||||
|
||||
Reference in New Issue
Block a user