How to copy planner tasks with labels using Graph API

I tried to create a flow that copies planner tasks from one plan to another and came across an issue where standard flow connectors did not support copying labels. I found that this could be implemented using graph API. Here are the steps:

Prerequisites

Create an app registration in Azure AD

  1. Follow the steps mentioned in the article to register an app in Azure active directory.

2. In order to create planner tasks, we need to grant Group.Read.Write.All Delegated access. See Microsoft documentation

We can use the registered app and call below methods either using a custom connector or HTTP request in flow.

Get access token :

Method 1 – Using HTTP RequestS

  • Get auth token
Method : POST
URI : https://login.microsoftonline.com/{Add Organization}/oauth2/token
Content-Type : application/x-www-form-urlencoded

Body :  

client_id= {AppID}
&resource= https://graph.microsoft.com
&client_secret= {ClientSecret}
&grant_type=client_credentials

See the post for detailed instructions on how to send token request and parse the response to get the token.

Standard planner connectors in flow do not provide us with the option to view task labels. We need to use below method for that.

  • Get planner task details

API Reference : Get plannerTask – Microsoft Graph v1.0 | Microsoft Docs

Request

GET https://graph.microsoft.com/v1.0/planner/tasks/{{TaskId}}   

Response

This will return a response with appliedCategories attribute. This attribute shows the labels for that task.

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#planner/tasks/$entity",
  "@odata.etag": "W/\"JzEtVGFzayAgQEBAQEBAQEBAQEBAQEBARCc=\"",
  "planId": "_gmhRzGIGEuwLXdIm7gc6X0AH3Mz",
  "bucketId": "mURyExWBH0yo-hkgHqPfkn0AEKmJ",
  "title": "Updated task title",
  "orderHint": "8585891215134225736",
  "assigneePriority": "",
  "percentComplete": 0,
  "createdDateTime": "2021-02-05T00:36:12.0550071Z",
  "hasDescription": false,
  "previewType": "automatic",
  "referenceCount": 0,
  "checklistItemCount": 0,
  "activeChecklistItemCount": 0,
  "id": "A-EiNgL-YUeQe9jSRpmtVX0AHgIm",
  "createdBy": {
    "user": {
      "displayName": null,
      "id": "2b95d16c-ada5-4501-8aca-855e32fde868"
    }
  },
  "appliedCategories": {
    "category1": true,
    "category2": true,
    "category4": true,
    "category5": true
  },

  "assignments": {}
}

2. Parse the response and get “appliedCategories”.

Use Parse JSON action for this. Below is the schema.

{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "@@odata.etag": {
            "type": "string"
        },
        "planId": {
            "type": "string"
        },
        "bucketId": {
            "type": "string"
        },
        "title": {
            "type": "string"
        },
        "orderHint": {
            "type": "string"
        },
        "assigneePriority": {
            "type": "string"
        },
        "percentComplete": {
            "type": "integer"
        },
        "createdDateTime": {
            "type": "string"
        },
        "hasDescription": {
            "type": "boolean"
        },
        "previewType": {
            "type": "string"
        },
        "referenceCount": {
            "type": "integer"
        },
        "checklistItemCount": {
            "type": "integer"
        },
        "activeChecklistItemCount": {
            "type": "integer"
        },
        "id": {
            "type": "string"
        },
        "createdBy": {
            "type": "object",
            "properties": {
                "user": {
                    "type": "object",
                    "properties": {
                        "displayName": {},
                        "id": {
                            "type": "string"
                        }
                    }
                }
            }
        },
        "appliedCategories": {
            "type": "object",
            "properties": {
                "category1": {
                    "type": "boolean"
                },
                "category2": {
                    "type": "boolean"
                },
                "category4": {
                    "type": "boolean"
                },
                "category5": {
                    "type": "boolean"
                }
            }
        },
        "assignments": {
            "type": "object",
            "properties": {}
        }
    }
}

Create new task with labels and title

API Reference : Create plannerTask – Microsoft Graph v1.0 | Microsoft Docs

Request:

POST https://graph.microsoft.com/v1.0/planner/tasks 

Body:

{
  "planId": <Enter the destination plan ID>,
  "title": <Title of the task>,
  "bucketId": <Add BucketID>,
  "appliedCategories": @{body('Parse_JSON')?['appliedCategories']}
}

This will create a new task in the specified plan with the title and same labels from the initial task.

METHOD 2 – Use an existing custom connector file

  1. You can download the connector file I created from here.
  2. Go to make.powerapps.com > Data > Custom Connectors
  3. Click on +New custom connector and select “Import an OpenAPI file”.

4. Click “continue”. This will load the connector file and open connector for editing.

5. Go to security tab and enter required connection details. Read this article to go through the steps of configuring a custom connector.

Note – This blog post only focuses on copying task labels. You can see the complete planner task copy flow in below post.

Once done, you can use the custom connector methods. Refer to Method 1 request parameters when configuring flow actions.

How to copy a plan in a group only using power automate

Happy Learning!



Categories: AzureAD, Power Automate

Tags: , ,

Leave a comment