public void Handle(VolunteerInformationAdded notification)
        {
            var volunteer = _context.Users.Single(u => u.Id == notification.UserId);
            var activity  = _context.Activities.Single(a => a.Id == notification.ActivityId);
            var campaign  = _context.Campaigns
                            .Include(c => c.Organizer)
                            .Single(c => c.Id == activity.CampaignId);
            var link = $"View activity: http://{_options.Value.SiteBaseUrl}/Admin/Activity/Details/{activity.Id}";

            var subject = $"A volunteer has signed up for {activity.Name}";

            if (campaign.Organizer != null)
            {
                var message = $"Your {campaign.Name} campaign activity '{activity.Name}' has a new volunteer. {volunteer.UserName} can be reached at {volunteer.Email}. {link}";
                var command = new NotifyVolunteersCommand
                {
                    ViewModel = new NotifyVolunteersViewModel
                    {
                        EmailMessage    = message,
                        HtmlMessage     = message,
                        EmailRecipients = new List <string> {
                            campaign.Organizer.Email
                        },
                        Subject = subject
                    }
                };

                _bus.Send(command);
            }
        }
Beispiel #2
0
        public async Task Handle(UserUnenrolls notification)
        {
            // don't let problem with notification keep us from continuing
            try
            {
                var notificationModel = await _mediator.SendAsync(new EventDetailForNotificationQueryAsync { EventId = notification.EventId, UserId = notification.UserId })
                                        .ConfigureAwait(false);

                var campaignContact = notificationModel.CampaignContacts.SingleOrDefault(tc => tc.ContactType == (int)ContactTypes.Primary);
                var adminEmail      = campaignContact?.Contact.Email;

                if (string.IsNullOrWhiteSpace(adminEmail))
                {
                    return;
                }

                TaskSummaryModel taskModel = null;
                string           remainingRequiredVolunteersPhrase;

                taskModel = notificationModel.Tasks.FirstOrDefault(t => t.Id == notification.TaskIds[0]) ?? new TaskSummaryModel();
                remainingRequiredVolunteersPhrase = $"{taskModel.NumberOfVolunteersSignedUp}/{taskModel.NumberOfVolunteersRequired}";

                var eventLink = $"View event: {_options.Value.SiteBaseUrl}Admin/Event/Details/{notificationModel.EventId}";
                var subject   = $"A volunteer has unenrolled from a task";

                var message = new StringBuilder();
                message.AppendLine($"A volunteer has unenrolled from a task.");
                message.AppendLine($"   Volunteer: {notificationModel.Volunteer.Name} ({notificationModel.Volunteer.Email})");
                message.AppendLine($"   Campaign: {notificationModel.CampaignName}");
                message.AppendLine($"   Event: {notificationModel.EventName} ({eventLink})");
                message.AppendLine($"   Task: {taskModel.Name} ({$"View task: {_options.Value.SiteBaseUrl}Admin/Task/Details/{taskModel.Id}"})");
                message.AppendLine($"   Task Start Date: {taskModel.StartDateTime?.Date.ToShortDateString()}");
                message.AppendLine($"   Remaining/Required Volunteers: {remainingRequiredVolunteersPhrase}");
                message.AppendLine();

                var command = new NotifyVolunteersCommand
                {
                    ViewModel = new NotifyVolunteersViewModel
                    {
                        EmailMessage    = message.ToString(),
                        HtmlMessage     = message.ToString(),
                        EmailRecipients = new List <string> {
                            campaignContact.Contact.Email
                        },
                        Subject = subject
                    }
                };

                await _mediator.SendAsync(command).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                _logger.LogError($"Exception encountered: message={e.Message}, innerException={e.InnerException}, stacktrace={e.StackTrace}");
            }
        }
