Cannot create contact with custom data in schema extensions, group works - microsoft-graph-api

I have created a schema extension for group and contacts.
First Issue: I can create new group with custom data using the extension but not with contact. I get the following error when I try to create a new contact with custom data in schema extension.
{
"error":
{
"code": "RequestBodyRead",
"message": "The property 'extcivhhslh_sbtest1' does not exist on type 'Microsoft.OutlookServices.Contact'. Make sure to only use property names that are defined by the type or mark the type as open type.",
"innerError":
{
"request-id": "5686a76f-f016-47aa-82a3-acd9ab57e3ae",
"date": "2017-06-14T05:44:22"
}
}
}
Issue#2: As per the 5th example in https://developer.microsoft.com/en-us/graph/docs/concepts/extensibility_schema_groups I should be able to get the custom data in the extensions. In my testing I don't get back the custom data in the extension.
The extension looks like the following:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#schemaExtensions",
"value": [
{
"id": "extcivhhslh_sbtest1",
"description": "SbGraph test extensions",
"targetTypes": [
"contact",
"group"
],
"status": "Available",
"owner": "da033fe6-d48e-435d-8014-e98a4b166900",
"properties": [
{
"name": "customerType",
"type": "String"
}
]
}
]
}

1 - Schema extensions cannot be used while creating the contact. Once the contact is created, you can patch it using schema extension value.
2 - Please verify that you have specified $select=extcivhhslh_sbtest1 while querying for /groups to get the extension values (along with other $select properties that you are interested in).
Thanks,
Pavan

Related

Filter Mail by Custom InternetMessageHeaders

I am able to send mail and add custom internetMessageHeaders. But what I'm attempting to do now is return messages based on filtering to the custom headers I'm adding.
Example:
If I add a custom header to the message for "x-custom-header-productid = x123z" I want to filter and return all messages that have the custom header for x-custom-header-productid that equals x123z. Is this possible?
Thanks!
The header needs to be provisioned in the Mailbox you want to search for it on eg https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-provision-x-headers-by-using-ews-in-exchange
So in the Graph if you send a Message using that mailbox that would provision it for use in that Mailbox eg
{
"message": {
"subject": "Meet for lunch?",
"body": {
"contentType": "Text",
"content": "The new cafeteria is open."
},
"toRecipients": [
{
"emailAddress": {
"address": "youmailbox#domain.com"
}
}
],
"singleValueExtendedProperties": [
{
"id": "String {00020386-0000-0000-C000-000000000046} Name X-blah-blah",
"value": "Food"
}
]
}
}
You could then search for any messages that arrived (after you provisioned that header)eg which would mean the property would be promoted in the store.
https://graph.microsoft.com/v1.0/me/mailfolders/inbox/messages?$filter=singleValueExtendedProperties/any(ep:ep/id eq 'String {00020386-0000-0000-C000-000000000046} Name X-blah-blah' and ep/value eq 'Food')

Modify value of an existing open-extension item in a calendar-event (MS-Graph api)

I'm trying to change the value of an open extension item in an calendar event.
The current extension in the event look like this
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('2c2..d2f')/events('AAM..AAA%3D')/extensions/$entity",
"#odata.type": "#microsoft.graph.openTypeExtension",
"id": "Microsoft.OutlookServices.OpenTypeExtension.ExtID",
"extensionName": "ExtID",
"WID": "My ext. ID"
}
I try to modify it with the following code:
PATCH URL:
https://graph.microsoft.com/v1.0/me/events('AAM..AAA=')/extensions('ExtID')
JSON DATA:
{
"WID": "Changed from My ext. ID to NewValue"
}
And I get this error:
{
"error": {
"code": "RequestBodyRead",
"message": "The property 'WID' does not exist on type 'Microsoft.OutlookServices.Extension'. Make sure to only use property names that are defined by the type or mark the type as open type.",
"innerError": {
"date": "2022-10-29T10:22:24",
"request-id": "b54....755",
"client-request-id": "dc538....d1e"
}
}
}
In Graph Explorer there is a sample code for updating an open extension:
https://graph.microsoft.com/v1.0/me/extensions/{extension-id}
{
"theme": "light",
"color": "yellow",
"lang": "Swahili"
}

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?)

Making AutoRest map classes to sub-objects in the response

I'm trying to write a client to a large non Swagger-documented API and thought that writing the swagger.json
for it and using AutoRest would be a good way to accomplish that. The case is that this API wraps each operation's
response data into a larger object with control information, like this:
{
"resp_code": "SUCCESS",
"caller_ref": "2016111116233156169531",
"server_ref": "2016111116233189512798",
"data": {
"id": "idstring",
"name": "nameString",
"address": "addressString",
...
}
}
Where "data" in this case would be a "Client" definition for us. Is there a way to define the 200 OK response
schema and the definitions in the swagger.json file so that AutoRest would map this "data" to a Client class?
In fact the answer is quite trivial, all I had to do is to write the "responses" object of the swagger file like this:
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/Client"
}
}
}
}
}
Besides creating the Client definition. AutoRest generates code that retrieves the "data" object, giving access to the Client within.

How do I model a key/value for which the key is not known in Swagger

I have a simple JSON object that can contain key/values for which the exact values are not known upfront. They depend on some server side process. How do I model this in Swagger?
An example of the JSON would be:
...
,message: "invalid length. Must be in between {min} and {max}"
,attributes: {
min: 0
,max: 6
}
...
Another example would be:
...
,message: "You must fill out this field as well because {field} has a value"
,attributes: {
field: "age"
}
...
The following solution will only work with Swagger 2.0.
Define the model as described like this:
{
"type": "object",
"properties": {
"message": {
"type": "string"
},
"attributes": {
"type": "object",
"additionalProperties": {}
}
}
}
This describes attributes as a map of properties, where the value can be anything (string, number, array and even an object).

Resources