Skip to content

Commit 73c6bc3

Browse files
author
gauffininteractive
committed
Corrected notifications
1 parent ec602ee commit 73c6bc3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+240
-31
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using DotNetCqs;
2+
3+
namespace OneTrueError.Api.Core.Feedback.Events
4+
{
5+
/// <summary>
6+
/// Feedback was attached to incident.
7+
/// </summary>
8+
public class FeedbackAttachedToIncident : ApplicationEvent
9+
{
10+
/// <summary>
11+
/// Incident that the feedback was attached to.
12+
/// </summary>
13+
public int IncidentId { get; set; }
14+
15+
/// <summary>
16+
/// Feedback message.
17+
/// </summary>
18+
public string Message { get; set; }
19+
20+
/// <summary>
21+
/// Email address to the user that wrote the message (optional)
22+
/// </summary>
23+
public string UserEmailAddress { get; set; }
24+
}
25+
}

src/Server/OneTrueError.Api/OneTrueError.Api.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
<Compile Include="Core\Applications\NamespaceDoc.cs" />
9090
<Compile Include="Core\Applications\Queries\GetApplicationTeamResult.cs" />
9191
<Compile Include="Core\Applications\Queries\OverviewStatSummary.cs" />
92+
<Compile Include="Core\Feedback\Events\FeedbackAttachedToIncident.cs" />
9293
<Compile Include="Core\Feedback\NamespaceDoc.cs" />
9394
<Compile Include="Core\Incidents\NamespaceDoc.cs" />
9495
<Compile Include="Core\Invitations\Commands\InviteUser.cs" />

src/Server/OneTrueError.App/Core/Feedback/EventSubscribers/AttachFeedbackToIncident.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
using System.Threading.Tasks;
1+
using System;
2+
using System.Threading.Tasks;
23
using DotNetCqs;
34
using Griffin.Container;
5+
using OneTrueError.Api.Core.Feedback.Events;
46
using OneTrueError.Api.Core.Incidents.Events;
57

