Me in Micorosft Graph - microsoft-graph-api

What does 'Me' represent in a statement like;
var inboxMessages1 = await graphClient
.Me
.MailFolders.Inbox
.Messages
.Request()
.OrderBy("")
.GetAsync();
I can't see anything clear enough in the docs.
Thanks
Regards

'Me' refers to the currently signed in user as seen here.

Related

Microsoft Graph API SDK for SharePoint to query a file

I try to use Graph API SDK to query a file in a SharePoint site
var site = await graphClient.Sites["myDomain"]
.SiteWithPath("relativePath").Request()
.GetAsync().ConfigureAwait(false);
var drive = await graphClient.Sites["myDomain]
.SiteWithPath("relativePath").Lists["mylib"].Drive
.Request().GetAsync().ConfigureAwait(false);
var file = await graphClient.Sites[site.Id]
.Drives[drive.Id].Root.ItemWithPath("/folder1").Children["myfile.txt"]
.Request().GetAsync().ConfigureAwait(false);
This is working and I get the file.
I try to combine the three steps into one,
var file = await graphClient.Sites["myDomain"]
.SiteWithPath("relativePath").Lists["mylib"].Drive
.Root.ItemWithPath("/folder1").Children["myfile.txt"]
.Request().GetAsync().ConfigureAwait(false);
But it gives Bad Request error. What's wrong? What is the best way to do this?
The navigation you are using is not accepted by Graph.
As per the get files docs, you need the site-id.
# Valid
GET /sites/mydomain.sharepoint.com:/relativePath/lists/mylib/drive
# Invalid addition to above url
GET /sites/mydomain.sharepoint.com:/relativePath/lists/mylib/drive/root:/myfile.txt:
If you don't have the site id, you can expand the list relationship in the get list drive call and use the site-id to request for the file. This will be two requests instead.
var drive = await graphServiceClient
.Sites["mydomain.sharepoint.com"]
.SiteWithPath(relativePath)
.Lists["mylib"]
.Drive
.Request()
.Expand("list")
.GetAsync()
.ConfigureAwait(false);
var file = await graphServiceClient
.Sites[drive.List.ParentReference.SiteId]
.Drives[drive.Id]
.Root.ItemWithPath("/Folder 1")
.Children["myfile.txt"]
.Request().GetAsync().ConfigureAwait(false);

GraphServiceClient expand function

I am working with the .NET Microsoft.Graph library in order to sync users and groups. The following query returns all 269 groups:
var msGraphGroup =
await graphServiceClient.Groups
.Request()
.Top(999)
.GetAsync();
Since the groups are nested, I need to get also the members:
var msGraphGroup_ =
await graphServiceClient.Groups
.Request()
.Top(999)
.Expand("members")
.GetAsync();
This query returns the groups with the members, but just 100 items. Why not all 269?
I wrote also the following:
var msGraphGroup =
await graphServiceClient.Groups
.Request()
.Expand("members")
.GetAsync();
List<Microsoft.Graph.Group> all = new List<Microsoft.Graph.Group>();
while (msGraphGroup.Count > 0)
{
all.AddRange(msGraphGroup.CurrentPage);
if (msGraphGroup.NextPageRequest == null)
{
break;
}
msGraphGroup = await msGraphGroup.NextPageRequest.GetAsync();
}
Is there a way to get all groups with all members in one single query?
As per the documentation on Graph API Throttling Guide, expand operator is quite expensive and that is why it is limited. Also it does not support select so you will end up fetching all user info in the expand.
As of now you have to query the members of each group separately. There is a suggestion here to use the batch API to reduce calls.
Note: Your question is similar to Retrieve all Users from all Groups? and Microsoft Graph cannot select on expand statement for /groups. Check them out for more insight.

Issue adding comments on Google Doc (Done all the work required in retrieving comments from Google Doc)

Could you please help me with an issue I am having adding comments on Google Doc? I have done all the work required in retrieving comments from Google Drive. This is how I retrieve comments from Google Doc:
String fileId ='1up_-hN_z6Fv4NuPUDZioIzFgk42o4j6n8';
String commentId = "AAAAp8ow";
googleUser = await _googleUserSignIn.signIn();
final authHeaders = await googleUser!.authHeaders;
final client = GoogleHttpClient(authHeaders);
print(' passed 1 ');
final marcoDrive = drive.DriveApi(client);
var result = await marcoDrive.comments.get(fileId, commentId, $fields: 'content');
The screenshot below shows the debugging results:
As you can see on the screenshot above, the results variable contains a comment data fetch from Google Doc. The screenshot below shows Google Doc and the orange circle is the comment:
My issue is creating a comment on Google Doc. I find the Comment request parameter, highlighted below using an orange arrow, problematic as I am struggling to create a comment in Google Doc.
var result2 = await marcoDrive.comments.create(request, fileId, $fields: 'content: data is data');
Could you please help me to understand what the Comment request parameter means and how to use it? I would also appreciate it if you could help me understand how to anchor comments.
The programming language I'm using is Dart. Here is a link that I used to help me understand how to manage Google Drive Doc comments: (https://developers.google.com/drive/api/v3/manage-comments).
You have to supply a Comment resource as your request body, as you can see at the official docs: Comments.create.
Here are the fields corresponding to the Comment resource. The only required field is content.
The JSON representation would be something like:
{
"content": "YOUR COMMENT"
}
In Dart, it would probably be something along the following lines:
Comment request = Comment();
request.content = "YOUR COMMENT";
var result = await marcoDrive.comments.create(request, fileId, $fields);
Library reference:
create method
Comment class
Comment constructor

endsWith filter not supported?

following:
https://graph.microsoft.com/v1.0/users?$filter=startsWith(displayName,'P')
works like a charm, whereas
https://graph.microsoft.com/v1.0/users?$filter=endsWith(displayName,'z')
throws a 400 error
Any idea why endsWith is not supported ?
Comment moved to answer:
This is a question that has been asked. Although UserVoice has voted a lot, it still does not support filters such as "endswith". see:here.
Unfortunately this is still not working for displayName. But for mail and userPrincipalName the following works (since recently).
Graph explorer:
https://graph.microsoft.com/v1.0//users?$count=true&$filter=endsWith(userPrincipalName,'#example.com')&$select=id,userPrincipalName
Graph.NET SDK:
var request = graphServiceClient.Users
.Request()
.Header("ConsistencyLevel", "eventual")
.Filter("endswith(userPrincipalName,'#example.com')")
.Select(x => new { x.Id, x.UserPrincipalName })
.OrderBy("userPrincipalName");
request.QueryOptions.Add(new QueryOption("$count", "true"));
var result = await request.GetAsync();
See also example 5 at https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=csharp (at this moment the C# example in the docs is incomplete)

When is Microsoft Graph API finished calculating in Excel?

I can see how to trigger the calculation of a spreadsheet using Microsoft Graph API here...
https://learn.microsoft.com/en-us/graph/api/workbookapplication-calculate?view=graph-rest-1.0&tabs=http
But, when I pull the results from the calculations they don't seem to be updated. However, I pull a second or third time, it is usually updated.
I assume this means that calculation hasn't finished b/c of the size of the file or complexity of the calcs.
However, being asynchronous, I'm not finding any way to check to see when the calculations have finished.
Any idea how to do this?
UPDATE 1:
This is the code I'm (now) using to create the session (per #UJJAVAL123-MSFT)
var persistChanges = false;
var wrkbk = await graphClient.Me.Drive.Items[strItemId].Workbook
.CreateSession(persistChanges)
.Request()
.PostAsync();
This will give me a value for 'id' like this...
cluster=US5&session=15.SN3PEPF000074ED1.A82.1.V24.7737Nwad4oPuVafaO%2fpAkiay14.5.en-US5.en-US26.10037ffe965d2cf2-Unlimited1.A1.N16.16.0.12904.3505114.5.en-US5.en-US1.V1.N0.1.A&usid=1b230e8f-3bd0-cdaa-2da6-47db74154075
I'm not exactly sure how/where to use this, or whether I use the entire thing (it looks like a query string) or if I'm supposed to parse and pull out one of the values...
cluster=US5
session=15.SN3PEPF000074ED1.A82.1.V24.xxxxxxxxxxxxxxxxx%2fpAkiay14.5.en-US5.en-US26.10037ffe965d2cf2-Unlimited1.A1.N16.16.0.12904.3505114.5.en-US5.en-US1.V1.N0.1.A
usid=1b230e8f-3bd0-cdaa-2da6-xxxxxxxxxxxx
and this is the code i'm using to trigger the calculation, but not sure how to connect the two...
var calculationType = "FullRebuild";
await graphClient.Me.Drive.Items[strItemId].Workbook.Application
.Calculate(calculationType)
.Request()
.PostAsync();
Also, I'm seeing that it is possible to create, refresh and close a session, but not entirely sure how to check on a specific async process inside that session.
Here is the code I'm using to check a specific range for a value, not sure where we pass the session-id here either...
var result = await graphClient.Me.Drive.Items[strItemId].Workbook.Worksheets[strSheetName]
.Range(strRangeName)
.Request()
.GetAsync();
UPDATE 2:
I can run an API call (presumably) in the same session successfully by passing the workbook-session-id (which is the ENTIRE string shown above) and I get the expected 204 No Content response. However, it is not clear from the c# Code Snippet in the Microsoft Graph Explorer how to pass the workbook-session-id in the request.
Here is the code it provides...
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
await graphClient.Me.Drive.Items["{item-id}"].Workbook.Application
.Calculate(null)
.Request()
.PostAsync();
So the question remains, how can I do a PostAsync or GetAsync and reference the workbook-session-id?
This code does NOT give me an error...
await graphClient.Me.Drive.Items[strItemId].Workbook.Application
.Calculate(calculationType)
.Request()
.Header("workbook-session-id",wrkbk.Id)
.PostAsync();
So now, the question is WHEN do I get the workbook-session-id? Do I get it when I initially open the workbook and then pass it to every call?
You should create a session and pass the session Id with each request. The presence of a
session Id in the requests ensures that you are using the Excel API in the most efficient
way possible.
Check here for API call to get a session
So after a decent amount of testing, i figured it out.
The answer is that you use the CreateSession method (https://learn.microsoft.com/en-us/graph/api/workbook-createsession?view=graph-rest-1.0&tabs=http) to get the workbook info, and you set the persistChanges setting, then you get back info about the workbook session.
Like this...
using Microsoft.Graph;
// strItemId = the id from the microsoft graph api of the item
// strUserId = the id of the user from the microsoft graph api (note: must have permissions set correctly)
public static async Task<WorkbookSessionInfo> GetWorkbookSessionId(string strItemId, string strUserId)
{
// true = you can see changes in the workbook
// false = don't update the workbook, just do calculations
var persistChanges = true;
try
{
var wrkbk = await graphClient.Users[strUserId].Drive.Items[strItemId].Workbook
.CreateSession(persistChanges)
.Request()
.PostAsync();
var result = wrkbk;
return result;
}
catch (Exception ex)
{
Console.WriteLine($"Error getting items: {ex.Message}");
return null;
}
}
And you are returned a WorkbookSessionInfo object, which includes the SessionId for use in subsequent calls. This way, it keeps all your calls in the same session!
https://learn.microsoft.com/en-us/graph/api/resources/workbooksessioninfo?view=graph-rest-1.0

Resources