最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

azure - MS Graph: updating isOnMyDay for a task - Stack Overflow

programmeradmin1浏览0评论

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

  • I request a list of all my tasks
  • decide somehow they need to be on my ToDay
  • alter the isOnMyDay property.

The V1.0 version of the API doesn't allow that, but the beta does. Information on this on the page: ;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: The Group.ReadWrite.All is there as suggested by Rukmini. I believe it does nothing for the problem at hand.

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

  • I request a list of all my tasks
  • decide somehow they need to be on my ToDay
  • alter the isOnMyDay property.

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: The Group.ReadWrite.All is there as suggested by Rukmini. I believe it does nothing for the problem at hand.

Share Improve this question edited Feb 7 at 18:32 Peter asked Feb 7 at 10:56 PeterPeter 3202 silver badges13 bronze badges 8
  • How are you generating access token? – Rukmini Commented Feb 7 at 11:25
  • Cannot post that in a comment... I'll edit the post – Peter Commented Feb 7 at 12:11
  • That doesn't do the trick :( – Peter Commented Feb 7 at 14:20
  • Grant Tasks.ReadWrite.All application type api permission to the application and pass scope as https://graph.microsoft.com/.default as scope as you are making use of client credentials flow – Rukmini Commented Feb 7 at 14:24
  • That is exactly what I did in the first place :D Added Group.ReadWrite.All and changes the scope by you suggestion. But it did not change anything. – Peter Commented Feb 7 at 16:42
 |  Show 3 more comments

1 Answer 1

Reset to default 0

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:

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

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

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  
  }
}

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

发布评论

评论列表(0)

  1. 暂无评论