Abhiram Diddigi home

Wunderlist - ServiceNow API

OK, so finally Wunderlist released a Public API. You can read about the API here: https://developer.wunderlist.com/documentation. The API like all the other APIs use the oAuth 2.0, but Wunderlist isn’t exactly 2.0. It is a partial implementation of oAuth 2.0.

If you scan Github for any libraries for Wunderlist, you will not really find any that refer to the new API ( there are a couple, but they use unofficial APIs), So I thought I could write one because I had a brand new Pebble time AND I was at Bozeman, chilling out and tubing and a lot of time to spend.

The reason why I chose ServiceNow is because I was speaking to one of the Integration Architects and he was asking me what my gotchas are about the new Scoped Application API. I never gave the API a spin, so this looked like an excellent use case to test the Scoped Application API. There is a lot of stuff that I learnt by writing this API, but there is really a lot to do in the app because of the limitations of the Scoped Application API.

So here is what the flow would look like, we only go through some snippets of code to the final product but not the final code in itself.

Below the Highlevel Architectural flow and the components I use to mimic oAuth. When I first saw that ServiceNow supports oAuth, I was excited that I can authenticate other systems using oAuth, then I understood that ServiceNow supports oAuth for authenticating other systems to pull the data, and ServiceNow doesn’t itself provide an API to communicate with other systems, so I had to write an entire landing UI page and a combination of a processor to do so.

High level steps:

A more technical look at what is happening here:

Let’s knock couple of things off before we continue:

Good things with Scoped Glide API:

_makeRequestFromRestMessage:function(code){
		var code = code+'';
		var client_id = gs.getProperty("x_4591_wunderlist.wu_client_id");
		var client_secret = gs.getProperty("x_4591_wunderlist.wu_client_secret");
		try{
			var r = new sn_ws.RESTMessageV2('wu_accessToken', 'post');
			r.setStringParameter("client_id", client_id);
			r.setStringParameter("code", code);
			r.setStringParameter("client_secret", client_secret);
			r.setHttpTimeout(10000) //In milliseconds. Wait at most 10 seconds for response from http request.
			response = r.execute();
			responseBody = response.haveError() ? response.getErrorMessage() : response.getBody();
			status = response.getStatusCode();
			this._output(responseBody, status);
			return responseBody;
		}catch(e){
			gs.info("error in the API call");
		}
	},


	_makeRequestDirect:function(code){

		var code = code+'';
		var client_id = gs.getProperty("x_4591_wunderlist.wu_client_id");
		var client_secret = gs.getProperty("x_4591_wunderlist.wu_client_secret");
		var body  = {"client_id":client_id,"client_secret":client_secret,"code":code};
		body = new global.JSON().encode(body);
		try{
			var restMessage = new sn_ws.RESTMessageV2();
			restMessage.setHttpMethod("post");
			restMessage.setRequestHeader("Content-Type", "application/json");
			restMessage.setEndpoint("https://www.wunderlist.com/oauth/access_token");
			restMessage.setRequestBody(body);
			global.JSUtil.logObject(restMessage.getRequestHeaders(), "The headers");
			global.JSUtil.logObject(restMessage.getRequestBody(), "the body");
			var response = restMessage.execute();
			responseBody = response.haveError() ? response.getErrorMessage() : response.getBody();
			status = response.getStatusCode();
			this._output("`call is successful - `"+responseBody, status);
			return responseBody;
		}catch(e){
			gs.info("error in the API call");
		}


	},
	
What’s bad:

More to come on this.

A sneak peak of my half baked API: https://thawing-fjord-6173.herokuapp.com/ [ built using a simple Node JS Server which access my API on ServiceNow ]

Code and Coffee are better in Mountains.