Beispiel #3
0
        public Task SendSmsAsync(string number, string message)
        {
            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    SmsMessage = message,
                    SmsRecipients = new List<string> { number },
                }
            };

            return _mediator.SendAsync(command);
        }
        public async Task Handle(VolunteerSignupNotification notification)
        {
            var model = _mediator.Send(new ActivityDetailForNotificationQuery {
                ActivityId = notification.ActivityId, UserId = notification.UserId
            });

            var signup = model.UsersSignedUp?.FirstOrDefault(s => s.User.Id == notification.UserId);

            if (signup == null)
            {
                return;
            }

            var emailRecipient = !string.IsNullOrWhiteSpace(signup.PreferredEmail)
                ? signup.PreferredEmail
                : signup.User?.Email;

            if (string.IsNullOrWhiteSpace(emailRecipient))
            {
                return;
            }

            var activityLink = $"View activity: {_options.Value.SiteBaseUrl}Admin/Activity/Details/{model.ActivityId}";
            var subject      = "allReady Activity Enrollment Confirmation";

            var message = new StringBuilder();

            message.AppendLine($"This is to confirm that you have volunteered to participate in the following activity:");
            message.AppendLine();
            message.AppendLine($"   Campaign: {model.CampaignName}");
            message.AppendLine($"   Activity: {model.ActivityName} ({activityLink})");
            message.AppendLine();
            message.AppendLine($"Thanks for volunteering. Your help is appreciated.");

            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    EmailMessage    = message.ToString(),
                    HtmlMessage     = message.ToString(),
                    EmailRecipients = new List <string> {
                        emailRecipient
                    },
                    Subject = subject
                }
            };

            await _mediator.SendAsync(command).ConfigureAwait(false);
        }
        public void Handle(TaskSignupStatusChanged notification)
        {
            var taskSignup = _context.TaskSignups
                             .Include(ts => ts.Task)
                             .ThenInclude(t => t.Activity).ThenInclude(a => a.Organizer)
                             .Include(ts => ts.Task)
                             .ThenInclude(t => t.Activity).ThenInclude(a => a.Campaign).ThenInclude(c => c.Organizer)
                             .Include(ts => ts.User)
                             .Single(ts => ts.Id == notification.SignupId);
            var volunteer = taskSignup.User;
            var task      = taskSignup.Task;
            var activity  = task.Activity;
            var campaign  = activity.Campaign;

            //Prefer activity organizer email; fallback to campaign organizer email
            var adminEmail = taskSignup.Task.Activity.Organizer?.Email;

            if (string.IsNullOrWhiteSpace(adminEmail))
            {
                adminEmail = taskSignup.Task.Activity.Campaign.Organizer?.Email;
            }
            if (!string.IsNullOrWhiteSpace(adminEmail))
            {
                var link    = $"View activity: http://{_options.Value.SiteBaseUrl}/Admin/Task/Details/{taskSignup.Task.Id}";
                var subject = $"Task status changed ({taskSignup.Status}) for volunteer {volunteer.Name ?? volunteer.Email}";

                var message = $@"A volunteer's status has changed for a task.
                                    Volunteer: {volunteer.Name} ({volunteer.Email})
                                    New status: {taskSignup.Status}
                                    Task: {task.Name} {link}
                                    Activity: {activity.Name}
                                    Campaign: {campaign.Name}";

                var command = new NotifyVolunteersCommand
                {
                    ViewModel = new NotifyVolunteersViewModel
                    {
                        EmailMessage    = message,
                        HtmlMessage     = message,
                        EmailRecipients = new List <string> {
                            adminEmail
                        },
                        Subject = subject
                    }
                };

                _bus.Send(command);
            }
        }
Beispiel #6
0
        public Task SendEmailAsync(string email, string subject, string message)
        {
            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    EmailMessage = message,
                    EmailRecipients = new List<string> {email},
                    HtmlMessage = message,
                    Subject = subject
                }
            };

            return _mediator.SendAsync(command);
        }
