From the Group API and /Conversations endpoint you can get a list of conversations and when looking in the Groups App you can see the user with image.
But data returned from API doesn't have any good data to use for a user lookup.
I would expect an email address at least, not just the name which is far from unique. Is there a efficient way to get the user without traversing all the threads and posts?
Data from API:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#groups('{id}')/threads",
"value": [{
"id": "{id}",
"topic": "Test main thread",
"hasAttachments": false,
"lastDeliveredDateTime": "2017-10-20T11:35:04Z",
"uniqueSenders": [
"Jonas Stensved"
],
"preview": "{message preview content}",
"isLocked": false
},
{
"id": "{id}",
"topic": "The new Test group is ready",
"hasAttachments": false,
"lastDeliveredDateTime": "2017-10-13T10:33:03Z",
"uniqueSenders": [
"Test"
],
"preview": "{message preview content}",
"isLocked": false
}
]
}
How a group in the Groups app looks:
[]
It might help to break down the object hierarchy here:
Group - parent to a collection of Conversation resources
Conversation - parent to a collection of Thread resources
Thread - parent to to a collection of Post resources
Post - the actual content sent to the Group by a User
In order to see which User resources map into a given Thread, you need to drill down another level to find the Post resources contained within the Thread.
You can do this using the $expand=posts parameter to expand the Posts collection. You can also a ($select=from) the $expand so you only return the properties you need to map back to the User resource.
So this query:
/v1.0/groups/{group-id}/threads?$expand=posts($select=from)
will provide you a Thread result like this:
{
"id": "{thread-id}",
"topic": "New Training Plans",
"hasAttachments": false,
"lastDeliveredDateTime": "2017-07-31T18:59:05Z",
"uniqueSenders": [
"HR Taskforce"
],
"preview": "{thread-preview}",
"isLocked": false,
"posts#odata.context": "https://graph.microsoft.com/v1.0/$metadata#groups('{group-id}')/threads('{thread-id}')/posts(from)",
"posts": [{
"#odata.etag": "W/\"CwAAABYAAADE9kXbLjqkSJUGeLzs6eumAAAAAA0/\"",
"id": "{post-id}",
"changeKey": "CwAAABYAAADE9kXbLjqkSJUGeLzs6eumAAAAAA0/",
"from": {
"emailAddress": {
"name": "HR Taskforce",
"address": "HRTaskforce#M365x214355.onmicrosoft.com"
}
}
}]
}
You can try this yourself using this Graph Explorer example.
You can get group members list and iterate over them. Depending on the size o the group this might require paging. You can find more information in the docs: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/group
I hope this helps.
Related
So I've been trying to get email addresses of people that have access to certain files in a Sharepoint document library of a site through the use of the Microsoft Graph API. Below is an example of how my permission object looks like, which is retrieved from https://graph.microsoft.com/v1.0/sites/<site id>/drives/<drive id>/items/<item id>/permissions.
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('...')/drives('...')/items('...')/permissions",
"value": [
{
"id": "...",
"roles": ["owner"],
"grantedTo": { "user": { "displayName": "testsite - Eigenaars" } },
"inheritedFrom": {}
},
{
"id": "...",
"roles": ["read"],
"grantedTo": { "user": {"displayName": "testsite - Bezoekers"} },
"inheritedFrom": {}
},
{
"id": "...",
"roles": ["write"],
"grantedTo": { "user": { "displayName": "testsite - Leden" } },
"inheritedFrom": {}
},
{
"id": "...",
"roles": [
"write"
],
"grantedToV2": {
"siteGroup": {
"displayName": "Developers",
"id": "120",
"loginName": "Developers"
}
},
"grantedTo": {
"user": {
"displayName": "Developers"
}
},
"inheritedFrom": {}
},
{
"id": "...",
"roles": ["owner"],
"grantedTo": {
"user": {
"email": "testsite#mysharepoint",
"id": "uuid",
"displayName": "testsite - Eigenaars"
}
},
"inheritedFrom": {}
}
]
}
I assume the testsite in the displayName property is a group name (probably the group that belongs to the site the file resides in), but I have seen cases where I can't find this group name in the groups retrieved from the /groups endpoint in the Graph API.
You can also see the group Developers, which I haven't managed to find in the full group list retrieved from /groups.
The documentation around this is quite vague and unclear to me. Somewhere I read that this lack of data could be due to authentication scopes, but I have "god mode" administrator rights in this Sharepoint environment, so that would seem strange to me.
My main goal is to be able to get all users that have access to a specific file.
Thanks in advance!
1. I assume the testsite in the displayName property is a group name, but I have seen cases where I can't find this group name in the groups retrieved from the /groups endpoint in the Graph API.
This is because as per Drive Item Permission >> Identity Set >> Identity resource type Quoting
The identity's display name. Note that this may not always be available or up to date. For example, if a user changes their display name, the API may show the new value in a future response, but the items associated with the user won't show up as having changed when using
This can explain why sometimes you don't see the group name in your groups.
I suggest you use the id.
2. My main goal is to be able to get all users that have access to a specific file.
Do you have any users that appear on the Has Access section of the drive item on sharepoint? For users you should be able to get permissions and use the ids to Get directoryObject using the id values from grantedToIdentitiesV2 or grantedToV2 which will return odate type.
GET https://graph.microsoft.com/v1.0/directoryObjects/{id}?$select=id
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#directoryObjects(id)/$entity",
"#odata.type": "#microsoft.graph.group or user or application",
"id": "id"
}
For groups, the users would be the members of the group.
I would like to get more properties from a conversation's group via Graph Api.
If I call :
https://graph.microsoft.com/beta/groups/{groupId}/conversations/{conversationId}
I get something like that :
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#groups('{GroupId}')/conversations/$entity",
"id": "{ConversationId}",
"topic": "{Subject}",
"hasAttachments": true,
"lastDeliveredDateTime": "2021-03-12T12:41:27Z",
"uniqueSenders": [
"{Sender}"
],
"preview": "{Message}"}
But in outlook i have some other properties :
Categories, Mentions, Likes
How to get them ?
I want to be able to have a list of all users who can view a certain mail item. As an admin on the frontend on exchange online, I can view all my users mail, but when i call to the API I only return my mail. I want to be able to make calls to see exactly who has permission to view each mail item, and cannot find a way through the api.
I can get a list of all users, and a list of all mail for each user, a list of all mailboxes, a list of all groups, but not permissions on each mail item
GET /users/{id | userPrincipalName}/messages
returns all the mail, but mail items come with the following structure:
{
"bccRecipients": [{"#odata.type": "microsoft.graph.recipient"}],
"body": {"#odata.type": "microsoft.graph.itemBody"},
"bodyPreview": "string",
"categories": ["string"],
"ccRecipients": [{"#odata.type": "microsoft.graph.recipient"}],
"changeKey": "string",
"conversationId": "string",
"createdDateTime": "String (timestamp)",
"flag": {"#odata.type": "microsoft.graph.followupFlag"},
"from": {"#odata.type": "microsoft.graph.recipient"},
"hasAttachments": true,
"id": "string (identifier)",
"importance": "String",
"inferenceClassification": "String",
"internetMessageHeaders": [{"#odata.type": "microsoft.graph.internetMessageHeader"}],
"internetMessageId": "String",
"isDeliveryReceiptRequested": true,
"isDraft": true,
"isRead": true,
"isReadReceiptRequested": true,
"lastModifiedDateTime": "String (timestamp)",
"parentFolderId": "string",
"receivedDateTime": "String (timestamp)",
"replyTo": [{"#odata.type": "microsoft.graph.recipient"}],
"sender": {"#odata.type": "microsoft.graph.recipient"},
"sentDateTime": "String (timestamp)",
"subject": "string",
"toRecipients": [{"#odata.type": "microsoft.graph.recipient"}],
"uniqueBody": {"#odata.type": "microsoft.graph.itemBody"},
"webLink": "string",
"attachments": [{"#odata.type": "microsoft.graph.attachment"}],
"extensions": [{"#odata.type": "microsoft.graph.extension"}],
"multiValueExtendedProperties": [{"#odata.type": "microsoft.graph.multiValueLegacyExtendedProperty"}],
"singleValueExtendedProperties": [{"#odata.type": "microsoft.graph.singleValueLegacyExtendedProperty"}]
}
this doesnt contain anything about the full permissions on the item. Does anyone know of a way to get this?
You can't get item level permission as item doesn't store ACL associated with it. You can, however, get Folder level permission by querying PR_NT_SECURITY_DESCRIPTOR (0x0E270102) on the folder.
I actually wrote script for this based on my old REST API client engine: Start-MailboxFolderPermissionReport
I can, if script isn't enough, write C# way of doing it through Graph Managed API
There doesn't appear to be a way to expose mailbox or folder permissions through the Graph API. These are available through the Exchange Online PowerShell module e.g. Get-MailboxFolderPermission.
When trying to filter for a custom created schema extension:
https://graph.microsoft.com/v1.0/me/events?$filter=(<schemaId>/<key> eq '<value>')
the error message we get is:
"message": "Could not find a property named 'e2_<ourTenantID>_<schemaId>' on type 'Microsoft.OutlookServices.Event'"
The problem is that before performing search, the API prepends tenantID to schema ID, thus failing to recognize the property. It seems that graph API performs search using their own internal schema ID.
Interesting thing is, that when searching for a non-existing schema, the tenantID is not added.
The problem persists when testing to filter messages, events and contacts.
Our schema extension creation JSON:
{
"description": "Extension to help avoid duplicates",
"targetTypes": [
"Contact",
"Message",
"Event"
],
"properties": [
{
"name": "UniqueId",
"type": "String"
}
],
"status": "InDevelopment",
"owner": "<appID>",
"id": "<name>",
"#odata.type": "#microsoft.graph.ComplexExtensionValue"
}
I am using Activiti 5.12. As provided, in its user guide, REST API to get he details of a process instance is :
GET /process-instance/{processInstanceId}
Its response is something like this :
{
"id": "2",
"processDefinitionId": "financialReport:1",
"businessKey": "55",
"startTime": "2010-10-13T14:54:26.750+02:00",
"startActivityId": "startFinancialAnalysis",
"startUserId": "kermit",
"completed": false,
"tasks": [
{
"taskId": "3",
"taskName": "Analyze report",
"owner": null,
"assignee": "Kermit",
"startTime": "2010-10-13T14:53:26.750+02:00",
"completed": false
}
],
"activities": [
{
"activityId": "4",
"activityName": "Get report",
"activityType": "ServiceTask",
"startTime": "2010-10-13T14:53:25.950+02:00",
"completed": true,
"duration": 200
}
],
"variables": [
{
"variableName": "reportName",
"variableValue": "classified.pdf"
}
],
"historyVariables": [
{
"variableName": "reportName",
"variableValue": "classified.pdf",
"variableType": "String",
"revision": 1,
"time": "2010-10-13T14:53:26.750+02:00"
}
]
}
A JAVA API for the same is also provided, which is :
ProcessEngines.getProcessEngine(configuredProcessEngineName).getHistoryService().createHistoricProcessInstanceQuery().processInstanceId("somevalue").singleResult()
This Java API does not work, as teh return type HistoricProcessInstance does not have the method to get the task list.
My objective is to get the current state of a process instance, i.e which task it's presently at.
The REST API lists all tasks that process instance has carried out and the last task of the list is the one it's currently executing, as its property completed is false.
I want to achieve the same from java code.
Can you please help me out. Any alternative way to get to my objective is also fine with me.
You can use another query of HistoricService API:
List<HistoricTaskIntance> taskList = getHistoryService()
.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.list()
The current task status can be defined by HistoricTaskInstance.getEndTime() that will return null for open tasks.
I have tried this way out.
SELECT NAME_ FROM act_hi_taskinst where PROC_INST_ID_= 1000 and END_TIME_ IS NULL;"
act_hi_taskinst contains history tasks for each and every instance.
If the process with instance id is completed then you wont get any result, so you can check that condition before moving forward.
I have run this piece of SQL Statement to get the required task name.
The answer given by #Mike also meets the objective. Even here also you have to check whether process is incomplete.