get In-Reply-To value from InternetMessageHeader in outlook graph api - microsoft-graph-api

I'm trying to use the MS graph API to get the In-Reply-To message header without having to return the entire header (internetMessageHeaders). I already get several properties (such as bccRecipients, from, id) which are documented here
I've seen several SO questions asking this and they point to using SingleValueExtendedProperties/internetMessageHeaders with a $filter clause. I've tried this and it appears to only work with properties which are documented
This is what I've tried all give a 404 error (i've checked the the In-Reply-To header is present on the actual message)
https://graph.microsoft.com/v1.0/me/messages/MSG_ID?
$select=Subject,internetMessageId,from,id,bccRecipients,
SingleValueExtendedProperties&$expand=SingleValueExtendedProperties($filter=In-Reply-To eq 'String 0x007D')
https://graph.microsoft.com/v1.0/me/messages/MSG_ID?
$select=Subject,internetMessageId,from,id,bccRecipients,
internetMessageHeaders&$expand=SingleValueExtendedProperties($filter=In-Reply-To eq 'String 0x007D')
https://graph.microsoft.com/v1.0/me/messages/MSG_ID?
$select=Subject,internetMessageId,from,id,bccRecipients,
internetMessageHeaders&$expand=internetMessageHeaders($filter=In-Reply-To eq 'String 0x007D')

You need to request PR_IN_REPLY_TO_ID MAPI property (0x1042001F)
$expand=singleValueExtendedProperties($filter=id eq 'String 0x1042')

Related

How to retrieve extended properties for calendar event (by name)?

