Table of Contents

Update subject and message for all Notification Actions

This script finds all Notification Actions that are run for a failed step and updates them with a new notification subject and message.

When you leave the Subject or Message blank for a NotificationAction, adTempus uses a default subject and message, but there is currently no way to customize the template that is used in this case.

In this scenario, a customer wanted to define their own template to be used for messages sent when a step fails.

To accomplish this, they defined two server-level Job Variables, FailedStepSubject and FailedStepMessage, which defined the templates for the subject and message. Because Job Variable values can contain other job variables, you can use predefined variable tokens to have the job name, step number, etc., automatically inserted.

Next the script below is run to modify the Notification Actions for failed steps to use the FailedStepSubject and FailedStepMessage variables as their subject and message.

  • The script retrieves all jobs
  • For each job it examines all Responses at the job and step level
  • If a Response is triggered by the "Step Failed" event, the script processes the Actions for the Response
  • For any Notification that does not already have a Subject or Message set, the script sets the Subject and Message to the variable tokens "%FailedStepSubject%" and "%FailedStepMessage%"

This script can be run once for initial conversion, and/or run periodically from an adTempus job to convert any new jobs that are created after the first run.

public void Main()
   {

       // define the new subject and message.
       // in this case they are being set to Job Variables that are defined elsewhere
       string subject = "%FailedStepSubject%";
       string message = "%FailedStepMessage%";

       using (var session = Scheduler.Connect(".", LoginAuthenticationType.Windows, "", ""))
       {
           using (var context = session.NewDataContext())
           {
               // fetch all jobs on the server
               var jobs = context.GetJobs("*");
               foreach (var job in jobs)
                   UpdateJob(job, subject, message);
           }
       }
   }

   public void UpdateJob(Job job, string subject, string message)
   {
       var jobUpdated = false;

       // update job-level Responses
       if (UpdateResponses(job.Responses, subject, message))
       {
           Debug.WriteLine("Updated action(s) for " + job.FullyQualifiedName);
           jobUpdated = true;
       }

       // update the Responses for each step
       foreach (var jobStep in job.Steps)
       {
           if (UpdateResponses(jobstep.Responses, subject, message))
           {
               jobUpdated = true;
               Debug.WriteLine("Updated action(s) for " + job.FullyQualifiedName + " step " + jobStep.StepNumber);
           }
       }

       if (jobUpdated)
           job.Save();
   }


   // determines if the Response is triggered by the specified event
   private void ResponseContainsEvent(Response response, JobEvent targetEvent)
   {
       foreach (var item in response.Events)
       {
           if (item.Event == targetEvent)
               return true;
       }
       return false;
   }

   private bool UpdateResponses(System.Collections.ResponseCollection responses, string subject, string message)
   {
       var changesMade = false;

       foreach (var response in responses)
       {

           // in this example we are only looking for Responses that get triggered if the Step fails.
           // So we check the events for the Response to see if it is triggered by JobEvent.TaskFailed.
           // This way we don't update resonses for other events (e.g., job succeeded)
           if (ResponseContainsEvent(response, JobEvent.TaskFailed))
           {

               // response is triggered by the event we want.

               // look at all Actions for the Response and process NotificationActions
               foreach (var action in response.Actions)
               {
                   if (action.ClassID == ClassID.NotificationAction)
                   {
                       if (UpdateAction((NotificationAction)action, subject, message))
                           changesMade = true;
                   }
               }
           }
       }

       return changesMade;
   }

   // Update a NotificationAction to use a new Subject and Message if those values are not already set
   private bool UpdateAction(NotificationAction action, string subject, string message)
   {
       var actionUpdated = false;

       if (string.IsNullOrEmpty(action.NotificationMessage))
       {
           actionUpdated = true;
           action.NotificationMessage = message;
       }

       if (string.IsNullOrEmpty(action.NotificationSubject))
       {
           actionUpdated = true;
           action.NotificationSubject = subject;
       }

       return actionUpdated;
   }