Searching Microsoft Graph api with spaces in the name - microsoft-graph-api

I'm using Microsoft Graph to do a search on the displayName for a substring of the name. The $search="displayName:MySearchTerm" format works perfect. But trying to search on the displayName with a space in the term doesn't seem to work as expected.
Using the sandbox application here
https://developer.microsoft.com/en-us/graph/graph-explorer?request=groups?$expand=members&method=GET&version=v1.0
If I use the following query format:
https://graph.microsoft.com/v1.0/groups?$search="displayName:Product vi"&$select=displayName&$orderBy=displayName
how can I get it to return only those records that have the term Product vi in the displayName field.
It shouldn't return any records in the sandbox because the term Product vi does not appear exactly in any part of the displayName but it currently returns the record "displayName": "Video Production"
I've tried the following without success:
$search="displayName:"Product vi""
$search="displayName:\"Product vi\""
$search="displayName:\\"Product vi\\""
$search="displayName:\\\"Product vi\\\""
$search="displayName:'Product vi'"
$search="displayName:\'Product vi\'"
The $filter format is no good to me as it doesn't search the middle of the displayName for the string.
How do I format the url to get the desired results if it is even possible?

The trick is to use comma instead of the space in $search clause.
https://graph.microsoft.com/v1.0/groups?$search="displayName:Product,vi"&$select=displayName&$orderBy=displayName
If $search clause contains "displayName:Product,vi" then Graph API will search on displayName for "Product vi"
It can require a special request header:
ConsistencyLevel: eventual

Try with %22
instead of
%20
good code...

Related

Sentence dictionary in Azure cognitive services

I'm having trouble to find the right way to create sentence dictionary using new portal
There is still a way to create one in legacy portal, but no clear examples. Also I'm curious if sentences would take into account grammar. I want to create some translations fron English to Polish which has quite complex grammar and depending on grammatical case and context different output is expected.
We can you the translator dictionary from the new portal too. But we need to take the keys generated from the new portal to custom language translator portal. Let’s walk through the solution.
Part 1: Language translation using Azure portal. Inbuild grammar (not complete)
Go to azure portal and search for a translator
Fill in the details according to the subscription
The above block will convert the English language into Polish according to the requirement. Below is the python code generated for translation. Fill in the details required according to the subscription.
import requests, uuid, json
# Add your key and endpoint
key = "<your-translator-key>"
endpoint = "https://api.cognitive.microsofttranslator.com"
# location, also known as region.
# required if you're using a multi-service or regional (not global) resource. It can be found in the Azure portal on the Keys and Endpoint page.
location = "<YOUR-RESOURCE-LOCATION>"
path = '/translate'
constructed_url = endpoint + path
params = {
'api-version': '3.0',
'from': 'en',
'to': ['fr', 'zu']
}
headers = {
'Ocp-Apim-Subscription-Key': key,
# location required if you're using a multi-service or regional (not global) resource.
'Ocp-Apim-Subscription-Region': location,
'Content-type': 'application/json',
'X-ClientTraceId': str(uuid.uuid4())
}
# You can pass more than one object in body.
body = [{
'text': 'I would really like to drive your car around the block a few times!'
}]
request = requests.post(constructed_url, params=params, headers=headers, json=body)
response = request.json()
print(json.dumps(response, sort_keys=True, ensure_ascii=False, indent=4, separators=(',', ': ')))
Get the keys before going to part 2
Part 2: To add sentence dictionary. Use the custom translator services studio
https://language.cognitive.azure.com/home -> Check into this link
This will create a project where we can choose the language to convert and start the translation with sentence dictionary. By default, sentence dictionary is application in new language translation.

Filtering on "null" or "no values"

