How to fetch "#microsoft.graph.downloadUrl" from Microsoft Search API? - microsoft-graph-api

I am using Microsoft Search API to search for files in SharePoint, objective is to fetch temporary url ("#microsoft.graph.downloadUrl") amoung other fields. I have used below search request,
Url - POST request: https://graph.microsoft.com/v1.0/search/query
Body:
{
"requests": [
{
"entityTypes": [
"driveItem"
],
"query": {
"queryString": "search-value",
"query": "path:\"https://{company}.sharepoint.com/sites/{site}/shared\""
},
"fields": [
"name",
"webUrl",
"#microsoft.graph.downloadUrl"
]
}
]
}
The result returned is below, and it is missing "#microsoft.graph.downloadUrl" field.
"moreResultsAvailable": false,
"hits": [
{
"hitId": "01CDLPULQVGFRNVHYTJVFL3NPPXIGOUDUS",
"rank": 1,
"summary": "string;#<c0>search-value</c0> <c0>search-value</c0> Internal 1 0 search-value Graph explorer {DA623115<ddd/>",
"resource": {
"#odata.type": "#microsoft.graph.driveItem",
"name": "word.docx",
"webUrl": "https://company.sharepoint.com/sites/{site}/Cases/search-value/word.docx"
}
},

Search API can retrieve only properties but not instance attributes like "#microsoft.graph.downloadUrl".
Properties
Instance attributes

I think there's no need to use the REST API. To get the temporary #microsoft.graph.downloadUrl download link I used the following to get the value:
var selectedFile = files.value[0];
var downloadLink = selectedFile["#microsoft.graph.downloadUrl"];
Found at this link: https://github.com/OneDrive/onedrive-api-docs/issues/547
I hope this helps

Related

How to build query with "sourcedoc" which is present in "SharePoint file" shared URL. I want to search file in OneDrive using Microsoft Graph API

I am using below URL to search files in Onedrive. How to add the query string as "Sourcecode"?
https://graph.microsoft.com/beta/search/query
Request parameters:
{
"requests": [
{
"entityTypes": [
"driveItem"
],
"query": {
// "queryString": "Presentation.pptx"
//"queryString": "contoso filetype:pdf OR filetype:docx"
//"queryString": "contoso
path:\"https://contoso.sharepoint.com/sites/Team Site/Documents/\\""
}
}
]
}
The sourcedoc value should be the same as id of the listItem which represents an item in a SharePoint list.
Try to specify the sourcedoc value in queryString.
Example:
{
"requests": [
{
"entityTypes": [
"listItem"
],
"query": {
"queryString": "C2CB147F-1B73-4307-990E-37F7CBE090C6"
}
}
]
}
It will search across the metadata including id.

Apache Ranger REST API addUsersAndGroups returns 404 not found

We have installed Apache Ranger and the Web UI works fine, most of the REST API method works fine on both PublicAPIsv2 and RoleREST as per https://ranger.apache.org/apidocs/ui/index.html.
I can get “test_role” id by calling GET /public/v2/api/roles/name/test_role which returns the id 409.
I can get test_role content by calling GET /public/v2/api/roles/409
I can change test_role users list by editing the response I get from GET /public/v2/api/roles/409 and submitting it through PUT /public/v2/api/roles/409
The body is:
{
"id": 409,
"isEnabled": true,
"createdBy": "admin",
"updatedBy": "admin",
"createTime": 1598241102841,
"updateTime": 1601975068428,
"name": "test_role",
"options": {},
"users": [
{
"name": "test_user1”,
"isAdmin": true
},
{
"name": “test_user2”,
"isAdmin": true
},
{
"name": “test_user3”,
"isAdmin": false
}
],
"groups": [
{
"name": "test_group”,
"isAdmin": false
}
],
"roles": []
}
But calling PUT /public/v2/api/roles/409/addUsersAndGroups returns “404 not found”.
I tried with the same body as above as parameter, and also with:
{
"users": [
{
"name": “test_user4”,
"isAdmin": true
}
]
}
Would anybody know what is the correct body to send as parameter to:
/public/v2/api/roles/409/addUsersAndGroups?
Also, making a wrong call such as GET /public/v2/api/roles/409/addUsersAndGroups returns “405 method not allowed”. So I believe it shows the end point does exist. I’m not sure why calling PUT public/v2/api/roles/409/addUsersAndGroups with (probably) incorrect body returns “404 not found” and not an error message related to the wrong parameter.
It happens because Apache Ranger API documentation is wrong, remove the suffix /addUsersAndGroups of your endpoint and it will work.
Example: https://ranger_url/service/roles/roles/409
Where 409 is the role ID, as you're using on your example.
The body that is needed:
{
"name": "test_role",
"users": [
{
"name": "test_user1",
"isAdmin": true
}
]
}

Schema Extensions : "Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'."

I'm currently building an application that requires me to retrieve users from the Graph API depending of a custom property, in that case, extoe82ql2v_test/companyName but so far, the API responded with Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'."
The request to retrieve the extension :
https://graph.microsoft.com/v1.0/schemaExtensions?$filter=id eq 'extoe82ql2v_test'
The result :
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#schemaExtensions",
"value": [
{
"id": "extoe82ql2v_test",
"description": "Extend data for users",
"targetTypes": [
"User"
],
"status": "InDevelopment",
"owner": "d9a847ce-ca03-4779-88d6-c7e4f98297fe",
"properties": [
{
"name": "companyName",
"type": "String"
},
{
"name": "managerMail",
"type": "String"
},
{
"name": "arrivalDate",
"type": "DateTime"
},
{
"name": "expiryDate",
"type": "DateTime"
}
]
}
]
}
The request to retrieve the users depending of extoe82ql2v_test/companyName :
https://graph.microsoft.com/v1.0/users?$select=extoe82ql2v_test,givenName,surname,mail,mobilePhone,department,companyName,accountEnabled&$filter=extoe82ql2v_test/companyName eq 'test'
The result :
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'.",
"innerError": {
"date": "2020-07-24T20:46:51",
"request-id": "639b8131-70dd-4436-b624-88167fe105eb"
}
}
}
The same query with the Microsoft Graph .NET SDK :
var res = await _graphClient.Users.Request()
.Select($"extoe82ql2v_test,givenName,surname,mail,mobilePhone,department,companyName,accountEnabled")
.Filter($"extoe82ql2v_test/companyName eq 'test'").GetAsync()
I don't understand what the issue is as I followed what the official documentation said about filtering custom properties
Any help is greatly appreciated
Edit : Here is how $select without a $filter looks like
Request :
https://graph.microsoft.com/v1.0/users?$select=givenName,surname,mail,mobilePhone,department,companyName,accountEnabled,extoe82ql2v_test
Response :
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(givenName,surname,mail,mobilePhone,department,companyName,accountEnabled,extoe82ql2v_test)",
"value": [
{
"givenName": "Antoine",
"surname": "D",
"mail": "antoine.d#contoso.com",
"mobilePhone": null,
"department": null,
"companyName": null,
"accountEnabled": true,
"extoe82ql2v_test": {
"#odata.type": "#microsoft.graph.ComplexExtensionValue",
"expiryDate": "2020-12-31T00:00:00Z",
"arrivalDate": "2020-07-22T00:00:00Z",
"managerMail": "antoine.d#contoso.com",
"companyName": "test"
}
}
]
}
Edit 2:
I successfully filtered the users with another custom attributes, extoe82ql2v_test/managerMail, it's progress but I still need to apply a filter on extoe82ql2v_test/companyName and make it works
Edit 3:
Filtering on extoe82ql2v_test/expiryDate and extoe82ql2v_test/arrivalDate also works, both of these attributes are useless to filter but at least I know they work. As for extoe82ql2v_test/companyName, I wonder if it is because this attribute exists in both the schema extensions and the User Graph object ?
I just faced the same problem and made it work by adding "$count=true" in the query parameters.
I also noticed it seems to need ConsistencyLevel=eventual in the request header.
For example:
https://graph.microsoft.com/v1.0/users?$filter=CompanyName eq 'xxxx'&$select=id,displayName,CompanyName
Bad Request - 400 - 146ms
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Unsupported or invalid query filter clause specified for property 'companyName' of resource 'User'.",
...
}
https://graph.microsoft.com/v1.0/users?$count=true&$filter=CompanyName eq 'xxxx'&$select=id,displayName,CompanyName (with header ConsistencyLevel=eventual)
OK - 200 - 404ms
\o/
(I got the hint by looking at this question Microsoft Graph API cannot filter /users by companyName?)

