How to build a VSTS assistant - The Life and Times of a Kanban bot - Part 2

In the previous post (Part 1) we learned how we can build a bot that can read out the assigned tasks for a specific user. Today we're continuing our series by learning how to use the VSTS API and Dialogflow to create work items.

Taking a look on the VSTS REST API documentation https://www.visualstudio.com/en-us/docs/integrate/api/wit/work-items#with-a-work-item-link we'll see that we have to build a request that looks like the one below:

 PATCH https://{instance}/DefaultCollection/{project}/_apis/wit/workitems/${workItemTypeName}?api-version={version}
 Content-Type: application/json-patch+json

Here's a sample:

For demo purposes, I decided to add some additional fields that will also add the task to Iteration 1 of my project and assigns it to my user.

The JSON array will look like the one below:

 
[
{
"op": "add",
"path": "/fields/System.Title",
"value": "JavaScript implementation for Microsoft Account"
},
{
"op": "add",
"path": "/fields/System.AreaPath",
"value": "MyFirstProject"
},
{
"op": "add",
"path": "/fields/System.IterationPath",
"value": "MyFirstProject\\Iteration 1"
},
{
"op": "add",
"path": "/fields/System.AssignedTo",
"value": "John Doe <john@jutestorg.onmicrosoft.com>"
}
]

I went ahead and created a new function in my Azure Function App, called CreateWorkItem. You can find the full code on GitHub - https://github.com/julianatanasoae/VSTSFunctionApp/blob/master/MyVSTSFunction/CreateWorkItem.cs

There was some additional work needed in order for HttpClient to be able to do PATCH requests, so I went ahead and created an HttpClientExtension that used this method. It's used like this:

 
var queryHttpResponseMessage = client.PatchAsync(url, content).Result;
if (queryHttpResponseMessage.IsSuccessStatusCode)
{
var response = "Work item created";
speechJson = "{ \"speech\": \"" + response + "\" }";
}

Dialogflow will pass a JSON of the following form to our function:

 
{
  "result": {
    "parameters": {
       "workItemTitle": "something"
    }
  }
}

So we have to make sure that in the Run function of the app, we're reading the workItemTitle correctly:

 
dynamic data = await req.Content.ReadAsAsync<object>();
var workItemTitle = data?.result.parameters.workItemTitle.ToString();

That's it. The function can be published now and read from Dialogflow.

In the Dialogflow console, we first have to create an Entity called "workItemTitle", to be able to give it as a parameter on an intent.

After this, when creating the "Create Work Item" intent, we have to give it training phrases, as shown below:

Notice that the entities are highlighted with yellow. In order for your bot to be trained correctly, you have to manually select the words at the end with the mouse and pick the corresponding entity (in our case, workItemTitle).

In the Action and parameters section, we will need to create an action and give the workItemTitle as a parameter.

That's it. Let's take a look and see if it works!

This is how my Kanban board looks like right now:

In the Dialogflow test console, I will type "create a work item with the title MSDN rocks":

As you can see, it identified my "Create Work Item" intent, and it also identified that I passed a parameter corresponding to the workItemTitle entity, with the value "MSDN rocks".

Fingers crossed while refreshing the VSTS work item dashboard...

It works!

This is an example of how you can use the VSTS API to create work items. Surely, there's a lot of things that can be done better: logging in to the Azure AD tenant so I can get the proper user name, not hardcoding it in a JSON object, as well as implementing prompts for things such as Iteration Path, parent user story (as it currently shows under 'Unparented'), and more. It's a nice start, though.

Let me know in the comments below if you like this or if you have ideas on contributing to the bot functionality.

Happy Kanban-ing!