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
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace AyaNova.Models
|
||||
public NotifyMailSecurity ConnectionSecurity { get; set; }
|
||||
public int SmtpServerPort { get; set; }
|
||||
public string NotifyFromAddress { get; set; }
|
||||
public string AyaNovaServerURL { get; set; }
|
||||
|
||||
public GlobalOpsNotificationSettings()
|
||||
{
|
||||
@@ -27,6 +28,7 @@ namespace AyaNova.Models
|
||||
ConnectionSecurity = NotifyMailSecurity.StartTls;
|
||||
SmtpServerPort = 465;
|
||||
NotifyFromAddress = "support@ayanova.com";
|
||||
AyaNovaServerURL="http://localhost:8080";
|
||||
#else
|
||||
SmtpServerAddress="mail.example.com";
|
||||
SmtpAccount="notifydeliverfromaccount@example.com";
|
||||
@@ -34,6 +36,7 @@ namespace AyaNova.Models
|
||||
ConnectionSecurity= NotifyMailSecurity.SSLTLS;
|
||||
SmtpServerPort=587;
|
||||
NotifyFromAddress="noreply@example.com";
|
||||
AyaNovaServerURL="https://ayanovaserver.example.com";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -1901,5 +1901,6 @@
|
||||
"SmtpPassword": "SMTP-Serverkennwort",
|
||||
"ConnectionSecurity": "SMTP-Verbindungssicherheit",
|
||||
"SmtpServerPort": "SMTP-Server-Port",
|
||||
"NotifyFromAddress": "SMTP-Benachrichtigungsadresse"
|
||||
"NotifyFromAddress": "SMTP-Benachrichtigungsadresse",
|
||||
"AyaNovaServerUrl": "AyaNova Server URL"
|
||||
}
|
||||
@@ -1901,5 +1901,6 @@
|
||||
"SmtpPassword": "SMTP server password",
|
||||
"ConnectionSecurity": "SMTP connection security",
|
||||
"SmtpServerPort": "SMTP server port",
|
||||
"NotifyFromAddress": "SMTP notify from address"
|
||||
"NotifyFromAddress": "SMTP notify from address",
|
||||
"AyaNovaServerUrl": "AyaNova server URL"
|
||||
}
|
||||
@@ -1901,5 +1901,6 @@
|
||||
"SmtpPassword": "Contraseña SMTP",
|
||||
"ConnectionSecurity": "Seguridad de conexión del servidor SMTP",
|
||||
"SmtpServerPort": "Puerto SMTP",
|
||||
"NotifyFromAddress": "Notificación SMTP desde la dirección"
|
||||
"NotifyFromAddress": "Notificación SMTP desde la dirección",
|
||||
"AyaNovaServerUrl": "URL del servidor AyaNova"
|
||||
}
|
||||
@@ -1901,5 +1901,6 @@
|
||||
"SmtpPassword": "Mot de passe du serveur SMTP",
|
||||
"ConnectionSecurity": "Sécurité de la connexion SMTP",
|
||||
"SmtpServerPort": "Port du serveur SMTP",
|
||||
"NotifyFromAddress": "Notification SMTP envoyée depuis l'adresse"
|
||||
"NotifyFromAddress": "Notification SMTP envoyée depuis l'adresse",
|
||||
"AyaNovaServerUrl": "URL du serveur AyaNova"
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace AyaNova.Util
|
||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
||||
private const int DESIRED_SCHEMA_LEVEL = 12;
|
||||
|
||||
internal const long EXPECTED_COLUMN_COUNT = 382;
|
||||
internal const long EXPECTED_COLUMN_COUNT = 383;
|
||||
internal const long EXPECTED_INDEX_COUNT = 139;
|
||||
|
||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
||||
@@ -237,7 +237,7 @@ namespace AyaNova.Util
|
||||
"backuptime timestamp, backupsetstokeep int, backupattachments bool)");
|
||||
|
||||
await ExecQueryAsync("CREATE TABLE aglobalopsnotificationsettings (id integer NOT NULL PRIMARY KEY, smtpdeliveryactive bool not null, " +
|
||||
"smtpserveraddress text, smtpaccount text, smtppassword text, connectionsecurity integer not null default 0, smtpserverport integer, notifyfromaddress text)");
|
||||
"smtpserveraddress text, smtpaccount text, smtppassword text, connectionsecurity integer not null default 0, smtpserverport integer, notifyfromaddress text, ayanovaserverurl text)");
|
||||
|
||||
//create aevent biz event log table
|
||||
await ExecQueryAsync("CREATE TABLE aevent (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, created timestamp not null, userid bigint not null," +
|
||||
|
||||
Reference in New Issue
Block a user