JavaScript Reference

This page lists different things which can be used in JavaScript blocks

Script variables for modified entity source

args.Author — an object representing the modifier

args.Current — this is an object representing the current state of modified entity.

// Get the name of the modified entity
const name = args.Current.Name;

// Most fields listed at /api/v1/Index/meta can be used
//
// Custom fields can be accessed directly by their name:
const cfValue1 = args.Current.Category;
const cfValue2 = args.Current["Expected Risk"];

// All own simple fields like Name, Effort, Description should be available
// Reference fields like Project have only a limited number of fields: Id and Name
const projectName = args.Current.Project.Name;
// So this WILL NOT work:
args.Current.Project.EntityState.Name;
// Collections ARE NOT available so this WILL NOT work:
args.Current.Bugs.Count

// If the script requires additional data, it can be retrieved through call to "targetprocess/api/v2" service.

args.Modification — a string representing the last modification type. Available values are: "Created", "Updated", "Deleted"

args.Previous — an object representing the state of the entity before modification. When args.Modification is "Created", this field is set to null

const originalEffort = args.Previous.Effort;

args.ResourceId — a number containing ID of the modified entity

args.ResourceType — a string representing the type of the modified entity, e.g. "UserStory", "Bug", "TeamAssignment".

args.ChangedFields — an array of string that contains the name of fields which were modified in scope of event which triggered the rule.

// Check whether the name of the User Story was modified:
const wasNameChanged = args.ChangedFields.contains("Name");

Script variables for incoming web hook source

args.headers — an object that represents header of incoming http request.

args.body — an object that represents body of incoming http request.

const branch = args.body.object_attributes.ref;

Querying Targetprocess API

context.getService("targetprocess/apiv2") — a call to this function returns a service which lets the script make queries to Targetprocess API v2.
require("targetprocess/api/v2") — the service can be also retrieved by this way.

Here's an example of fetching 100 Bugs ordered by Name for modified User Story:

const userStoryId = args.ResourceId;

const api = context.getService("targetprocess/api/v2");

// `querySpec` here mirrors the shape of API v2 query parameters,
// such as `select`, `where`, `result`, etc.
// See https://dev.targetprocess.com/docs/api-v2-overview for details
const querySpec = {
    select: "{id, name}",
    where: "userStory.id == " + userStoryId,
    take: 100,
    orderBy: "name"
};

// `queryAsync` function makes HTTP call to tpondemand.com/api/v2/bugs
const bugs = await api.queryAsync(
  // The first argument is the name of Targetprocess entities to query
  "bug",
  // The second is our query definition — filters, fields to return, etc.
  querySpec);

// At this point, `bugs` is an array of objects with the fields specified in `querySpec.select`, e.g.
// [ 
//   {id: 1, name: "First Bug"},
//   {id: 2, name: "Second Bug"}
// ]

const firstBugName = bugs[0].name;

Targetprocess API client can also query individual resources using getByIdAsync method

const api = context.getService("targetprocess/api/v2");
const userStoryDetails = await api.getByIdAsync(
  // Return details of UserStory#42
  "UserStory", 42,
  // 3rd parameter acts like `select` in API v2 query and lets the script specify which fields of resource to fetch
  {select: "{id,name,bugsCount:Bugs.Count}"});

if (!userStoryDetails) {
  console.error("There is no such User Story");
} else {
  console.log(userStoryDetails.bugsCount);
}

Performing HTTP requests

context.getService("http") - a call to this function returns a service which lets the script perform HTTP requests to external APIs.
require("http") — the service can be also retrieved by this way.

HTTP service supports the following methods:

  • http.getAsync()
  • http.postAsync()
  • http.sendAsync()
  • http.putAsync()
  • http.deleteAsync()
  • http.patchAsync()

Here's an example that fetches data from some 3rd party API.

const http = context.getService('http');

const firstResponse = await http.getAsync('https://reqres.in/api/users');
// Response object contains the body of HTTP response directly.
console.log(firstResponse);

// Script can also pass HTTP headers
const secondResponse = await http.getAsync(
  'https://reqres.in/api/users',
  {
    headers: {
      'Authorization': 'Scheme Token'
    }
  }
);

console.log(secondResponse);

Another example with the post query to some webhook URL.

const http = require('http');