In TFS (or ADO) is there an API call to link a Team to an Area Path?

We're automating our TFS Team/Board creation and found that there is an API to create a Team and an API to create an Area Path, but not one to link the two. Basically we're looking for something that acts as the ‘Create an area path with the name of the team.’ check box in the attached picture.Screenshot Here's the code for our Team post:
$azdoURI = https://prd-ourCompanyName/tfs/ourOrg/_apis/projects/ourProject/teams?api-version=5.0"
$requestBody = #{ name = "$boardName" }
$jsonRequestBody = $requestBody | ConvertTo-Json -Compress
$response = (Invoke-WebRequest -Method Post -Uri $azdoURI -Body $jsonRequestBody -Content 'application/json' -Credential $credential -UseBasicParsing)
Adding an iteration to a team is done through the /_apis/work/teamsettings/iterations API.
Request:
POST https://dev.azure.com/fabrikam/Fabrikam-Fiber/_apis/work/teamsettings/iterations?api-version=5.1
"{\"id\":\"a589a806-bf11-4d4f-a031-c19813331553\"}"
Response:
{
"id": "a589a806-bf11-4d4f-a031-c19813331553",
"name": "Sprint 2",
"path": "Fabrikam-Fiber\\Release 1\\Sprint 2",
"attributes": {
"startDate": null,
"finishDate": null
}
}
To set area paths use the /_apis/work/teamsettings/teamfieldvalues:
Request:
PATCH https://dev.azure.com/fabrikam/Fabrikam-Fiber/_apis/work/teamsettings/teamfieldvalues?api-version=5.1
{
"defaultValue": "Fabrikam-Fiber\\Auto",
"values": [
{
"value": "Fabrikam-Fiber\\Auto",
"includeChildren": true
},
{
"value": "Fabrikam-Fiber\\Fiber",
"includeChildren": false
},
{
"value": "Fabrikam-Fiber\\Optics",
"includeChildren": false
}
]
}
Response:
{
"field": {
"referenceName": "System.AreaPath",
"url": "https://dev.azure.com/fabrikam/_apis/wit/fields/System.AreaPath"
},
"defaultValue": "Fabrikam-Fiber\\Auto",
"values": [
{
"value": "Fabrikam-Fiber\\Auto",
"includeChildren": true
},
{
"value": "Fabrikam-Fiber\\Fiber",
"includeChildren": false
},
{
"value": "Fabrikam-Fiber\\Optics",
"includeChildren": false
}
]
}
See also:
TeamFieldvales
Iterations
Basically we're looking for something that acts as the ‘Create an area
path with the name of the team.’ check box in the attached picture.
If I understand you well, you're trying to create a new Team Project in which there's one default Area path. (Of course you also want their names should be the same)
For TFS2018U2, try:
POST https://{instance}/{collection}/_apis/projects?api-version=4.1
For Azure Devops Server 2019, try:
POST https://{instance}/{collection}/_apis/projects?api-version=5.0
You can find more details from my another post here. After my check, this api will automatically define the default area path with same name like Team project's:
So here's where I ended up:
5 Steps:
Create team: POST https://dev-tfs.../{organization}/_apis/projects/{project}/teams?api-version=5.1
Body: {"name":"BoardByPostmanTest_3"}
Create Area Path to match team: POST https://dev-tfs.../{organization}/{project}/_apis/wit/classificationnodes/Areas?api-version=5.1
Body: {"name":"BoardByPostmanTest_3"}
Update Team with Area path: PATCH https://dev-tfs.z../{organization}/{project}/BoardByPostmanTest_3/_apis/work/teamsettings/teamfieldvalues?api-version=5.1
Body:
{
"defaultValue": "Agile\BoardByPostmanTest_3",
"values": [
{
"value": "Agile\BoardByPostmanTest_3",
"includeChildren": true
}
]
}
Find Iteration for project: GET https://dev-tfs.../{organization}/{project}/_apis/wit/classificationnodes/Iterations?api-version=5.1
Add that Iteration to Team: PATCH https://dev-tfs.../{organization}/{project}/BoardByPostmanTest_3/_apis/work/teamsettings?api-version=5.1
Body:
{
"backlogIteration": "whatever that Iteration number is from GET in step 4"
}
Thank you to jessehouwing for step 3 that I was missing.