68
namespace OneTrueError.App.Core.Feedback.EventSubscribers
@@ -12,10 +14,13 @@ namespace OneTrueError.App.Core.Feedback.EventSubscribers
1214
internal class AttachFeedbackToIncident : IApplicationEventSubscriber<ReportAddedToIncident>
1315
{
1416
private readonly IFeedbackRepository _repository;
17+
private readonly IEventBus _eventBus;
1518

16-
public AttachFeedbackToIncident(IFeedbackRepository repository)
19+
public AttachFeedbackToIncident(IFeedbackRepository repository, IEventBus eventBus)
1720
{
21+
if (eventBus == null) throw new ArgumentNullException("eventBus");
1822
_repository = repository;
23+
_eventBus = eventBus;
1924
}
2025

2126
public async Task HandleAsync(ReportAddedToIncident e)
@@ -25,6 +30,9 @@ public async Task HandleAsync(ReportAddedToIncident e)
2530
return;
2631

2732
feedback.AssignToReport(e.Report.Id, e.Incident.Id, e.Incident.ApplicationId);
33+
34+
var evt = new FeedbackAttachedToIncident {IncidentId = e.Incident.Id, Message = feedback.Description, UserEmailAddress = feedback.EmailAddress};
35+
await _eventBus.PublishAsync(evt);
2836
await _repository.UpdateAsync(feedback);
2937
}
3038
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using System.Threading.Tasks;
2+
using DotNetCqs;
3+
using Griffin.Container;
4+
using OneTrueError.Api.Core.Accounts.Queries;
5+
using OneTrueError.Api.Core.Feedback.Events;
6+
using OneTrueError.Api.Core.Incidents.Queries;
7+
using OneTrueError.Api.Core.Messaging;
8+
using OneTrueError.Api.Core.Messaging.Commands;
9+
using OneTrueError.App.Configuration;
10+
using OneTrueError.App.Core.Users;
11+
using OneTrueError.Infrastructure.Configuration;
12+
13+
namespace OneTrueError.App.Core.Notifications.EventHandlers
14+
{
15+
/// <summary>
16+
/// Responsible of sending notifications when a new report have been analyzed.
17+
/// </summary>
18+
[Component(RegisterAsSelf = true)]
19+
public class CheckForFeedbackNotificationsToSend :
20+
IApplicationEventSubscriber<FeedbackAttachedToIncident>
21+
{
22+
private readonly ICommandBus _commandBus;
23+
private readonly INotificationsRepository _notificationsRepository;
24+
private readonly IQueryBus _queryBus;
25+
26+
/// <summary>
27+
/// Creates a new instance of <see cref="CheckForNotificationsToSend" />.
28+
/// </summary>
29+
/// <param name="notificationsRepository">To load notification configuration</param>
30+
/// <param name="commandBus">To send emails</param>
31+
/// <param name="queryBus"></param>
32+
public CheckForFeedbackNotificationsToSend(INotificationsRepository notificationsRepository,
33+
ICommandBus commandBus,
34+
IQueryBus queryBus)
35+
{
36+
_notificationsRepository = notificationsRepository;
37+
_commandBus = commandBus;
38+
_queryBus = queryBus;
39+
}
40+
41+
public async Task HandleAsync(FeedbackAttachedToIncident e)
42+
{
43+
var settings = await _notificationsRepository.GetAllAsync(-1);
44+
var incident = await _queryBus.QueryAsync(new GetIncident(e.IncidentId));
45+
foreach (var setting in settings)
46+
{
47+
if (setting.UserFeedback == NotificationState.Disabled)
48+
continue;
49+
50+
var notificationEmail = await _queryBus.QueryAsync(new GetAccountEmailById(setting.AccountId));
51+
var config = ConfigurationStore.Instance.Load<BaseConfiguration>();
52+
53+
var shortName = incident.Description.Length > 40
54+
? incident.Description.Substring(0, 40) + "..."
55+
: incident.Description;
56+
57+
if (string.IsNullOrEmpty(e.UserEmailAddress))
58+
e.UserEmailAddress = "unknown";
59+
60+
var incidentUrl = string.Format("{0}/#/application/{1}/incident/{2}",
61+
config.BaseUrl.ToString().TrimEnd('/'),
62+
incident.ApplicationId,
63+
incident.Id);
64+
65+
//TODO: Add more information
66+
var msg = new EmailMessage(notificationEmail);
67+
msg.Subject = "New feedback: " + shortName;
68+
msg.TextBody = string.Format(@"Incident: {0}
69+
Feedback: {0}/feedback
70+
From: {1}
71+
72+
{2}
73+
", incidentUrl, e.UserEmailAddress, e.Message);
74+
75+
76+
var emailCmd = new SendEmail(msg);
77+
await _commandBus.ExecuteAsync(emailCmd);
78+
}
79+
}
80+
}
81+
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,23 @@
99
namespace OneTrueError.App.Core.Notifications.EventHandlers
1010
{
1111
/// <summary>
12-
/// Responsible of sending notifcations when a new report have been analyzed.
12+
/// Responsible of sending notifications when a new report have been analyzed.
1313
/// </summary>
1414
[Component(RegisterAsSelf = true)]
15-
public class SendConfiguredNotifications :
15+
public class CheckForNotificationsToSend :
1616
IApplicationEventSubscriber<ReportAddedToIncident>
1717
{
1818
private readonly ICommandBus _commandBus;
1919
private readonly INotificationsRepository _notificationsRepository;
2020
private readonly IUserRepository _userRepository;
2121

2222
/// <summary>
23-
/// Creates a new instance of <see cref="SendConfiguredNotifications" />.
23+
/// Creates a new instance of <see cref="CheckForNotificationsToSend" />.
2424
/// </summary>
2525
/// <param name="notificationsRepository">To load notification configuration</param>
2626
/// <param name="commandBus">To send emails</param>
2727
/// <param name="userRepository">To load user info</param>
28-
public SendConfiguredNotifications(INotificationsRepository notificationsRepository, ICommandBus commandBus,
28+
public CheckForNotificationsToSend(INotificationsRepository notificationsRepository, ICommandBus commandBus,
2929
IUserRepository userRepository)
3030
{
3131
_notificationsRepository = notificationsRepository;

src/Server/OneTrueError.App/Core/Notifications/Tasks/SendIncidentEmail.cs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace OneTrueError.App.Core.Notifications.Tasks
1212
{
1313
/// <summary>
14-
/// Send incident emal
14+
/// Send incident email
1515
/// </summary>
1616
public class SendIncidentEmail
1717
{
@@ -44,43 +44,50 @@ public async Task SendAsync(string idOrEmailAddress, IncidentSummaryDTO incident
4444

4545
var config = ConfigurationStore.Instance.Load<BaseConfiguration>();
4646

47-
var shortName = incident.Name.Length > 20
48-
? incident.Name.Substring(0, 20) + "..."
47+
var shortName = incident.Name.Length > 40
48+
? incident.Name.Substring(0, 40) + "..."
4949
: incident.Name;
5050

51+
var baseUrl = string.Format("{0}/#/application/{1}/incident/{2}",
52+
config.BaseUrl.ToString().TrimEnd('/'),
53+
report.ApplicationId,
54+
report.IncidentId);
55+
5156
//TODO: Add more information
5257
var msg = new EmailMessage(idOrEmailAddress);
5358
if (incident.IsReOpened)
5459
{
5560
msg.Subject = "ReOpened: " + shortName;
56-
msg.TextBody = string.Format(@"Incident url: {0}/incident/{1}
57-
Report url: {0}/incident/{1}/report/{2}
58-
Exception: {3}
61+
msg.TextBody = string.Format(@"Incident: {0}
62+
Report url: {0}/report/{1}
63+
Exception: {2}
5964
60-
{4}
61-
", config.BaseUrl, incident.Id, report.ReportId, report.Exception.FullName, report.Exception.StackTrace);
65+
{3}
66+
", baseUrl, report.Id, report.Exception.FullName, report.Exception.StackTrace);
6267
}
6368
else if (incident.ReportCount == 1)
6469
{
6570
msg.Subject = "New: " + shortName;
66-
msg.TextBody = string.Format(@"Incident url: {0}/incident/{1}
67-
Exception: {2}
71+
msg.TextBody = string.Format(@"Incident: {0}
72+
Exception: {1}
6873
69-
{3}", config.BaseUrl, incident.Id, report.Exception.FullName, report.Exception.StackTrace);
74+
{2}", baseUrl, report.Exception.FullName, report.Exception.StackTrace);
7075
}
7176
else
7277
{
7378
msg.Subject = "Updated: " + shortName;
74-
msg.TextBody = string.Format(@"Incident url: {0}/incident/{1}
75-
Report url: {0}/incident/{1}/report/{2}
76-
Exception: {3}
79+
msg.TextBody = string.Format(@"Incident: {0}
80+
Report url: {0}/report/{1}
81+
Exception: {2}
7782
78-
{4}
79-
", config.BaseUrl, incident.Id, report.ReportId, report.Exception.FullName, report.Exception.StackTrace);
83+
{3}
84+
", baseUrl, report.Id, report.Exception.FullName, report.Exception.StackTrace);
8085
}
8186

8287
var emailCmd = new SendEmail(msg);
8388
await _commandBus.ExecuteAsync(emailCmd);
8489
}
90+
91+
8592
}
8693
}

src/Server/OneTrueError.App/Modules/Messaging/Commands/SendEmailHandler.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
using System.IO;
1+
using System;
2+
using System.IO;
23
using System.Net;
34
using System.Net.Mail;
45
using System.Net.Mime;
56
using System.Threading.Tasks;
67
using DotNetCqs;
78
using Griffin.Container;
9+
using OneTrueError.Api.Core.Accounts.Queries;
810
using OneTrueError.Api.Core.Messaging.Commands;
911
using OneTrueError.App.Configuration;
1012
using OneTrueError.Infrastructure.Configuration;
@@ -15,6 +17,14 @@ namespace OneTrueError.App.Modules.Messaging.Commands
1517
[Component]
1618
internal class SendEmailHandler : ICommandHandler<SendEmail>
1719
{
20+
private IQueryBus _queryBus;
21+
22+
public SendEmailHandler(IQueryBus queryBus)
23+
{
24+
if (queryBus == null) throw new ArgumentNullException("queryBus");
25+
_queryBus = queryBus;
26+
}
27+
1828
#pragma warning disable 1998
1929
public async Task ExecuteAsync(SendEmail command)
2030
#pragma warning restore 1998
@@ -32,7 +42,15 @@ public async Task ExecuteAsync(SendEmail command)
3242
};
3343
foreach (var recipient in command.EmailMessage.Recipients)
3444
{
35-
email.To.Add(new MailAddress(recipient.Address, recipient.Name));
45+
int accountId;
46+
if (int.TryParse(recipient.Address, out accountId))
47+
{
48+
var query = new GetAccountEmailById(accountId);
49+
var emailAddress = await _queryBus.QueryAsync(query);
50+
email.To.Add(new MailAddress(emailAddress, recipient.Name));
51+
}
52+
else
53+
email.To.Add(new MailAddress(recipient.Address, recipient.Name));
3654
}
3755
if (string.IsNullOrEmpty(command.EmailMessage.HtmlBody))
3856
{

src/Server/OneTrueError.App/OneTrueError.App.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
<Compile Include="Configuration\OneTrueErrorConfigSection.cs" />
8383
<Compile Include="Core\Applications\ApplicationRole.cs" />
8484
<Compile Include="Core\Applications\EventHandlers\UpdateTeamOnInvitationAccepted.cs" />
85+
<Compile Include="Core\Notifications\EventHandlers\CheckForFeedbackNotificationsToSend.cs" />
8586
<Compile Include="Core\Reports\PagedReports.cs" />
8687
<Compile Include="GlobalSuppressions.cs" />
8788
<Compile Include="Modules\Geolocation\ErrorOrginResult.cs" />
@@ -145,7 +146,7 @@
145146
<Compile Include="Modules\ReportSpikes\NewSpike.cs" />
146147
<Compile Include="Modules\Tagging\Handlers\IncidentReopenedHandler.cs" />
147148
<Compile Include="OneTruePrincipal.cs" />
148-
<Compile Include="Core\Notifications\EventHandlers\SendConfiguredNotifications.cs" />
149+
<Compile Include="Core\Notifications\EventHandlers\CheckForNotificationsToSend.cs" />
149150
<Compile Include="Modules\ReportSpikes\IReportSpikeRepository.cs" />
150151
<Compile Include="Core\Notifications\INotificationsRepository.cs" />
151152
<Compile Include="Core\Notifications\NotificationState.cs" />
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using DotNetCqs;
4+
using Griffin.Container;
5+
using OneTrueError.Api.Core.Accounts.Queries;
6+
using OneTrueError.App.Core.Accounts;
7+
8+
namespace OneTrueError.SqlServer.Core.Accounts.QueryHandlers
9+
{
10+
[Component]
11+
public class GetAccountEmailByIdHandler : IQueryHandler<GetAccountEmailById, string>
12+
{
13+
private readonly IAccountRepository _accountRepository;
14+
15+
public GetAccountEmailByIdHandler(IAccountRepository accountRepository)
16+
{
17+
if (accountRepository == null) throw new ArgumentNullException(nameof(accountRepository));
18+
_accountRepository = accountRepository;
19+
}
20+
21+
public async Task<string> ExecuteAsync(GetAccountEmailById query)
22+
{
23+
var usr = await _accountRepository.GetByIdAsync(query.AccountId);
24+
return usr.Email;
25+
}
26+
}
27+
}

src/Server/OneTrueError.SqlServer/Core/Feedback/Commands/SubmitFeedbackHandler.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Griffin.Data;
77
using log4net;
88
using OneTrueError.Api.Core.Feedback.Commands;
9+
using OneTrueError.Api.Core.Feedback.Events;
910
using OneTrueError.Api.Core.Reports;
1011
using OneTrueError.App.Core.Reports;
1112
using OneTrueError.SqlServer.Tools;
@@ -18,11 +19,13 @@ public class SubmitFeedbackHandler : ICommandHandler<SubmitFeedback>
1819
private readonly ILog _logger = LogManager.GetLogger(typeof(SubmitFeedbackHandler));
1920
private readonly IReportsRepository _reportsRepository;
2021
private readonly IAdoNetUnitOfWork _unitOfWork;
22+
private IEventBus _eventBus;
2123

22-
public SubmitFeedbackHandler(IAdoNetUnitOfWork unitOfWork, IReportsRepository reportsRepository)
24+
public SubmitFeedbackHandler(IAdoNetUnitOfWork unitOfWork, IReportsRepository reportsRepository, IEventBus eventBus)
2325
{
2426
_unitOfWork = unitOfWork;
2527
_reportsRepository = reportsRepository;
28+
_eventBus = eventBus;
2629
}
2730

2831
public async Task ExecuteAsync(SubmitFeedback command)
@@ -80,6 +83,15 @@ public async Task ExecuteAsync(SubmitFeedback command)
8083
cmd.AddParameter("EmailAddress", command.Email);
8184
cmd.AddParameter("Conversation", "");
8285
cmd.AddParameter("CreatedAtUtc", DateTime.UtcNow);
86+
87+
var evt = new FeedbackAttachedToIncident
88+
{
89+
Message = command.Feedback,
90+
UserEmailAddress = command.Email,
91+
IncidentId = report.IncidentId
92+
};
93+
await _eventBus.PublishAsync(evt);
94+
8395
await cmd.ExecuteNonQueryAsync();
8496
}
8597
}

0 commit comments

Comments
 (0)