const response = await http.postAsync('https://webhook.site/123456', {
  headers: {
    'Some-header-key': 'some-value'
  },
  body: {
    "firstName": "John",
    "lastName": "Doe"
  }
});

PUT method example.

const http = context.getService("http")
 
const res = await http.putAsync("http://dummy.restapiexample.com/api/v1/update/21");

DELETE method.

const http = require('http');

const response = await http.deleteAsync('https://test.tpondemand.com/api/v1/UserStories/12345?token=1234567890==');

Access to HTTP response headers

Some integrations, pass required information in HTTP headers. Currently, there is a way to access them from JS automation rules.
sendAsync method was added to http service. This method returns a result object that provides access to response internals, e. g. statusCode, headers.

const http = require('http');

const response = await http.sendAsync('https://reqres.in/api/users', {
  method: 'POST',
  body: {
    "name": "morpheus",
    "job": "leader"
  }
});

console.log(response.statusCode); // Returns response status code as a number, e.g. 200
console.log(response.headers); // Returns all response headers as an object
console.log(response.headers['content-type']); // Returns particular response header value as a string value
console.log(response.body); // Returns response body as a string value

📘

White list for requests from Automation Rules

If you need to allow queries from automation rules service on your proxy\firewall, the list of IP-addresses to whitelist can be found at Apptio Community Targetprocess public IPs range.

Action commands

This section describes the format of commands which can be returned from JavaScript action blocks. Command format is describe with TypeScript syntax, and Example tab shows working command examples.

targetprocess:CreateResource allows to create a new Targetprocess entity, like Task or Project.

{
  command: "targetprocess:CreateResource",
  payload: {
    resourceType: string,
    // Shape of this field should follow API meta
    // See Example and /api/v1/Index/meta for details
    fields: object
  }
}
{
  command: "targetprocess:CreateResource",
  payload: {
    resourceType: "UserStory",
    fields: {
      // Reference fields like `Project` or `Feature`
      // should be specified as objects with `Id` field
      Project: { Id: 20 },
      Name: "New User Story",
      // You can also create nested objects
      Tasks: [
        { Name: "Task #1" },
        { Name: "Task #2" }
      ]
    }
  }
}

targetprocess:UpdateResource allows to modify the fields of existing Targetprocess entity

{
  command: "targetprocess:UpdateResource",
  payload: {
    resourceType: string,
    resourceId: number,
    // Shape of this field should follow API meta
    // See Example and /api/v1/Index/meta for details
    fields: object
  }
}
{
  command: "targetprocess:UpdateResource",
  payload: {
    resourceType: "UserStory",
    resourceId: 20,
    fields: {
      // Reference fields like `Project` or `Feature`
      // should be specified as objects with `Id` field
      Feature: { Id: 30 },
      Name: "Updated User Story name"
    }
  }
}

targetprocess:DeleteResource allows to delete existing Targetprocess entity

{
  command: "targetprocess:DeleteResource",
  payload: {
    resourceType: string,
    resourceId: number
  }
}
{
  command: "targetprocess:DeleteResource",
  payload: {
    resourceType: "UserStory",
    resourceId: 20
  }
}

targetprocess:MoveToState allows to move Targetprocess entity, like Bug or User Story, to the state of specified kind — Initial, Planned, or Final.

{
  command: "targetprocess:MoveToState",
  payload: {
    resourceType: string,
    resourceId: number,
    stateKind: 'Initial' | 'Planned' | 'Final'
  }
}
{
  command: "targetprocess:MoveToState",
  payload: {
    resourceType: "UserStory",
    resourceId: 40,
    stateKind: 'Planned'
  }
}

It is also possible to change the state by the Name of the state.

return {
  command: "targetprocess:MoveToState",
  payload: {
    resourceType: "UserStory",
    resourceId: args.ResourceId,
    stateName: "In Testing"
  }
}

Dates formatting

To format a date based on a specific timezone, the following approach can be used:

const myDate = new Date(); // 2020-02-10T11:16:34.240Z
const dateFormatter = new Intl.DateTimeFormat('en-US', { timeZone: "America/Chicago" });
const formattedDate = dateFormatter.format(myDate); // 2/10/2020

We do not recommend use .toLocaleDateString() because memory and CPU consumption are much higher than with the solution above.
For more details check this article.