I’m trying to suppress the Requester and Requestee email notifications for two specific roles:
OnBase_All_Users
Unity Client
I tried the following approaches, but the email is still being sent.
Approach 1
#if(!($requestedObjectType == "Role" &&
($requestedObjectName == "OnBase_All_Users" ||
$requestedObjectName == "Unity Client")))
<p>Dear $user.name,</p>
<p>$requesterName has requested the following access on your behalf:</p>
#foreach($type in $requestedObjectDetailsByType.keySet())
<p><strong>$type</strong></p>
<ul>
#foreach($detail in $requestedObjectDetailsByType.get($type))
<li>
<strong>$detail.name</strong>
#if($detail.startDate)
(Access Start Date: $detail.startDate)
#end
#if($detail.removeDate)
(Access End Date: $detail.removeDate)
#end
</li>
#end
</ul>
#end
<p>Thanks,<br>The ${PRODUCT_NAME} Team</p>
#end
Approach 2
#set($skip = false)
#foreach($type in $requestedObjectDetailsByType.keySet())
#foreach($detail in $requestedObjectDetailsByType.get($type))
#if($type == "ROLE" && ($detail.name == "OnBase_All_Users" || $detail.name == "Unity Client"))
#set($skip = true)
#end
#end
#end
#if($skip)
#stop
#else
<p>Dear ${user.name},</p>
<p>${requesterName} has requested the following access on your behalf:</p>
#foreach($type in $requestedObjectDetailsByType.keySet())
<p>$type:</p>
<ul>
#foreach($detail in $requestedObjectDetailsByType.get($type))
<li>${detail.name}</li>
#end
</ul>
#end
<p>Thanks,<br>The ${PRODUCT_NAME} Team</p>
#end
Both approaches still send the email.
Has anyone successfully suppressed email notifications for specific roles using ISC email templates? Is this supported, or is the email decision made before the Velocity template is evaluated?
Unfortunately this isn’t achievable through the email template, and your suspicion at the end is correct — the decision to send the notification is made by the notification service before the Velocity template is rendered. The template only controls the body content, not whether the email is dispatched.
Try the no_send or Stop keywords by using conditional subject line in the email template. Something similar to this by using the supported global variables.
Your Approach 2 is close, but I think the issue is that the condition is in the body instead of the Subject. From what the docs say, ISC suppresses the email only when the rendered subject starts with no_send or Stop. So body-level Velocity would just control what content shows up inside the email, but it won’t actually stop it from going out.
For Access Request for Other, try something like this as the Subject:
#set($s=false)#foreach($d in $requestedObjectDetailsByType.get("ROLE"))#if($d.name=="OnBase_All_Users"||$d.name=="Unity Client")#set($s=true)#end#end#if($s)no_send#{else}${requesterName} Has Requested Access on Your Behalf#end
For Access Request Submitted Email for Requester After Validation, the variables are different, so this should work:
#set($s=false)#foreach($r in $requestDetails)#set($l=$r.getSuccessDetails().get("ROLE"))#foreach($i in $l)#if($i.objectName=="OnBase_All_Users"||$i.objectName=="Unity Client")#set($s=true)#end#end#end#if($s)no_send#{else}Access request submitted#end
Make sure the Velocity starts at the very beginning of the Subject with no leading spaces or line breaks.
The admin “Test Email” button won’t populate these request-specific variables, so you would want to test with an actual access request for one of those roles. Also, if either role is requested together with other items in the same request, the full summary email would get suppressed since the subject evaluates per email, not per item.
I’ve had no luck getting this to work as expected. I tried the following two approaches:
#set($m=$requestedObjectDetailsByType.get("ROLE"))#set($s=$m&&($m.toString().contains("OnBase_All_Users")||$m.toString().contains("Unity Client")))#if($s)#stop#else${requesterName} Has Requested Access on Your Behalf#end
and
#set($s=false)#set($m=$requestedObjectDetailsByType)#foreach($t in $m.keySet())#foreach($d in $m.get($t))#if($t=="ROLE"&&($d.name=="OnBase_All_Users"||$d.name=="Unity Client"))#set($s=true)#end#end#end#if($s)#stop#elseRequest submitted.#end
Unfortunately, neither approach works. The condition is always skipped, and the email is still sent.
My suspicion is that the variables I’m using may not be correct. Specifically, I want to confirm whether requestedObjectDetailsByType actually contains the requested role details and whether each object within it has a name property.
Is there any way to verify the structure of requestedObjectDetailsByType or inspect the variables available to the email template? Any guidance on how to confirm the available variables or debug the template would be greatly appreciated.
Hello Gopi. requestedObjectDetailsByType is the right variable. SailPoint’s own default Access Request for Other template loops through this same map and reads ${detail.name}, so the structure is confirmed.
I think the issue might be the "ROLE" key check and the use of #stop. The exact map key isn’t documented as far as I can tell, so .get("ROLE") could be returning null and skipping the condition entirely. And for the suppression part, the currently documented keywords are the literal text no_send or Stop at the beginning of the rendered Subject.
Try this as a single line in the Subject:
#set($s=false)#foreach($t in $requestedObjectDetailsByType.keySet())#foreach($d in $requestedObjectDetailsByType.get($t))#if($d.name=="OnBase_All_Users"||$d.name=="Unity Client")#set($s=true)#end#end#end#if($s)no_send#elseRequest submitted#end
This checks every requested object without depending on the type key, same traversal pattern as the default template. To confirm exactly what your tenant is passing, you could temporarily add this to the email body:
<pre>$__contentJson</pre>
Redirect emails to a test address and submit a real access request for one of those roles. The “Test Email” button only populates global variables, so request-specific values will show up as null there.
I think the option to block notification using standard email notifications could be tricky in terms of mainability of solution in longer run. The main way to achieve this is by using subject field on standard notifications. But this field has a limit of certain number of characters (250 i think). Even if you manage to achieve it even by renaming the role to keep the name very short, then too in longer run it will cause issues if role list increases.
Below are couple of approaches which you could use in my opinion
Can you use birthright role criteria for these roles so instead of assigning the access via access request, maintain birthright criteria such as no notification gets triggered.
Another option is to completely turn off this notification and maintain no_send in the subject and rely on workflows to send these notifications. Here you will need to then block all access request related notifications and handle even access request approved or declined sort of notifications via workflow. It gives you quite some flexibility but then maintenance and creating this framework is something that will consume lot of time so if it only for two roles, then may be it is not worth going this route.
But in my opinion, primary option would be to use the subject field to stop the notifications being sent.
Yes, that’s exactly the tricky and challenging part—the 250-character limit in the subject field. To work around this, we’ve added prefixes to most of the roles so that we can keep the subject logic as short as possible while still excluding the required roles from triggering email notifications.
Regarding your first suggestion, the organization requires every role to be requestable, and we don’t have an RBAC/birthright role implementation in our architecture. Because of that, converting these roles to birthright roles isn’t an option.
As for your second suggestion, while using workflows would definitely provide more flexibility, someone would need to own and maintain that framework. In our case, the operations team doesn’t typically handle these kinds of operational workflow customizations, so introducing and maintaining a workflow-based notification framework wouldn’t be practical.
Given our current architecture and operational model, the most feasible approach is to modify the existing email template and selectively suppress notifications for only the roles that don’t require them.
Thanks for your suggestions—they were helpful and gave me a few ideas to consider.
Yes, i completely forgot about something similar i did for similar requirement where i made use of contain method from velocity text. I think with that if you can have certain naming convention for the roles falling in this scope, then it is something that can help you because then you do not have to check for every role individually but you can check for that specific substring or check if the role starts with this name, that could potentially help you.
Another option is also populating the identity attribute on the user based on these roles but since notifications will start getting sent immediately after the request is submitted, the identity attribute population approach may not work. But you can perhaps think in that direction if somehow it is possible to populate the identity attribute on the user then you can just check $user.StopNotification = true then stop otherwise send the notification.
Thanks! That’s exactly the approach I went with. I used the contains() method with a naming convention, which made the logic much simpler and avoided checking each role individually. Appreciate the suggestion!