Beispiel #7
0
        public Task SendSmsAsync(string number, string message)
        {
            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    SmsMessage = message,
                    SmsRecipients = new List<string> { number },
                }
            };

            _bus.Send(command);

            return Task.FromResult(0);
        }
        public Task SendEmailAsync(string email, string subject, string message)
        {
            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    EmailMessage = message,
                    EmailRecipients = new List<string> {email},
                    Subject = subject
                }
            };

            _bus.Send(command);
            return Task.FromResult(0);
        }
        public async Task Handle(TaskSignupStatusChanged notification)
        {
            var taskSignup = await _context.TaskSignups
                             .Include(ts => ts.Task)
                             .ThenInclude(t => t.Event).ThenInclude(a => a.Organizer)
                             .Include(ts => ts.Task)
                             .ThenInclude(t => t.Event).ThenInclude(a => a.Campaign).ThenInclude(c => c.CampaignContacts).ThenInclude(cc => cc.Contact)
                             .Include(ts => ts.User)
                             .SingleAsync(ts => ts.Id == notification.SignupId)
                             .ConfigureAwait(false);

            var volunteer     = taskSignup.User;
            var task          = taskSignup.Task;
            var campaignEvent = task.Event;
            var campaign      = campaignEvent.Campaign;

            var campaignContact = campaign.CampaignContacts?.SingleOrDefault(tc => tc.ContactType == (int)ContactTypes.Primary);
            var adminEmail      = campaignContact?.Contact.Email;

            if (!string.IsNullOrWhiteSpace(adminEmail))
            {
                var link = $"View event: http://{_options.Value.SiteBaseUrl}/Admin/Task/Details/{taskSignup.Task.Id}";

                var subject = volunteer.FirstName != null && volunteer.LastName != null ? $"{volunteer.FirstName} {volunteer.LastName}" : volunteer.Email;

                var message = $@"A volunteer's status has changed for a task.
                    Volunteer: {volunteer.Name} ({volunteer.Email})
                    New status: {taskSignup.Status}
                    Task: {task.Name} {link}
                    Event: {campaignEvent.Name}
                    Campaign: {campaign.Name}";

                var command = new NotifyVolunteersCommand
                {
                    ViewModel = new NotifyVolunteersViewModel
                    {
                        EmailMessage    = message,
                        HtmlMessage     = message,
                        EmailRecipients = new List <string> {
                            adminEmail
                        },
                        Subject = subject
                    }
                };

                await _mediator.SendAsync(command).ConfigureAwait(false);
            }
        }
        public async Task Handle(UserUnenrolls notification)
        {
            var model = await _mediator.SendAsync(new EventDetailForNotificationQueryAsync { EventId = notification.EventId, UserId = notification.UserId })
                        .ConfigureAwait(false);

            var signup = model.UsersSignedUp?.FirstOrDefault(s => s.User.Id == notification.UserId);

            if (signup == null)
            {
                return;
            }

            var emailRecipient = !string.IsNullOrWhiteSpace(signup.PreferredEmail)
                ? signup.PreferredEmail
                : signup.User?.Email;

            if (string.IsNullOrWhiteSpace(emailRecipient))
            {
                return;
            }

            var eventLink = $"View event: {_options.Value.SiteBaseUrl}Admin/Event/Details/{model.EventId}";

            var message = new StringBuilder();

            message.AppendLine("This is to confirm that you have elected to un-enroll from the following event:");
            message.AppendLine();
            message.AppendLine($"   Campaign: {model.CampaignName}");
            message.AppendLine($"   Event: {model.EventName} ({eventLink})");
            message.AppendLine();
            message.AppendLine("Thanks for letting us know that you will not be participating.");

            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    EmailMessage    = message.ToString(),
                    HtmlMessage     = message.ToString(),
                    EmailRecipients = new List <string> {
                        emailRecipient
                    },
                    Subject = "allReady Event Un-enrollment Confirmation"
                }
            };

            await _mediator.SendAsync(command).ConfigureAwait(false);
        }
        public void Handle(TaskSignupStatusChanged notification)
        {
            var taskSignup = _context.TaskSignups
                             .Include(ts => ts.Task)
                             .ThenInclude(t => t.Activity).ThenInclude(a => a.Organizer)
                             .Include(ts => ts.Task)
                             .ThenInclude(t => t.Activity).ThenInclude(a => a.Campaign).ThenInclude(c => c.CampaignContacts).ThenInclude(cc => cc.Contact)
                             .Include(ts => ts.User)
                             .Single(ts => ts.Id == notification.SignupId);
            var volunteer = taskSignup.User;
            var task      = taskSignup.Task;
            var activity  = task.Activity;
            var campaign  = activity.Campaign;

            var campaignContact = campaign.CampaignContacts?.SingleOrDefault(tc => tc.ContactType == (int)ContactTypes.Primary);
            var adminEmail      = campaignContact?.Contact.Email;

            if (!string.IsNullOrWhiteSpace(adminEmail))
            {
                var link    = $"View activity: http://{_options.Value.SiteBaseUrl}/Admin/Task/Details/{taskSignup.Task.Id}";
                var subject = $"Task status changed ({taskSignup.Status}) for volunteer {volunteer.Name ?? volunteer.Email}";

                var message = $@"A volunteer's status has changed for a task.
                                    Volunteer: {volunteer.Name} ({volunteer.Email})
                                    New status: {taskSignup.Status}
                                    Task: {task.Name} {link}
                                    Activity: {activity.Name}
                                    Campaign: {campaign.Name}";

                var command = new NotifyVolunteersCommand
                {
                    ViewModel = new NotifyVolunteersViewModel
                    {
                        EmailMessage    = message,
                        HtmlMessage     = message,
                        EmailRecipients = new List <string> {
                            adminEmail
                        },
                        Subject = subject
                    }
                };

                _mediator.SendAsync(command);
            }
        }
        public async Task Handle(UserUnenrolls notification)
        {
            var taskInfo = await _mediator.SendAsync(new TaskDetailForNotificationQuery { TaskId = notification.TaskId, UserId = notification.UserId })
                           .ConfigureAwait(false);

            if (taskInfo == null)
            {
                return;
            }

            var emailRecipient = taskInfo?.Volunteer?.Email;

            if (string.IsNullOrWhiteSpace(emailRecipient))
            {
                return;
            }

            var eventLink = $"View event: {_options.Value.SiteBaseUrl}Event/Details/{taskInfo.EventId}";

            var message = new StringBuilder();

            message.AppendLine($"This is to confirm that you have elected to un-enroll from the following task:");
            message.AppendLine();
            message.AppendLine($"   Campaign: {taskInfo.CampaignName}");
            message.AppendLine($"   Event: {taskInfo.EventName} ({eventLink})");
            message.AppendLine($"   Task: {taskInfo.TaskName}");
            message.AppendLine();
            message.AppendLine("Thanks for letting us know that you will not be participating.");

            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    EmailMessage    = message.ToString(),
                    HtmlMessage     = message.ToString(),
                    EmailRecipients = new List <string> {
                        emailRecipient
                    },
                    Subject = "allReady Task Un-enrollment Confirmation"
                }
            };

            await _mediator.SendAsync(command).ConfigureAwait(false);
        }
        public void SendMessageToAssignedVolunteers()
        {
            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    Subject = "This is my subject",
                    EmailRecipients = new List<string> { "*****@*****.**", "*****@*****.**" },
                    EmailMessage = "This is my message"
                }
            };

            var queueWriter = new Mock<IQueueStorageService>();

            var handler = new NotifyVolunteersHandler(queueWriter.Object);
            var result = handler.Handle(command);

            queueWriter.Verify(q => q.SendMessageAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(2));
        }
        public async Task Handle(TaskAssignedToVolunteersNotification notification)
        {
            var users = await _context.Users.Where(x => notification.NewlyAssignedVolunteers.Contains(x.Id)).ToListAsync();

            var smsRecipients   = users.Where(u => u.PhoneNumberConfirmed).Select(v => v.PhoneNumber).ToList();
            var emailRecipients = users.Where(u => u.EmailConfirmed).Select(v => v.Email).ToList();
            var command         = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    SmsMessage      = "You've been assigned a task from AllReady.",
                    SmsRecipients   = smsRecipients,
                    EmailMessage    = "You've been assigned a task from AllReady.",
                    HtmlMessage     = "You've been assigned a task from AllReady.",
                    EmailRecipients = emailRecipients,
                    Subject         = "You've been assigned a task from AllReady."
                }
            };
            await _mediator.SendAsync(command);
        }
