Assignment Notification task, customization and custom messages
Assignment Notification Customization and Standalone Notifications
When the new approval mechanism was introduced in SP4 we also added a new notification script. This was designed to be fairly flexible and usable for other notifications as well so you can use it in your workflows to send notifications about anything. I will do two things in this blog
1) Add additional/custom replacement strings to existing template
2) Use the Assignment Notification task to send a message as part of a regular (non-assignment) workflow
Common steps
Importing the Assignment Notification task and Notification Templates job folder
Start by importing the job folder and task and configuring the notification repository as outlined in the documentation. This is the quick version:
The templates are located in “\usr\sap\IdM\Identity Center\Templates\Identity Center\Provisioning\Notifications“
The first thing to do is check if you need to fix a mistake we did. The Assignment Notification task was not made public in the template provided with some versions. So open the task and verify that Public is checked, and if not, check it and save:
If this is not done any attempts to start this task using uProvision will be rejected.
Configure the notification repository values
You also need a notification repository with these values set:
Import the standard notification templates
Next we need to update the templates in the database, so run the job named Import notification templates and verify there are no errors.
Create a basic approval workflow
Create a test privilege
The privilege for this does not need anything more than a name and pointing the Validate Add task to the Assignment Approval Workflow that we created
Creating users and repeatedly testing
It’s very useful to create a small job that just creates a new user and perform a few test operations on it, and this sample can be used in a multitude of scenarios. In this job I have two very simple passes. The first just sets an email address on the user I’ve decided to use as an approver:
The next pass creates a new user prefixed with the %ddm.job% constant which is a counter that increases every time the job is run.
This means that every time I run this job a user with the name USER.TEST.BLOGNOTIFICATION.<number> will be created and assigned the privilege that has the approval task, and I can rerun this and test the approval process with new users as many times as I need until I get all the bugs sorted out of my configuration.
At this point you should be able to run the job and get a notification in your mailbox when the assignment hits the approval task, more or less like this one if you’re using the same release as me. Not perfect, but enough for this purpose:
End of Common
Customizing existing message with new strings
This is a fairly simple operation and I will use the Initial Approval Notification sent to approvers to demonstrate this. The notification script looks at the context variables for most of its data. All the template files use a syntax of PAR_<VARIABLENAME> for text replacement strings. These are passed to the notification script as context variables named MSG_PAR_<VARIABLENAME>. This means that to add a new value all you have to do is
1) Add the new string replacement variable to the template file
2) Add the context variable using the uSetContextVar function
Editing the template
Locate the file AssignmentRequestApprovalinitialnotification_EN.html in \usr\sap\IdM\Identity Center\Templates\Identity Center\Provisioning\Notifications. Open it in a UTF-8 compatible editor and start editing. For this example I’ve modified the end of the file and added PAR_QOTD where the copyright notice used to be, and inserted a shoppinglist reminder above the URL:
Next we need to update the templates in the database, so run the job named Import notification templates as outlined in the common section
Setting the additional variables in the workflow
First we need an Assignment Approval workflow, again I keep most of this short and simple, it’s well documented in tutorials etc. and focus on the new part, Add custom message variables. The basic layout of the task is described in the Common section.
// Main function: setCTXVARS
function setCTXVARS(Par){
tmp = Par.get("MSGVARS");
ctxVars = uSplitString(tmp,"!!");
for (ctxvar = ctxVars.iterator(); ctxvar.hasNext();dummy=1)
{
tmp = ctxvar.next();
vals = tmp.split("=");
ctxVarToSet = "#MSG_"+vals[0];
ctxValToSet = vals[1];
OutString = uSetContextVar(ctxVarToSet, ctxValToSet);
}
}
The QOTD script returns a random string. I’ll attach it to the end of the blog for the curious.
With the templates up to date in the system it’s time to test, and to do that we just run the testjob from the common section again. My result, red outlines around the changes are added by me:
End of Customizing existing message with new strings!
Sending custom messages
This is a bit more complex. First we need to create a new template. The default location for the template files is
\usr\sap\IdM\Identity Center\Templates\Identity Center\Provisioning\Notifications
Creating a new template
Make sure you use a text editor that can save the file as UTF-8 without BOM (Byte Order Mark, gives two garbage chars at the beginning of the message if included) when performing the next steps.
We’re creating a new message template text file named MyCustomMessage_EN.html with the following content:
<html>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<head>
</head>
<body>
<p>Something PAR_DESCRIPTION has happened!</p>
</body>
</html>
Next we need to add a row describing this template to the index file, AssignmentNotificationsList.txt:
Here’s the text for those who like things easy.
Custom Workflow Message;EN;999;Its custom;Message for you sir;CHARENC=UTF8;MyCustomMessage_EN.html;CUSTOM
Importing the template
Next we need to get this template into the mc_templates table. This is what the Import Notification Templates job we imported earlier does. Run it and check the log. There should be no warnings or errors. You can also verify the database contents using this query
select * from mc_templates where mcClass = 'CUSTOM'
The result should be something like this:
Starting the notification from a workflow
Now we’re ready to trigger the notification. It requires some fixed values to be set to work, and these are:
#MSG_TEMPLATE Should match the name we used: Custom Workflow Message
#MSG_TYPE Should match the message class used: CUSTOM
#MSG_RECIPIENTS Is the MSKEY of the user message recipient
#MSG_PAR_<variables> Whatever else we feel like saying
I already made a script that sets a range of context variables earlier so I reuse it with a small modification in the script. This can be part of pretty much any workflow, you decide where it makes sense to you. My test task works as a UI task and when started using test provisioning and should give you some ideas on how to use it, nothing more:
// Main function: setCTXVARS
function setCTXVARS(Par){
tmp = Par.get("MSGVARS");
ctxVars = uSplitString(tmp,"!!");
for (ctxvar = ctxVars.iterator(); ctxvar.hasNext();dummy=1)
{
tmp = ctxvar.next();
uInfo(tmp);
vals = tmp.split("=");
ctxVarToSet = "#MSG_"+vals[0];
ctxValToSet = vals[1];
OutString = uSetContextVar(ctxVarToSet, ctxValToSet);
}
mskey = Par.get("MSKEY");
taskid = Par.get("NOTIFICATIONTASKID");
AuditID = uGetAuditID();
OutString = uProvision(mskey ,taskid ,AuditID, 0, "does this work?",0);
}
The key change is that in addition to set the #MSG_ context variables it also calls the Notification task. This is brute force hard-coded taskid in the action, no error checking and not pretty code. So go forth and improve it.
Anyway, the result in my case was a very simple but satisfying email in my inbox:
And thats it.
Additional data
What does all this context variable look like anyway
At the time when the Assignment Notification action runs the mc_audit_variables table can look like this:
And for the custom notification:
Quote of the Day script
, not well designed or thought out but for this sample it does what it needs to
// Main function: qotd
function qotd(Par){
qn = Math.floor((Math.random()*5)+1);
if (qn == 1) {
return "A day without sunshine is like, night";
} else
if (qn == 2) {
return "A penny saved is a government oversight";
} else
if (qn == 3) {
return "When everything comes your way you're in the wrong lane";
} else
if (qn == 4) {
return "Silence is golden, duct tape is silver";
} else
if (qn == 5) {
return "The road to success is always under construction";
}
return "You should not be here?! No quote for you!";
}
As always, great stuff! Thanks for sharing. I like the QOTD, maybe it should greet all users when they sign in! 🙂
Your blogs are the best Chris. Keep 'em coming and I'll keep learning from them.
Thanks for the blog post.
An additional information on creating the custom notification template .We have used IDM admin link - Message Templates tab as shown below.
This will allow us to provide the message body which can be a html content [ can get a copy of template body from a standard template and amend where required]
By saving the template here in this link , the template file gets automatically created in the IdentityCenter->Templates->Identity Center->Provisioning->Notifications folder.
Also the template gets updated automatically in the mc_templates table.
So only thing we need to update is to update the AssignmentNotificationList file with this new template. For doing this , we can use "Export Notification templates" from job folder to get the file exported from the mc_templates table to a text file and replace the contents of the AssignmentNotificationList file with this exported content after verification.
By this way ,we can avoid updating the content in the template file editors.
Thank you
Very useful, as always. But I want to know the implication of not updating the AssignmentNotificationList file with the new template. Isnt updating the mc_templates suffice? Wish I had system to check this.
Thanks,
Jaisuryan
The .txt file is just the initial templates shipped with IdM.
regards, Tero
Thanks Tero, so if I dont update the .txt file, it wont stop me from using my new template, isnt?
Regards,
Jaisuryan
No, you don't need to maintain the text file.
regards, Tero
One more query.. the mc_templates will be automatically updated only if I use Admin UI. If I create the .HTML file directly in the notification template folder, then I should update the .txt file and run the import job to update mc_templates table?
Thanks,
Jaisuryan
Yes , when we update the folder with the template directly , Import Notification Template (Standard SAP job) can be run to update mc_templates table. In this job , temporary table gets created from AssignmentNotificationList text file (this file should be updated when the new template gets created) and then the template gets updated into mc_templates table with To_database pass.
Hope this helps
Best Regards
Srilakshmi
This is a really great thread that I would like to update with some details from my experience:
We had requirements to include the role name (not just display name), the user's MSKEYVALUE and User country in the Notifications. Using all the information in this blog post, I was able to make it work and wanted to provide the scripts and details on how I did it.
I DID NOT modify Per's script above that actually calls the notification task.
I went into the AdminUI and created the templates that I wanted to use. What I don't understand is why you can create custom templates in the text file and designate them as CUSTOM and set their TYPE to 999, but you cannot create CUSTOM templates with the AdminUI and designate them as CUSTOM; all templates you create in the AdminUI are set to a type 2 and category of MX_APPROVALS.
Anyway, 🙂 after creating the templates in the AdminUI and setting up the custom PAR values per Per's instructions above, I was able to push those custom PAR values to my custom template by merely adding the PAR_<VALUE> in the actual HTML file. The displayed notification looks like this:
Now that the template works and can be tested with the static values placed in the custom notification job, its time to bring in values from other areas to place in the template (if you have a requirement for that).
Things to know. If you place a custom notification in workflow and set the source of the job to be the MX_PENDING_VALUE, then the MSKEY that is passed to the custom notification is the MSKEY of the pending value. For testing purposes, my custom jobs source is pointing to MX_PERSON (since I am kicking it off via a UI enabled Task).
After you create the script (that also executes the notification task - provided by Per above), you create your "To Generic" task and assign the script to the Next day entry (per Per's instructions above).
I created four (4) additional scripts that I use. One set is for the actual notification in workflow and the other set is just for the test job.
In my test job I HARDCODE the MSKEY of the role. In the workflow, the MSKEY of the role is retrieved from the pending value.
The test job scripts are as follows:
The above script merely writes the Par value -- the value in the ( ) -- to the log for review
The above script uses the Par value (which should be the users MSKEY) to retrieve the users MSKEYVALUE value and makes that value available to this job by assigning it to the PAR_MSKEYVALUE
The above script uses the Par value (which should be the users MSKEY) to retrieve the users MX_ADDRESS_COUNTRY value and makes that value available to this job by assigning it to the PAR_CTRY_NAME
The above script uses the Par value (which is a hard coded MSKEY of the role in this test job) to retrieve the roles MSKEYVALUE value and makes that value available to this job by assigning it to the PAR_ROLE_MSKEYVALUE.
Now that you have all the scripts created and assigned to this job, the template created in the AdminUI and the MSGVARS value set appropriately, you should ensure the NOTIFICATIONTASKID value in your job points to the "TASK" (not the job) of the default "Assignment Notification" Task (ensure its set to public per Per above).
The Workflow job scripts are as follows:
The highlighted value above is a MSKEY and is the MSKEY of the actual IdM user that the custom notification should go to (the recipient). If that notification should go to multiple people, create a distribution list in your email system that has an email address, create a local user directly in IdM and assign that distribution list email address to that user in IdM. Query the db and get the MSKEY of THAT user and hard code it into this job. For now, use your own MSKEY so you get all notifications.
The same z_getUserCountry script used in the test job
Keep in mind that the %MSKEY% variable that is in the z_getRoleMSKEYVALUE setting in the MSGVARS value is the %MSKEY% of the pending value and has replaced the hardcoded MSKEY in the similar but different test job)
Lastly, the WF related jobs all must have their source set as follows:
Since the WF related custom notifications MUST get the MSKEY of the pending value to get the user, their country and the MSKEYVALUE of the role in the Pending value, this setting cannot be missed.
To test my "test" job, I created it in the WF (as a job) not in the Jobs folder (as a job). I then enabled the folder the task was in and ensured the job was assigned to my dispatchers correctly. When I go to the UI, I search for a user, select them, do choose task, select my Custom Notifications folder and the job. When I execute, it takes me to another page where I click SUBMIT (which I changed to SEND) and it sends. I monitor the progress by checking the job log of the custom notification job and the Assignment Notification. If both are error free, I should be getting a message in email.
Keep in mind, you have to ensure you set the DEBUG settings in the NOTIFICATIONS repository correctly per the documentation
Having all this information would have made my job creating custom notifications so much easier. I hope this helps someone else.