I have an IApplicationService that does some work. I want to notify users that the work has completed. For example, content has been updated.
Now, I was going to inject my own NotificationProvider into my app service and send a message to users within the same organization.
My understanding is that if I publish a notification it will get sent to everyone who has subscribed. But if I explicitly publish a notification to a user, they will get it whether they subscribed or not. Is this correct?
What would be the best way to publish a notification to users that have subscribed that are also in the same organization.? Oh, and also have permissions to get that notification?
8 Answer(s)
-
0
Hi,
If you mean Tenant by organization, then you can check this document for sending a notification to all subscribed users of a Tenant <a class="postlink" href="https://aspnetboilerplate.com/Pages/Documents/Notification-System#publish-notifications">https://aspnetboilerplate.com/Pages/Doc ... ifications</a>.
You can also define permissionDependency for your notification, see <a class="postlink" href="https://aspnetboilerplate.com/Pages/Documents/Notification-System#notification-definitions">https://aspnetboilerplate.com/Pages/Doc ... efinitions</a>
If you want to send notification to users in a OrganizationUnit, then it is not possible by default. You need to get all users in that Organization Unit, then send one by one.
Thanks.
-
0
Yes to each user in an organization.
My question is, if I simply loop over all the users in an organization and send the notification explicitly, will the notification service respect the Subscribe/Unsubscribe options. In other words, if I send a notification to a user who has not subscribed AND who does not have permissions for that notification, will he get the notification?
-
0
This is what I'm thinking.... I haven't tried it yet. I'm about to. I created another AppService called ContentNotificationAppService. I'll call this on the client after a successful content creation. Is this the right direction? Rather than injecting some notification service in my ContentAppService?? Below is the method from ContentNoficationAppService.
public async Task ContentSubmitted(EntityDto<Guid> input) { var content = await _contents.GetAsync(input.Id); var org = await _organizations.GetAsync(content.OrganizationUnitId);
var users = await _userManager.GetUsersInOrganizationUnit(org, false); var currentUser = await _userManager.GetUserByIdAsync(AbpSession.GetUserId()); List<UserIdentifier> userIds = new List<UserIdentifier>(); foreach(var user in users) { if(user.Id == currentUser.Id) { // we don't need to send a notification to ourselves continue; } // we need to see if this is a manager within our organization bool isManager = await _userManager.IsGrantedAsync(user.Id, AppPermissions.Pages_Content_ManageContent); bool isSubscribed = await _notificationSubcriptionManager.IsSubscribedAsync(user.ToUserIdentifier(), ContentAppNotificationNames.ContentSubmitted); if(isManager && isSubscribed) { userIds.Add(user.ToUserIdentifier()); } } if (userIds.Count > 0) { // send the notification to the users await _notificationPublisher.PublishAsync( ContentAppNotificationNames.ContentSubmitted, data: new MessageNotificationData($"{currentUser.FullName} has submitted some content."), userIds: userIds.ToArray()); } }
-
0
BTW, my managers might be in parent organizations. So I need to go up the tree first. Is this a good way to do it?
var org = await _organizations.GetAsync(header.OrganizationUnitId); // go up the organization tree while(org.Parent != null) { org = org.Parent; } // now that we're on the top, get the users var users = await _userManager.GetUsersInOrganizationUnit(org, true);
***************************** [EDIT] *********************************** This is not the correct way to get managers of an organization. Obviously, it will get ALL the users within the tenant!!
This works though. I will probably make this an extension method since I frequently need to find managers within parent organizations.
List<User> users = new List<User>(); // go up the organization tree do { var ous = await _userManager.GetUsersInOrganizationUnit(org, false); users.AddRange(ous); org = org.Parent; } while (org != null);
-
0
Hi,
Yes, it is a good way I think. When you send a notification to a user, user's subscription to that notification and user's permission is considered.
If your app service is not called from UI but from other app services, then it is better to convert it to a domain service. But if it is called from UI, then it is good to have this as an app service.
Thanks.
-
0
Ok great. I'm running into an angular injection error.
I named my service IContentNotificationAppService. I tried to inject 'abp.services.app.contentNotification'. It complains that it cannot find 'abp.services.app.contentNotificationProvider'.
Is this due to some convention?
-
0
Nevermind..... forgot to inherit IApplicationService.
-
0
Ok :)