Beispiel #15
0
        public async Task Handle(VolunteerSignupNotification notification)
        {
            var taskInfo = await _mediator.SendAsync(new TaskDetailForNotificationQueryAsync { TaskId = notification.TaskId, UserId = notification.UserId })
                           .ConfigureAwait(false);

            var emailRecipient = taskInfo?.Volunteer.Email;

            if (string.IsNullOrWhiteSpace(emailRecipient))
            {
                return;
            }

            var eventLink = $"View event: {_options.Value.SiteBaseUrl}/Event/Details/{taskInfo.EventId}";
            var subject   = "allReady Task Enrollment Confirmation";

            var message = new StringBuilder();

            message.AppendLine($"This is to confirm that you have volunteered to participate in the following task:");
            message.AppendLine();
            message.AppendLine($"   Campaign: {taskInfo.CampaignName}");
            message.AppendLine($"   Event: {taskInfo.EventName} ({eventLink})");
            message.AppendLine($"   Task: {taskInfo.TaskName}");
            message.AppendLine();
            message.AppendLine($"Thanks for volunteering. Your help is appreciated.");

            var command = new NotifyVolunteersCommand
            {
                ViewModel = new NotifyVolunteersViewModel
                {
                    EmailMessage    = message.ToString(),
                    HtmlMessage     = message.ToString(),
                    EmailRecipients = new List <string> {
                        emailRecipient
                    },
                    Subject = subject
                }
            };

            await _mediator.SendAsync(command).ConfigureAwait(false);
        }
        public async Task Handle(UserUnenrolls notification)
        {
            // don't let problem with notification keep us from continuing
            try
            {
                var notificationModel = _mediator.Send(new ActivityDetailForNotificationQuery {
                    ActivityId = notification.ActivityId, UserId = notification.UserId
                });

                var campaignContact = notificationModel.CampaignContacts.SingleOrDefault(tc => tc.ContactType == (int)ContactTypes.Primary);
                var adminEmail      = campaignContact?.Contact.Email;

                if (string.IsNullOrWhiteSpace(adminEmail))
                {
                    return;
                }

                TaskSummaryModel taskModel = null;
                string           remainingRequiredVolunteersPhrase;
                var isActivityUnenroll = (notificationModel.ActivityType == ActivityTypes.ActivityManaged);

                if (isActivityUnenroll)
                {
                    remainingRequiredVolunteersPhrase = $"{notificationModel.UsersSignedUp.Count}/{notificationModel.NumberOfVolunteersRequired}";
                }
                else
                {
                    taskModel = notificationModel.Tasks.FirstOrDefault(t => t.Id == notification.TaskIds[0]) ?? new TaskSummaryModel();
                    remainingRequiredVolunteersPhrase = $"{taskModel.NumberOfVolunteersSignedUp}/{taskModel.NumberOfVolunteersRequired}";
                }


                var activityLink = $"View activity: {_options.Value.SiteBaseUrl}Admin/Activity/Details/{notificationModel.ActivityId}";
                var subject      = $"A volunteer has unenrolled from {(isActivityUnenroll ? "an activity" : "a task")}";

                var message = new StringBuilder();
                message.AppendLine($"A volunteer has unenrolled from {(isActivityUnenroll ? "an activity" : "a task")}.");
                message.AppendLine($"   Volunteer: {notificationModel.Volunteer.Name} ({notificationModel.Volunteer.Email})");
                message.AppendLine($"   Campaign: {notificationModel.CampaignName}");
                message.AppendLine($"   Activity: {notificationModel.ActivityName} ({activityLink})");
                if (!isActivityUnenroll)
                {
                    message.AppendLine($"   Task: {taskModel.Name} ({$"View task: {_options.Value.SiteBaseUrl}Admin/Task/Details/{taskModel.Id}"})");
                    message.AppendLine($"   Task Start Date: {taskModel.StartDateTime?.Date.ToShortDateString()}");
                }
                message.AppendLine($"   Remaining/Required Volunteers: {remainingRequiredVolunteersPhrase}");
                message.AppendLine();


                if (isActivityUnenroll)
                {
                    var assignedTasks = notificationModel.Tasks.Where(t => t.AssignedVolunteers.Any(au => au.UserId == notificationModel.Volunteer.Id)).ToList();
                    if (assignedTasks.Count == 0)
                    {
                        message.AppendLine("This volunteer had not been assigned to any tasks.");
                    }
                    else
                    {
                        message.AppendLine("This volunteer had been assigned to the following tasks:");
                        message.AppendLine("   Name             Description               Start Date           TaskLink");
                        foreach (var assignedTask in assignedTasks)
                        {
                            var taskLink = $"View task: {_options.Value.SiteBaseUrl}Admin/Task/Details/{assignedTask.Id}";
                            message.AppendFormat("   {0}{1}{2:d}{3}",
                                                 assignedTask.Name?.Substring(0, Math.Min(15, assignedTask.Name.Length)).PadRight(17, ' ') ??
                                                 "None".PadRight(17, ' '),
                                                 assignedTask.Description?.Substring(0, Math.Min(25, assignedTask.Description.Length)).PadRight(26, ' ') ??
                                                 "None".PadRight(26, ' '),
                                                 assignedTask.StartDateTime?.Date.ToShortDateString().PadRight(21, ' ') ?? "".PadRight(21, ' '),
                                                 taskLink);
                        }
                    }
                }


                var command = new NotifyVolunteersCommand
                {
                    ViewModel = new NotifyVolunteersViewModel
                    {
                        EmailMessage    = message.ToString(),
                        HtmlMessage     = message.ToString(),
                        EmailRecipients = new List <string> {
                            campaignContact.Contact.Email
                        },
                        Subject = subject
                    }
                };
                await _mediator.SendAsync(command).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                _logger.LogError($"Exception encountered: message={e.Message}, innerException={e.InnerException}, stacktrace={e.StackTrace}");
            }
        }
        public async Task<IActionResult> Assign(int id, List<TaskViewModel> tasks)
        {
            if (!UserIsTenantAdminOfActivity(id))
            {
                return new HttpUnauthorizedResult();
            }

            var updates = tasks.ToModel(_dataAccess).ToList();
            //TODO: Replacement for API like Tasks.UpdateRange(updates);
            foreach (var item in updates)
            {
                await _dataAccess.UpdateTaskAsync(item);
            }

            // send all notifications to the queue
            var smsRecipients = new List<string>();
            var emailRecipients = new List<string>();

            foreach (var allReadyTask in updates)
            {
                // get all confirmed contact points for the broadcast
                smsRecipients.AddRange(allReadyTask.AssignedVolunteers.Where(u => u.User.PhoneNumberConfirmed).Select(v => v.User.PhoneNumber));
                emailRecipients.AddRange(allReadyTask.AssignedVolunteers.Where(u => u.User.EmailConfirmed).Select(v => v.User.Email));
            }

            var command = new NotifyVolunteersCommand
            {
                // todo: what information do we add about the task?
                // todo: should we use a template from the email service provider?
                // todo: what about non-English volunteers?
                ViewModel = new NotifyVolunteersViewModel
                {
                    SmsMessage = "You've been assigned a task from AllReady.",
                    SmsRecipients = smsRecipients,
                    EmailMessage = "You've been assigned a task from AllReady.",
                    EmailRecipients = emailRecipients,
                    Subject = "You've been assigned a task from AllReady."
                }
            };

            _bus.Send(command);

            return RedirectToRoute(new { controller = "Activity", Area = "Admin", action = "Details", id = id });
        }