How to retrieve contents of an itemAttachment via the Microsoft Graph API

I'm currently developing a solution which is retrieving e-mails via the Microsoft Graph API. In november 2015 Microsoft stated it is ready for production and I've read in another forum post that if you start now on developing using a Microsoft API, you should use the Graph API, since it is the future.
Everything is going well except for one thing and that is the following.
I must retrieve e-mails. Inside these e-mails there are of course attachments. These attachments come in some variaties. fileAttachment (images, documents etc.), referenceAttachments and itemAttachments (outlook-item). The issue here is with the itemAttachments. An itemAttachment can be anything from an appointment to another message. The problem here is that I'm not able to get and retrieve the contentBytes in some way which is working for fileAttachments. A related object to itemAttachment is outlookItem. There is also a page with a description made for this outlookItem, but the examples and the details are missing.
The user rights are set to Mail.Read and Mail.ReadWrite.
Links:
General overview: http://graph.microsoft.io/docs/overview/overview
Get outlookItem (empty?):
Example call and response I get. Please note the types of the attachments.
https://graph.microsoft.com/v1.0 /users/ /messages/ /attachments
{
"#odata.context": "link",
"value": [
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAGhN_vm1RlBPt7V4N9a89UY=",
"lastModifiedDateTime": "2016-01-13T14:25:33Z",
"name": "image001.png",
"contentType": "image/png",
"size": 5077,
"isInline": true,
"contentId": "image001.png#01D14E16.A3A32480",
"contentLocation": null,
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAKAAAACCCAIAAABOyVRHAAAAAXNSR0IArs4c6QAAEndJREFUeF7tXQ1QFFe2bkbU... (truncated)"
},
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAFnSLgIC5wZOosmLtBWK8gE=",
"lastModifiedDateTime": "2016-01-13T14:25:34Z",
"name": "image002.png",
"contentType": "image/png",
"size": 3722,
"isInline": true,
"contentId": "image002.png#01D14E16.A3A32480",
"contentLocation": null,
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAPoAAABSCAYAAAB9o8m+AAAAGXRFWHRTb... (truncated)"
},
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQANOuw7m8sW1Ot3MivYQ5OYU=",
"lastModifiedDateTime": "2016-01-13T14:25:24Z",
"name": "Knipsel.PNG",
"contentType": null,
"size": 7641,
"isInline": false,
"contentId": null,
"contentLocation": null,
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAKAAAACCCAYAAADBq8MQAAA... (truncated)"
},
{
"#odata.type": "#microsoft.graph.itemAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAPEUC740tjtAlNTe8NpopUI=",
"lastModifiedDateTime": "2016-01-14T15:55:07Z",
"name": "RE: Test met plaatje",
"contentType": null,
"size": 36972,
"isInline": false
}
]
}
I've tried to change the GET-statement by pasting the attachment id with or without the messages path and the expand feature (which is only supported one level deep), but I can't seem te find the solution.
Something I've found is this question, which is kind of the same, however it is for the office365 unified API. How to retrieve ItemAttachment contents from Office 365 REST API?.
So, the question: How can I retrieve the contents of an outlookItem via the Microsoft Graph API? And how do I know what to expect? Can anybody help me getting past this obstacle.
Use $expand option:
GET https://graph.microsoft.com/v1.0/me/messages('AAMkADA1M-zAAA=')/attachments('AAMkADA1M-CJKtzmnlcqVgqI=')/?$expand=microsoft.graph.itemattachment/item
Response:
HTTP/1.1 200 OK
Content-type: application/json
{
"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('d1a2fae9-db66-4cc9-8133-2184c77af1b8')/messages('AAMkADA1M-zAAA%3D')/attachments/$entity",
"#odata.type":"#microsoft.graph.itemAttachment",
"id":"AAMkADA1MCJKtzmnlcqVgqI=",
"lastModifiedDateTime":"2017-07-21T00:20:34Z",
"name":"Reminder - please bring laptop",
"contentType":null,
"size":32005,
"isInline":false,
"item#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('d1a2fae9-db66-4cc9-8133-2184c77af1b8')/messages('AAMkADA1M-zAAA%3D')/attachments('AAMkADA1M-CJKtzmnlcqVgqI%3D')/microsoft.graph.itemAttachment/item/$entity",
"item":{
"#odata.type":"#microsoft.graph.message",
"id":"",
"createdDateTime":"2017-07-21T00:20:41Z",
"lastModifiedDateTime":"2017-07-21T00:20:34Z",
"receivedDateTime":"2017-07-21T00:19:55Z",
"sentDateTime":"2017-07-21T00:19:52Z",
"hasAttachments":false,
"internetMessageId":"<BY2PR15MB05189A084C01F466709E414F9CA40#BY2PR15MB0518.namprd15.prod.outlook.com>",
"subject":"Reminder - please bring laptop",
"importance":"normal",
"conversationId":"AAQkADA1MzMyOGI4LTlkZDctNDkzYy05M2RiLTdiN2E1NDE3MTRkOQAQAMG_NSCMBqdKrLa2EmR-lO0=",
"isDeliveryReceiptRequested":false,
"isReadReceiptRequested":false,
"isRead":false,
"isDraft":false,
"webLink":"https://outlook.office365.com/owa/?ItemID=AAMkADA1M3MTRkOQAAAA%3D%3D&exvsurl=1&viewmodel=ReadMessageItem",
"body":{
"contentType":"html",
"content":"<html><head>\r\n</head>\r\n<body>\r\n</body>\r\n</html>"
},
"sender":{
"emailAddress":{
"name":"Adele Vance",
"address":"AdeleV#contoso.onmicrosoft.com"
}
},
"from":{
"emailAddress":{
"name":"Adele Vance",
"address":"AdeleV#contoso.onmicrosoft.com"
}
},
"toRecipients":[
{
"emailAddress":{
"name":"Alex Wilbur",
"address":"AlexW#contoso.onmicrosoft.com"
}
}
],
"ccRecipients":[
{
"emailAddress":{
"name":"Adele Vance",
"address":"AdeleV#contoso.onmicrosoft.com"
}
}
]
}
}
Source: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/attachment_get#request-2
The official documentation: https://graph.microsoft.io/en-us/docs/api-reference/beta/api/attachment_get.htm . Use valid Bearer authentication access code, and check for appropriate Graph API permissions on the Azure management portal. Attachment is based64 encoded string, coming in the contentBytes field. Correct Uri for loading list of a message attachments is: https://graph.microsoft.com/beta/me/messages/[ message Id ]/attachments. Sample code to call attachments endpoint is below:
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Get,
"https://graph.microsoft.com/beta/me/messages/..id../attachments"))
{
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", "...valid access token...");
using (HttpResponseMessage response = await client.SendAsync(request))
{
if (response.StatusCode == HttpStatusCode.OK)
{
result = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(result);
}
}
}
}
Get attachment using MS Graph API for Java:
First build the graph client. Sample code
ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(yourClientId).clientSecret(yourClientSecret)
.tenantId(yourTenantId).build();
TokenCredentialAuthProvider tokenCredAuthProvider = new TokenCredentialAuthProvider(clientSecretCredential);
GraphServiceClient<Request> gClient = GraphServiceClient.builder().authenticationProvider(tokenCredAuthProvider)
.buildClient();
Either get all the attachments for a message-
FileAttachment fa = (FileAttachment) graphClient.users(id).messages(messageId).attachments().buildRequest().get();
Or get a particular attachment by passing the attachment id:
FileAttachment fa = (FileAttachment) graphClient.users(id).messages(messageId).attachments(attachmentId).buildRequest().get();
//Copy file attachment into a File from byte stream using FileUtils.
FileUtils.writeByteArrayToFile(new File(yourFileLocation), fa.contentBytes);
You can also similarly either get all users, messages or attachments or pass particular id to get a unique result for these entities.

Resources