I am trying to make a filter in Graph API, querying for employees without phone, but with no luck.
This is a part of the query I am working on.
https://graph.microsoft.com/beta/users?$filter=userType eq 'Member'&$select = businessPhones
This results in something like this:
{ "businessPhones": ["+473456789"]},
{ "businessPhones": ["+479876543"]},
{ "businessPhones": ["+471234567"]}
What I am trying to do is ask for users without a businessphone
{ "businessPhones": []}
Something like this
https://graph.microsoft.com/beta/users?$filter=userType eq 'Member' and businessPhones eq ''
However, I have no clue on how to do this. Anyone?
EDIT, thanks Tiny Wang for pointing out "no filtering support":
businessPhones does not support filtering. However, assignedLicenses does. If I want to query for users without any assignedLicenses
{ "assignedLicenses" : [] }
How can I accomplish that?
Pls note, according to the api properity doc, businessPhones isn't a properity supporting $filter, see https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-beta#properties
==========================UPDATE============================
Per my testing, I think it's also an unachievable task. It seems there're some 'defect' exists in ms graph OData filter. In this case, we need to use not assignedLicenses/any() according to OData protocol.
But according to my testing result, the query doesn't support using assignedLicenses/any()->Error: Complex query on property assignedLicenses is not supported , not assignedLicenses/any()->Error: Unsupported Query", but only support like assignedLicenses/any(x:x/skuId eq 3b555118-xxxx-e2096870).
What's more, when executing below query, it returns error Complex query on property assignedLicenses is not supported.
https://graph.microsoft.com/beta/users?$filter=userType eq 'Member' and assignedLicenses/any(x:x/skuId eq 3b555118-xxxx-2096870)&$select=assignedLicenses
But when executing this, it worked, so weird.
https://graph.microsoft.com/beta/users?$filter=assignedLicenses/any(x:x/skuId eq 3b555118-xxxxxx-df1e2096870)&$select=assignedLicenses
I also tried to use $count property to do the filter, but also failed:
I had the same task. After some research, I figured out how to filter out null string properties such as jobTitle, department, etc. Check this link.
Based on the answer, I tried the following query, and It works for me.
https://graph.microsoft.com/v1.0/users?$filter=NOT (businessPhones/any(p:p ge ' '))&$count=true
Be sure that you specified whitespace between quotes ' '.

[MS Graph]: Handling special characters in string search in a MS graph query

I am searching for an object with a display name. MS graph throws an exception if it contains & or # withing the search string. Is there a way around this??
https://graph.microsoft.com/XXXXXXXXXXXXXXXXXXXXXXXXXXXX?$filter=displayName eq 'application # manager'
You need to URL encoding the '#' in the request.
For example below request will help you in querying 'application # manager',
https://graph.microsoft.com/v1.0/users?$filter=displayName eq 'application%20%23%20manager'
For more details look in to Output in my environment below:-

The Microsoft Graph API returned a different threadID for the same mail

