Task Assistant API

Introduction

The Task Assistant web service offers an API based on JSON-RPC (http://json-rpc.org/) to programmatically access core Task Assistant functionality, such as creating or modifying tasks directly, without having to go through the web-client interface.

This document includes a Java-based example that exercises these functions. This document is outlined as follows:

  1. API
  2. Task JSON format
  3. API Example

Requirements

Throughout this document, the following are in effect:


API

Following is a list of basic Task Assistant functions available through the JSON-RPC API.

All of the above calls must be sent to http://$TASK-ASSISTANT-SERVER/JSON-RPC, with the exception of login, which is conducted via regular HTTP POST or GET, instead of JSON-RPC.

All JSON-RPC calls have the required values for method and params described. params contains a JSON array, and values are given in the order they should appear. The callback id field is not specified, and is used at the discretion of the developer.

JSON-RPC API sessions must login before making JSON-RPC calls.


Login

Logging in must be performed via a HTTP GET or POST request to the Task Assistant server. Once a valid login request is made, the Task Assistant server will return a session cookie. This cookie must be maintained by the client and sent back with further JSON-RPC requests.

The request must be sent to http://$TASK-ASSISTANT-SERVER/login.jsp and have the following parameters set:

ParameterValue
action
login
userid
User Name
password
User Password

The action parameter must have login as its value. userid and password correspond to the user name and password for the account to use.


Logout

ParameterValue
methodAPI.logout
params

Logout requires no parameters, as the session information is tied with the cookie first obtained on login.


Download Task

ParameterValue
methodAPI.getTask
params[Task ID]

This returns a JSON object, with the Task stored under the "result" key. The Task format is described under the Task JSON format section.


Modify Task Property

ParameterValue
methodAPI.modifyTask
params[Task ID, Property Name, New Value]

For example, a call to set the SUMMARY property of Task id 123 to the value "Updated Name" is given as:

	{ "method" : "API.modifyTask, "params" : ["123", "SUMMARY", "Updated Name"] }
      

Task properties follow a subset of the iCalender format (RFC 5545). Those supported by Task Assistant, with the argument types and descriptions, are given in the following table:

PropertyTypeDescription
DUELongDue time for task, in milliseconds from epoch.
DUE_OFFSETDoubleDue time for task, in terms of the number of minutes from now.
TAGSStringComma delimited string of tags, spaces allowed (e.g., "Critical,Important,Battle Drill")
DURATIONLongDuration of task, in minutes
SUMMARYStringName of the task.
DESCRIPTIONStringDetailed task description.

Create Task

ParameterValue
methodAPI.createTask
params[Parent ID, Task Name, Position]

Parent ID corresponds to the Task ID of the task to attach the new task to. If Parent ID is set to -1, a new Tasklist is created instead.

Position corresponds to the position in the children of the parent Task (if any).

This call returns a JSON object containing the execution result, and a reference newly created task. To access the new task:

  1. On the returned execution result JSON object, access the result JSON object under the result object's "result" key.
  2. Obtain the task object by the accessing the result object's "tasklist" key.
The format is described under the
Task JSON format section.


Remove Task

ParameterValue
methodAPI.removeTask
params[Task ID]

This deletes the task with the given Task ID provided that the given user has permission to delete it.


Query Tasks by Name

ParameterValue
methodAPI.queryTasksByName
params[Query Text, Max Results]

This performs a string based search over task names, using the terms given in Query Text.

Query Text corresponds to the search terms used for finding task matches.

Max Results is the maximum number of results to return. Note: although this is a number, it must be given as a string.

The following example illustrates a query for Tasks containing the terms "high priority tasks", returning up to a maximum of 10 results.

	{ "method" : "API.queryTasksByName", "params" : [ "high priority tasks", "10" ] }
      

Any tasks matching the search query are returned in the execution result JSON object object. To access them:

  1. Access the result object under the "result" key.
  2. Access the JSON array under the result object's "list key.

Matching tasks are stored in the Task JSON format.



Task JSON format

Task objects returned by a download or query task request are represented as JSON objects. An example illustrating several pertinent fields follows:

{
      "tags":[],
      "position":0,
      "status": {"displayString":"incomplete","name":"INCOMPLETE","javaClass":"com.sri.ai.taskassistant.model.Status"},
      "root":false,
      "links":[],
      "properties": {"javaClass":"org.hibernate.collection.PersistentMap","map":{"COMPUTED-PERCENT-COMPLETE":"0","X-PERCENT-COMPLETE-UPDATE":"1269971301679","STATUS":"INPROGRESS"}},
      "formFields":[],
      "id":111,
      "createdBy":{"id":7,"lastName":"","prefs":{"javaClass":"org.hibernate.collection.PersistentMap","map":{"email":"exampleuser@ai.sri.com","ea_tasksDelegatedToMe":"true","ea_newComment":"true","ea_tasksIDelegated":"true"}},"email":"exampleuser@ai.sri.com","name":"exampleuser","administrator":true,"javaClass":"com.sri.ai.taskassistant.model.User","idName":"7","fullName":"exampleuser","firstName":"","forcePasswordChange":false,"disabled":false},
      "name": "Collect mission requirements",
      "delegatees":[],
      "annotations":[],
      "attachments":[],
      "childrenIds":[4458],
      "comments":[],
      "completed":false
}
    

Common Task fields of interest are:

KeyValue
tagslist of tags associated with this task
positionposition of task in parent task's list of children (if any)
statustask completion status information
idunique identifier for this task

API Example

This example illustrates how the API is used to perform the following tasks:

  1. Logging in.
  2. Creating a new Task.
  3. Performing a string search over Task names.
  4. Modify the SUMMARY property of the newly created Task.
  5. Deleting the Task.
  6. Logging out.

The demonstration application uses Apache HTTPComponents (http://hc.apache.org/) for web client functionality, and the JSON Java library (http://json.org/java/) for processing the JSON strings.

We now examine each of these steps in more detail. The following examples make use of the function jsonCall(String jsonStr), which takes the JSON formatted method call and submits it to the Task Assistant server. This function, along with the utility routine readHttpResponse are given here:

    public JSONObject jsonCall(String jsonStr) {
	try {
	    JSONObject jsonObj = new JSONObject(jsonStr);
	    HttpPost postObj = new HttpPost(RPC_URL);
	    postObj.setEntity(new StringEntity(jsonStr));
	    HttpResponse resp = hc.execute(postObj);
	    String respStr = readHttpResponse(resp);
	    if (respStr.length() > 0)
		return new JSONObject(respStr);
	    else
		return new JSONObject("{}");
	} catch (JSONException e) {
	    System.err.println(e.getMessage());
	    return null;
	} catch (Exception e) {
	    System.err.println(e.getMessage());
	    return null;
	}
    }

    public String readHttpResponse(HttpResponse resp) {
	try {
	    ByteArrayOutputStream buf = new ByteArrayOutputStream();
	    InputStream inStr = resp.getEntity().getContent();
	    int read = inStr.read();
	    while (read != -1) {
		buf.write(read);
		read = inStr.read();
	    }
	    resp.getEntity().consumeContent();
	    return buf.toString();
	} catch (Exception e) {
	    return null;
	}
    }
    
  1. Logging in

    Login is performed via HTTP Post, instead of the regular JSON-RPC interface. The following fragment uses the Apache HttpClient class to pass the userid and password to the Task Assistant server at LOGIN_URL.

          LOGIN_URL = SERVER_URL + "/login.jsp";
          List<NameValuePair> params = new ArrayList<NameValuePair>();
          params.add(new BasicNameValuePair("action", "login"));
          params.add(new BasicNameValuePair("userid", userid));
          params.add(new BasicNameValuePair("password", password));
          UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
          HttpPost postObj = new HttpPost(LOGIN_URL);
          postObj.setEntity(entity);
          HttpResponse resp = hc.execute(postObj); 
  2. Creating a new Task.

    	    JSONObject newTaskObj = jrpc.jsonCall("{\"method\" : \"API.createTask\", \"params\" : [\"-1\", \"New Test Tasklist\", \"0\"]}");
    	    String newId = newTaskObj.getJSONObject("result").getJSONObject("tasklist").getString("id");
    	    System.out.println("Created new task id = "+newId); 

    This requests that a new Task named "New Test Tasklist" be created. Setting the parent argument to be -1 indicates that no other Task is this Task's parent. The position argument, with value 0, is not used in this case, but is still required.

    The variable newId is bound to the value of the newly created Task's unique ID.

  3. Performing a string search over Task names.

    	JSONObject searchResult = jrpc.jsonCall("{\"method\" : \"API.queryTasksByName\", \"params\" : [\"new test tasklist\", \"10\"]}");
            JSONArray resultsArray = searchResult.getJSONObject("result").getJSONArray("list");
            System.out.println("Number of results found = "+resultsArray.length());
            for (int i=0;i<resultsArray.length(); i++) {
                JSONObject task = resultsArray.getJSONObject(i);
                String id = task.getString("id");
                String name = task.getString("name");
                System.out.println("Result #"+(i+1)+" id="+id+", name="+name);
            }

    This searches for tasks containing the search terms "new test tasklist", returning at most 10 results. The results themselves are packed in a JSONArray, each element being a Task in the form of a JSONObject.

  4. Modify a Task property.

    	    JSONObject modifyResult = jrpc.jsonCall("{\"method\" : \"API.modifyTask\", \"params\" : ["+newId+", \"SUMMARY\", \"Changed Test Task Name\"]}");	    
    	  

    This sets the name of the newly created Task, identified by newId, to "Changed Test Task Name".

  5. Remove the Task.

    	    JSONObject deleteResult = jrpc.jsonCall("{\"method\" : \"API.removeTask\", \"params\" : [\""+newId+"\"]");
    	  

    This deletes the newly created Task.

  6. Logout.

    	    JSONObject logoutResult = jrpc.jsonCall("{\"method\" : \"API.logout\", \"params\" : []}");	    
    	  

    This logs the user account out of the system, ending the session.

The required source, library files, and Ant buildfile are located in the zipfile, jsonrpc_example.zip (download temporarily disabled due to a licensing issue).

A build.xml is provided, and the example can be compiled using Apache Ant.

The compiled example accepts three arguments:

  1. A URL to an existing Task Assistant server (i.e., http://localhost:8080/taskassistant).
  2. Username of an existing account on the server.
  3. Password for the account.

For UNIX based systems, a convenience shellscript run.sh is provided for executing the example. The script musters the classpath and calls Java to execute the example, using the supplied arguments.

For example,

      run.sh http://localhost:8200/taskassistant testuser testpassword
    

On Windows systems, a corresponding batch file run.bat is provided for executing the example.

For example,

      run.bat http://localhost:8200/taskassistant testuser testpassword
    

This script executes the demonstration, using the Task Assistant server at http://localhost:8200/taskassistant, with an account whose username is "testuser" and password "testpassword".