Beispiel #18
0
        public async Task Handle(VolunteerSignedUpNotification notification)
        {
            // don't let problem with notification keep us from continuing
            try
            {
                var taskInfo = await _mediator.SendAsync(new TaskDetailForNotificationQuery { TaskId = notification.TaskId, UserId = notification.UserId });

                var campaignContact = taskInfo.CampaignContacts?.SingleOrDefault(tc => tc.ContactType == (int)ContactTypes.Primary);
                var adminEmail      = campaignContact?.Contact.Email;
                if (string.IsNullOrWhiteSpace(adminEmail))
                {
                    return;
                }

                var eventLink = $"View event: http://{_options.Value.SiteBaseUrl}/Admin/Event/Details/{taskInfo.EventId}";

                var @task = await _context.Tasks.SingleOrDefaultAsync(t => t.Id == notification.TaskId);

                if (@task == null)
                {
                    return;
                }

                var taskLink   = $"View task: http://{_options.Value.SiteBaseUrl}/Admin/task/Details/{@task.Id}";
                var taskSignup = @task.AssignedVolunteers.FirstOrDefault(t => t.User.Id == taskInfo.Volunteer.Id);

                //set for task signup
                var          volunteerEmail       = taskInfo.Volunteer.Email;
                var          volunteerPhoneNumber = taskInfo.Volunteer.PhoneNumber;
                var          volunteerComments    = !string.IsNullOrWhiteSpace(taskSignup?.AdditionalInfo) ? taskSignup.AdditionalInfo : string.Empty;
                var          remainingRequiredVolunteersPhrase = $"{@task.NumberOfUsersSignedUp}/{@task.NumberOfVolunteersRequired}";
                const string typeOfSignupPhrase = "a task";

                var subject = $"A volunteer has signed up for {typeOfSignupPhrase}";

                var message = new StringBuilder();
                message.AppendLine($"A volunteer has signed up for {typeOfSignupPhrase}:");
                message.AppendLine();
                message.AppendLine($"   Campaign: {taskInfo.CampaignName}");
                message.AppendLine($"   Event: {taskInfo.EventName} ({eventLink})");
                message.AppendLine($"   Task: {@task.Name} ({taskLink})");
                message.AppendLine($"   Remaining/Required Volunteers: {remainingRequiredVolunteersPhrase}");
                message.AppendLine();
                message.AppendLine($"   Volunteer Name: {taskInfo.Volunteer.Name}");
                message.AppendLine($"   Volunteer Email: {volunteerEmail}");
                message.AppendLine($"   Volunteer PhoneNumber: {volunteerPhoneNumber}");
                message.AppendLine($"   Volunteer Comments: {volunteerComments}");
                message.AppendLine();
                message.AppendLine(GetTaskSkillsInfo(@task, taskInfo.Volunteer));

                var command = new NotifyVolunteersCommand
                {
                    ViewModel = new NotifyVolunteersViewModel
                    {
                        EmailMessage    = message.ToString(),
                        HtmlMessage     = message.ToString(),
                        EmailRecipients = new List <string> {
                            adminEmail
                        },
                        Subject = subject
                    }
                };

                await _mediator.SendAsync(command);
            }
            catch (Exception e)
            {
                _logger.LogError($"Exception encountered: message={e.Message}, innerException={e.InnerException}, stacktrace={e.StackTrace}");
            }
        }
        public async Task Handle(VolunteerSignupNotification notification)
        {
            // don't let problem with notification keep us from continuing
            try
            {
                var volunteer = await _context.Users.SingleAsync(u => u.Id == notification.UserId).ConfigureAwait(false);

                var campaignEvent = await _context.Events
                                    .Include(a => a.RequiredSkills).ThenInclude(r => r.Skill)
                                    .SingleAsync(a => a.Id == notification.EventId).ConfigureAwait(false);

                var eventSignup = campaignEvent.UsersSignedUp.FirstOrDefault(a => a.User.Id == notification.UserId);

                var campaign = await _context.Campaigns
                               .Include(c => c.CampaignContacts).ThenInclude(cc => cc.Contact)
                               .SingleOrDefaultAsync(c => c.Id == campaignEvent.CampaignId).ConfigureAwait(false);

                var campaignContact = campaign.CampaignContacts?.SingleOrDefault(tc => tc.ContactType == (int)ContactTypes.Primary);
                var adminEmail      = campaignContact?.Contact.Email;
                if (string.IsNullOrWhiteSpace(adminEmail))
                {
                    return;
                }

                var IsEventSignup = (campaignEvent.EventType == EventTypes.EventManaged);
                var eventLink     = $"View event: http://{_options.Value.SiteBaseUrl}/Admin/Event/Details/{campaignEvent.Id}";

                AllReadyTask task       = null;
                string       taskLink   = null;
                TaskSignup   taskSignup = null;

                if (!IsEventSignup)
                {
                    task = await _context.Tasks.SingleOrDefaultAsync(t => t.Id == notification.TaskId).ConfigureAwait(false);

                    if (task == null)
                    {
                        return;
                    }
                    taskLink   = $"View task: http://{_options.Value.SiteBaseUrl}/Admin/task/Details/{task.Id}";
                    taskSignup = task.AssignedVolunteers.FirstOrDefault(t => t.User.Id == volunteer.Id);
                }

                //set defaults for event signup
                var volunteerEmail       = !string.IsNullOrWhiteSpace(eventSignup?.PreferredEmail) ? eventSignup.PreferredEmail : volunteer.Email;
                var volunteerPhoneNumber = !string.IsNullOrWhiteSpace(eventSignup?.PreferredPhoneNumber) ? eventSignup.PreferredPhoneNumber : volunteer.PhoneNumber;
                var volunteerComments    = eventSignup?.AdditionalInfo ?? string.Empty;
                var remainingRequiredVolunteersPhrase = $"{campaignEvent.NumberOfUsersSignedUp}/{campaignEvent.NumberOfVolunteersRequired}";
                var typeOfSignupPhrase = "an event";

                if (campaignEvent.EventType != EventTypes.EventManaged)
                {
                    //set for task signup
                    volunteerEmail       = !string.IsNullOrWhiteSpace(taskSignup?.PreferredEmail) ? taskSignup.PreferredEmail : volunteerEmail;
                    volunteerPhoneNumber = !string.IsNullOrWhiteSpace(taskSignup?.PreferredPhoneNumber) ? taskSignup.PreferredPhoneNumber : volunteerPhoneNumber;
                    volunteerComments    = !string.IsNullOrWhiteSpace(taskSignup?.AdditionalInfo) ? taskSignup.AdditionalInfo : volunteerComments;
                    remainingRequiredVolunteersPhrase = $"{task.NumberOfUsersSignedUp}/{task.NumberOfVolunteersRequired}";
                    typeOfSignupPhrase = "a task";
                }

                var subject = $"A volunteer has signed up for {typeOfSignupPhrase}";

                var message = new StringBuilder();
                message.AppendLine($"A volunteer has signed up for {typeOfSignupPhrase}:");
                message.AppendLine();
                message.AppendLine($"   Campaign: {campaign.Name}");
                message.AppendLine($"   Event: {campaignEvent.Name} ({eventLink})");
                if (!IsEventSignup)
                {
                    message.AppendLine($"   Task: {task.Name} ({taskLink})");
                }
                message.AppendLine($"   Remaining/Required Volunteers: {remainingRequiredVolunteersPhrase}");
                message.AppendLine();
                message.AppendLine($"   Volunteer Name: {volunteer.Name}");
                message.AppendLine($"   Volunteer Email: {volunteerEmail}");
                message.AppendLine($"   Volunteer PhoneNumber: {volunteerPhoneNumber}");
                message.AppendLine($"   Volunteer Comments: {volunteerComments}");
                message.AppendLine();
                message.AppendLine(IsEventSignup ? GetEventSkillsInfo(campaignEvent, volunteer) : GetTaskSkillsInfo(task, volunteer));

                Debug.WriteLine(adminEmail);
                Debug.WriteLine(subject);
                Debug.WriteLine(message.ToString());

                if (!string.IsNullOrWhiteSpace(adminEmail))
                {
                    var command = new NotifyVolunteersCommand
                    {
                        ViewModel = new NotifyVolunteersViewModel
                        {
                            EmailMessage    = message.ToString(),
                            HtmlMessage     = message.ToString(),
                            EmailRecipients = new List <string> {
                                adminEmail
                            },
                            Subject = subject
                        }
                    };

                    await _mediator.SendAsync(command).ConfigureAwait(false);
                }
            }
            catch (Exception e)
            {
                _logger.LogError($"Exception encountered: message={e.Message}, innerException={e.InnerException}, stacktrace={e.StackTrace}");
            }
        }