Peter
Peter

Reputation: 320

MS Graph: updating isOnMyDay for a task

Being a bit dissatisfied by MS MyDay, it removes everything at midnight, I decided to write myself some code to rectify this. At first using PowerAutomate, but that soon became to complex for me to handle. Never been a big fan of it. So I went ahead using MS Graph directly. Am familiar with that approach a bit, manage around 2000 teams using Graph. Seems like extending my knowledge with managing plans and tasks.

The plan is as follows

The V1.0 version of the API doesn't allow that, but the beta does. Information on this on the page: https://learn.microsoft.com/en-us/graph/api/plannertask-update?view=graph-rest-beta&tabs=http

New for me was that I had to include an If-Match in the header containing the ETag value of the task. As data I can include isOnMyDay with a value true or false. Prototyped this using the Graph Explorer and it worked as expected. This was done in the context of me being logged in and updating one off my own tasks.

Next was coding this in an app. An app needs the permission Tasks.ReadWrite.All, which I set in the app registration and consented as admin. After resolving my issues with adapting the header to suit the needs, never needed to do that before, it looked like it was going to work… but it didn't. It comes back with a return code 403 and the message "You do not have the required permissions to access this item, or the item may not exist.". When I copy the relevant values (id, etag and value) from that failed request to the Graph Explorer it just works.

I know it's the beta API I'm using, it does have other issues (like ignoring filters when I request a list of my tasks), but what permission should I give to make this work?

FYI some relevant bit from the request: The headers:

{
   '_headers' => bless( {
     'user-agent' => 'libwww-perl/6.77',
     'if-match' => 'W/"<some identifier>"',
     'accept' => '*/*',
     'consistencylevel' => '',
     '::std_case' => {
         'consistencylevel' => 'Consistencylevel'
     },
     'content-type' => 'application/json; charset=utf-8 ',
     'authorization' => 'Bearer <some key>'
     }

The data:

_content' => '{"isOnMyDay":true}'

And finally the reply:

{
    "error": {
        "code": "",
        "message": "You do not have the required permissions to access this item, or the item may not exist.",
        "innerError": {
            "date": "2025-02-07T10:43:17",
            "request-id": "<some id>",
            "client-request-id": "<some id>"
        }
    }
}

The task id and ETag are extracted from a list of tasks requested just before I try to update the task.

In reply to Rukmini:

sub  getToken {
    my $self = shift;
    #say "Token ophalen";
    my $url = $self->_get_login_endpoint."/".$self->_get_tenant_id."/oauth2/token";
    my $ua = LWP::UserAgent->new(
        'send_te' => '0',
    );
    my $r = HTTP::Request->new(
        POST => $url,
        [
            'Accept'        =>  '*/*',
            'User-Agent'    =>  'Perl LWP',
            'Content-Type'  =>  'application/x-www-form-urlencoded'
        ],
        "grant_type=client_credentials&".
        "client_id="     .$self->_get_app_id . 
        "&client_secret=". $self->_get_app_secret . 
        "&scope="        . $self->_get_graph_endpoint . "/.default" .
        #"&scope="        .  "offline_access" . # Dit zou een refresh token op moeten leveren in de reply maar werkt niet
        "&resource="     . $self->_get_graph_endpoint,
    );

    my $result = $ua->request($r);

    if ($result->is_success){
        my $reply = decode_json($result->decoded_content);
        #print Dumper $reply;
        $self->_set_access_token($reply->{'access_token'});
        $self->_set_token_expires($reply->{'expires_on'});
    }else{
        print Dumper $result;
        die $result->status_line;
    }
}

hope this is clear to you. It's an object method which is called during initialisation.

As requested a screendump of the permission for the app: UserPlanPermissions The Group.ReadWrite.All is there as suggested by Rukmini. I believe it does nothing for the problem at hand.

Upvotes: 0

Views: 76

Answers (1)

Rukmini
Rukmini

Reputation: 16064

The v1.0 version is supported and must work to update planner Task, refer this MsDoc to update tasks using the v1.0 API version.

I granted Tasks.ReadWrite.All application type API permission:

enter image description here

For sample, I generated access token by passing below parameters:

https://login.microsoftonline.com/TenantID/oauth2/v2.0/token

client_id: ClientID
client_secret: Secret
scope: https://graph.microsoft.com/.default
grant_type: client_credentials

enter image description here

Decode the access token and make sure that Tasks.ReadWrite.All :

enter image description here

Now I used v1.0 endpoint to update the planner task and updated successfully:

PATCH https://graph.microsoft.com/v1.0/planner/tasks/TaskID

{
  "assignments": {
    "UserID": {
      "@odata.type": "#microsoft.graph.plannerAssignment",
      "orderHint": "N9917 U2333!"  
    }
  },
  "appliedCategories": {
    "category3": true,
    "category4": true  
  }
}

enter image description here

enter image description here

Modify your code, by passing the correct scope as https://graph.microsoft.com/.default

The error "You do not have the required permissions to access this item, or the item may not exist." usually occurs if the application doesn't have sufficient permissions or that the task may not be accessible in the current context.

  • Verify the task ID and ETag values to make sure they are correct.
  • Verify that the taskId you're passing to the API is correct.
  • And also try the same in Graph Explorer.

If still the issue persists, check the below references:

POST to /planner/tasks on Premium Plan Fails error 403 - Microsoft Q&A

microsoft graph api - Can Not Create Planner Plan duo lack of permission - Stack Overflow by Tarkan Sevilmis

Upvotes: 0

Related Questions