In our application we make calls to the Microsoft Graph API to fetch the email header data.
During the initial call to the api we received the following conversationId details for an email
{"conversationId":"AAQkADVhMzU1YWY5LWVkNGQtNGZjOC1hMjJmLTk0MzIxMGQzMzRhMQAQAA8kZ_w6rdxIsHkFk+h7byQ="}
And a few seconds later when we made a similar request for the same email, we received a different conversationId
{"conversationId":"AAQkADVhMzU1YWY5LWVkNGQtNGZjOC1hMjJmLTk0MzIxMGQzMzRhMQAQAA8kZ_w6rdxIsHkFk_h7byQ="}
Now the expectation here is that the value of the conversationId should always remain the same.
In the above scenario the only difference in the 2 conversationId returned is the '+' being replaced with the '_'
AAQkADVhMzU1YWY5LWVkNGQtNGZjOC1hMjJmLTk0MzIxMGQzMzRhMQAQAA8kZ_w6rdxIsHkFk+h7byQ=
AAQkADVhMzU1YWY5LWVkNGQtNGZjOC1hMjJmLTk0MzIxMGQzMzRhMQAQAA8kZ_w6rdxIsHkFk_h7byQ=
Detailed Steps:-
The owa mail dom is parsed to fetch the conversationId
AAQkADVhMzU1YWY5LWVkNGQtNGZjOC1hMjJmLTk0MzIxMGQzMzRhMQAQAA8kZ_w6rdxIsHkFk+h7byQ=
Using this conversationId we make a call to the MS Graph API and get the details including the messageId which we store in our DB as a primary key
A few minutes later, we make another MS Graph API call, this time using the messageId, and in response we get a different conversationId
AAQkADVhMzU1YWY5LWVkNGQtNGZjOC1hMjJmLTk0MzIxMGQzMzRhMQAQAA8kZ_w6rdxIsHkFk_h7byQ=
Question:-
Is it possible by any chance that + and _ are interchangable
You shouldn't assume Exchange identifiers are interchangeable across platforms. Over the years, Exchange has used a crazy number of different formats for identifiers. This is likely the crux of the issue here.
There are some mechanisms for converting between them but I generally advise against it unless you've got no other option.
I'm not sure why/how you're parsing the OWS DOM but I'm frankly more surprised the identifiers are that close than I am that it doesn't work as expected. If you want to pull the message from Graph from within OWA, I would use an Outlook Web Add-in for this. The add-in framework includes a convertToRestId method that returns an identifier you can use with Microsoft Graph:
function getItemRestId() {
if (Office.context.mailbox.diagnostics.hostName === 'OutlookIOS') {
// itemId is already REST-formatted
return Office.context.mailbox.item.itemId;
} else {
// Convert to an item ID for API v2.0
return Office.context.mailbox.convertToRestId(
Office.context.mailbox.item.itemId,
Office.MailboxEnums.RestVersion.v2_0
);
}
}
As for the + vs _, this comes down to the encoding format. There are multiple flavors of Base64. Standard In standard Base64, the 62nd character is + and the 63rd is /. This presents a problem when you want to use Base64 in a URL as + and / are reserved characters. To get around this, you need a URL safe variant of Base64. There are several such variants out there. The most common is base64url (defined in RFC 4648) which swaps out the - for the 62nd and _ for the 63rd.

How to search the group by the DisplayName using Microsoft Graph?

According to the document, I can list the Office 365 Groups by using the following Graph API:
GET https://graph.microsoft.com/v1.0/groups
I have a C# Web application, and there is a input for searching by the Group DisplayName. Any idea how to query groups based on the DisplayName?
I have tried the following URL: https://graph.microsoft.com/v1.0/groups?$search="displayName:Test" in the MS Graph Explorer which didn't work.
I get the following error.
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "This query is not supported.",
"innerError": {
"request-id": "35d90412-03f3-44e7-a7a4-d33cee155101",
"date": "2018-10-25T05:32:53"
}
}
Any suggestion is welcomed.
Thanks in advance.
According to your description, I assume you want to search the Group by the DisplayName using the search parameters.
Based on this document, we can currently search only message and person collections. So we couldn't use the search parameter.
We can use the filter query parameter to search the Group by DisplayName. For example, we can search the groups whose displayName is start with 'Test',the request url like this:
https://graph.microsoft.com/v1.0/groups?$filter=startswith(displayName,'Test')
Here is C# code that I wrote to get a group using the DisplayName. This code requires a reference to the OfficeDevPnP.Core.
private static async Task<Group> GetGroupByName(string accessToken, string groupName)
{
var graphClient = GraphUtility.CreateGraphClient(accessToken);
var targetGroupCollection = await graphClient.Groups.Request()
.Filter($"startsWith(displayName,'{groupName}')")
.GetAsync();
var targetGroup = targetGroupCollection.ToList().Where(g => g.DisplayName == groupName).FirstOrDefault();
if (targetGroup != null)
return targetGroup;
return null;
}
UPDATE
I see that the answer has already been accepted, but I came across the same issue and found that this answer is out of date. For the next person, this is the update:
The 'search' functionality does work. Whether it was fixed along the way or always has, I am not sure.
'groups' support search,
both the v1 and beta api support search,
search only works on 'displayName' and 'description' fields,
searching on 'directory objects' require a special header: 'ConsistencyLevel: eventual'
Point number 4 is what tripped me up!
Your request would look like this:
https://graph.microsoft.com/v1.0/groups?$search="displayName:Test"
With the request header:
ConsistencyLevel: eventual
There is another catch: You can only specify the first 21 characters and the search always uses 'startsWith'. You're out of luck if you specify more than that: The search always fails.

Resources