I have an Exchange calendar populated though Exchanges Web Services (EWS) UpdateItem SOAP calls containing:
(Example here for an integer TTID and a TTSyncID string field)
<mes:UpdateItem ConflictResolution="AlwaysOverwrite" SendMeetingInvitationsOrCancellations="SendToNone">
<mes:ItemChanges>
<typ:ItemChange>
<typ:ItemId Id="%s" ChangeKey="%s" />
<typ:Updates>
<typ:SetItemField>
<typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TTID" PropertyType="Integer"/>
<typ:CalendarItem>
<typ:ExtendedProperty>
<typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TTID" PropertyType="Integer"/>
<typ:Value>10</typ:Value>
</typ:ExtendedProperty>
</typ:CalendarItem>
</typ:SetItemField>
<typ:SetItemField>
<typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TTSyncID" PropertyType="String"/>
<typ:CalendarItem>
<typ:ExtendedProperty>
<typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="%s" PropertyType="String"/>
<typ:Value>SomeStringData</typ:Value>
</typ:ExtendedProperty>
</typ:CalendarItem>
</typ:SetItemField>
</typ:Updates>
</typ:ItemChange>
</mes:ItemChanges>
</mes:UpdateItem>
In EWS they came back in the GetItem SOAP requests as
<ExtendedProperty>
<ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TTID" PropertyType="Integer"/>
<Value>10</Value>
</ExtendedProperty>
<ExtendedProperty>
<ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TTSyncID" PropertyType="String"/>
<Value>SomeStringData</Value>
</ExtendedProperty>
I'm now trying to retrieve these with the other event properties through Postman calls to the MS Graph API.
From what I understand I have to use Outlook extended properties and not Open extensions to keep this backward compatible (correct me if I'm wrong).
But I can't get this to work, because the singleValueExtendedProperties expansion seems to insist on MAPIPropertyTpes and GUIDs. If I call
https://graph.microsoft.com/v1.0/users/{{UserID}}/calendar/events/{{TTSyncedEventID}}?$expand=singleValueExtendedProperties($filter=id eq '{{extensionID}}')
with {{extensionID}} = TTSyncID or TTID, I get
{
"error": {
"code": "ErrorInvalidProperty",
"message": "PropertyId values may only be in one of the following formats: 'MapiPropertyType namespaceGuid Name propertyName', 'MapiPropertyType namespaceGuid Id propertyId' or 'MapiPropertyType propertyTag'."
}
}
Can I somehow retrieve these namespaceGuid and use those (as suggested here?
Is there an easier way referencing the properties with the human-readable TTSyncID or TTID?
Based on this, namespace GUID for public strings property sets is {00020329-0000-0000-C000-000000000046}.
If you use the following form of URL
https://graph.microsoft.com/v1.0/users/{{UserID}}/calendar/events/{{TTSyncedEventID}}?$expand=singleValueExtendedProperties($filter=id eq 'MapiPropertyType namespaceGuid Name propertyName')
You should be able to get the value of TTID property
https://graph.microsoft.com/v1.0/users/{{UserID}}/calendar/events/{{TTSyncedEventID}}?$expand=singleValueExtendedProperties($filter=id eq 'Integer {00020329-0000-0000-C000-000000000046} Name TTID')
and get the value of TTSyncID property
https://graph.microsoft.com/v1.0/users/{{UserID}}/calendar/events/{{TTSyncedEventID}}?$expand=singleValueExtendedProperties($filter=id eq 'String {00020329-0000-0000-C000-000000000046} Name TTSyncID')
You can look at existing messages with these properties set with MFCMAPI or OutlookSpy (I am its author, click IMessage button to see Extended MAPI properties). In OutlookSpy you can also construct a Graph query and specify any MAPI property (fixed or named) - click Message button in the Graph group on the OutlookSpy ribbon, click "Query Parameters", check "$expand" checkbox, click on the button next to the edit box.
In your particular case, the query would most likely be
singleValueExtendedProperties($filter=id eq 'String {00020329-0000-0000-C000-000000000046} Name TTSyncID')

How to get conversationTopic in Graph API?

Earlier we were using Exchange Service to read outlook mails. And we were able to get conversation topic. But now in Graph API we are only getting conversationId and conversationIndex.
Is ther any way to get conversavtionTopic in graph api.
Example:
subject: [EXTERNAL] Test-1
conversationTopic: Test-1
subject: [EXTERNAL] RE: Test-1
conversationTopic: Test-1
ConversationTopic
Contains a normalized form of the subject value that was set on the original message. This is the same as the Thread-Topic message header. This value is read-only.
I tried to use conversationId to search if I can find conversation topic but could't find anything.
https://graph.microsoft.com/v1.0/me/messages?$filter= conversationId eq 'yourConversationId'
The Graph doesn't provide that as a strongly typed property but you can query the PR_CONVERSATION_TOPIC property using the ExtendedProperty definition eg
https://graph.microsoft.com/v1.0/me/messages?$expand=singleValueExtendedProperties($filter=id eq 'string 0x0070')

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 ' '.

Search for an event according to a specific value of a singleValueExtendedProperty

Situation:
We have an old application that is creating events in outlook (via MAPI). To identify the events the custom property 'CTOID' is set with a specific value by which the events can be found again.
For a newer application we would like to use the Graph API but the application should still be able to read/find the events created by the old application. So I created a test event with a specific CTOID and I can already use the graph client to get the mentioned event with the according property and its value (queryOptions is just some start-/enddate restrictions).
// Initialize the GraphServiceClient.
GraphServiceClient client = await m_MicrosoftGraphClient.GetGraphServiceClient();
// Load user events.
var request = client.Users[userId].CalendarView.Request(queryOptions).Expand("singleValueExtendedProperties($filter=id%20eq%20'Double%20{00020329-0000-0000-C000-000000000046}%20Name%20CTOID')");
var result = await request.GetAsync();
var calendarEvents = result.CurrentPage;
Result:
The event gets fetched correctly including the value for the CTOID property.
Problem:
I can "Expand" events so they contain the value for the CTOID property. But how do I find an event with a specific CTOID value? And specifically, how do I do this with the Graph client in C#?
According to the documentation and this Stackoverflow post, the following REST call should work:
GET /users/{id|userPrincipalName}/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq '{id_value}' and ep/value eq '{property_value}')
So I tried this in the online Graph Explorer:
https://graph.microsoft.com/v1.0/users/[MY_USER_ID]/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq 'Double {00020329-0000-0000-C000-000000000046} Name CTOID' and ep/value eq '229236')
But all I get as response is:
{
"error": {
"code": "ErrorInvalidUrlQueryFilter",
"message": "The filter expression for $filter does not match to a single extended property and a value restriction.",
"innerError": {
"date": "2020-08-03T12:44:05",
"request-id": "33e82c77-92ea-4865-a8d0-00cfc2f99154"
}
}
}
What am I doing wrong? I'm out of ideas and any help would be greatly appreciated.
(Also if you have any idea how to do this with the Graph client in C# and not just the bare REST call).
Additional Information:
Don't know if it's important, but the following permissions are set for our application:
In your filter you need to cast the value to a Double eg
https://graph.microsoft.com/v1.0/users/[MY_USER_ID]/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq 'Double {00020329-0000-0000-C000-000000000046} Name CTOID' and cast(ep/value, Edm.Double) eq 229236)
For anything other then a String in a filter you need to do this

Using OR in filters for Office 365 Service Communications API or filtering by multiple IDs

How can I filter by multiple IDs using the Office 365 Service Communications API?
I'm getting the current status using https://manage.office.com/api/v1.0/{tenent}/ServiceComms/CurrentStatus which gives me incident IDs. I'm trying to use those IDs to get the messages affiliated but the message endpoint /ServiceComms/Messages is not working well with the filters.
The documentation shows:
I've tried:
/ServiceComms/Messages?ID=CR555555,/ServiceComms/Messages?ID='CR555555', /ServiceComms/Messages?Id=CR555555,/ServiceComms/Messages?Id='CR555555' - Returns everything (doesn't filter)
/ServiceComms/Messages?$filter=ID eq 'CR555555' - Returns Error
/ServiceComms/Messages?$filter=Id eq 'CR555555' - Returns 1 result
/ServiceComms/Messages?$filter=Id eq 'CR555555' or Id eq 'CR555556' - Returns error
I was able to get an AND result using
$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and EndTime ge 2019-07-25T00:00:00Z but OR always errors with the message "Filter {filter} is invalid. Expected '<Item> <operator> <Value>' pattern."
You need to use Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' as your MessageType.
A request to /Messages should return you a odata context at the top of the response. For example:
{
"#odata.context": "https://office365servicecomms-prod.cloudapp.net/api/v1.0/{{TenantID}}/$metadata#Messages",
...
}
If you query that, you receive the metadata along with the possible filters. I cannot give you an example as of today (2020-02-16) a query returns a 500 Internal Server Error. Microsoft is working on a fix. Maybe it works again by the time you read my reply.
Complete example:
https://manage.office.com/api/v1.0/{{TenantID}}/ServiceComms/Messages?$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and LastUpdatedTime ge 2020-02-13T00:00:00.000Z
And yes, the ID filter must be written 'Id'. Microsofts documentation has a lot of wrong information in it.

Resources