Reputation: 15462
I'm working on a onedrive integration in my app. The idea is that users that have the onedrive file explorer client installed can drag a file and the app is able to generate a link to the file online.
I've pretty much implemented it but there is one situation that I can't get working.
For regular onedrive files I use:
RESTRequest1.Resource := Format('/me/drive/root:/%s:/createLink', [RelativePath]);
And for shared files I use
RESTRequest1.Resource := '/me/drive/sharedWithMe';
And then I loop through shared files until I find matching file and then I grab the webUrl
from the response.
The problem is this though. There is a folder shared with me and for this folder I added a shortcut to the shared folder in my OneDrive like described here. One of the files in this folder is also shared directly with me, the other one isn't. The file that's shared directly with me I can find using /me/drive/sharedWithMe
. But I'm not able to retrieve the file that isn't shared directly with me. It is in the shared folder though so I thought I should be able to.
I tried some different things like looking if I could get the shared folder by calling this: /me/drive/root/children
. But this gives me all folders and files except for the shared folder.
Is it possible what I'm trying to do?
Upvotes: 1
Views: 184
Reputation: 15462
I was able to figure something out.
Like I mentioned in my question I had tried this endpoint: /me/drive/root/children
. But this gives me all folders and files except for the shared folder.
I found something interesting in the response when I tried this endpoint: me/drive/root
. The response contained: "folder":{"childCount":7}
. 7
is the correct number of files and folders in the root onedrive directory including the shortcut to the shared folder.
I find it strange that this endpoint shows the correct count, but that the children endpoint does not get the shared folder, but either way because of this I did try to get info on the shared folder directly with this endpoint: /me/drive/root:/NameSharedFolder:/
and that actually worked. Got back something like this:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(driveItem)/$entity",
"createdBy": {
"application": {
"id": "id",
"displayName": "SharePoint Online Client Extensibility"
},
"user": {
"email": "email",
"id": "id",
"displayName": "displayname"
}
},
"createdDateTime": "2025-02-17T09:26:14Z",
"eTag": "\"{tag},3\"",
"id": "id",
"lastModifiedBy": {
"user": {
"email": "email",
"id": "id",
"displayName": "displayName"
}
},
"lastModifiedDateTime": "2025-02-17T09:26:15Z",
"name": "NameSharedFolder",
"parentReference": {
"driveType": "business",
"driveId": "driveID",
"id": "id",
"name": "Documents",
"path": "/drive/root:",
"siteId": "siteID"
},
"cTag": "\"c:{tag},1\"",
"fileSystemInfo": {
"createdDateTime": "2025-02-17T09:26:14Z",
"lastModifiedDateTime": "2025-02-17T09:26:15Z"
},
"remoteItem": {
"folder": {
"childCount": 2
},
"id": "id",
"parentReference": {
"driveType": "business",
"driveId": "driveID"
},
"sharepointIds": {
"listId": "id",
"listItemUniqueId": "id",
"siteId": "id",
"siteUrl": "id",
"webId": "id",
"webRelativeListUrl": "Documents"
},
"size": 31810
},
"size": 0
}
From this I could get the driveID
and folderID
(id
) and do a request to /drives/{drive-id}/items/{item-id}/children
. The response of this request listed the file with webUrl
.
This is the delphi code that gives me the file link:
RESTRequest1.Resource := '/me/drive/root:/' + ExtractFileDir(RelativePath) + ':/';
RESTRequest1.Method := rmGET;
RESTRequest1.Params.Clear;
RESTRequest1.Execute;
if RestRequest1.Response.StatusCode = 200 then
begin
var sharedFolder := TJSONObject.ParseJSONValue(RestRequest1.Response.Content) as TJSONObject;
try
if sharedFolder.Values['remoteItem'] <> nil then
begin
var remoteItem := sharedFolder.Values['remoteItem'] as TJSONObject;
folderID := remoteItem.GetValue<string>('id');
driveID := TJSONObject(remoteItem.GetValue('parentReference')).GetValue<string>('driveId');
end else
begin
folderID := sharedFolder.GetValue<string>('id');
driveID := TJSONObject(sharedFolder.Values['parentReference']).GetValue<string>('driveId');
end;
finally
sharedFolder.Free;
end;
RESTRequest1.Resource := '/drives/' + driveID + '/items/' + folderID + '/children';
RESTRequest1.Method := rmGET;
RESTRequest1.Params.Clear;
RESTRequest1.Execute;
if RestRequest1.Response.StatusCode = 200 then
begin
var sharedFolderItems := TJSONObject.ParseJSONValue(RestRequest1.Response.Content) as TJSONObject;
try
var sharedFolderItemsArray := sharedFolderItems.GetValue<TJSONArray>('value');
var fileName := ExtractFileName(RelativePath);
for var I := 0 to sharedFolderItemsArray.Count - 1 do
begin
var item := sharedFolderItemsArray.Items[I] as TJSONObject;
if SameText(item.GetValue<string>('name'), fileName) then
begin
var webURL := item.GetValue<string>('webUrl'); // Got webURL do something with it...
Break;
end;
end;
finally
sharedFolderItems.Free;
end;
end;
end;
Upvotes: 1
Reputation: 2671
As I see it you try to query the files in your onedrive (either shared by you or with you). But if it is a shared file you do not always have the file availabe in you own onedrive. It is rather a shortcut to the file (although you don`t see that), where the files resides in the original owners onedrive.
/me/drive/root/children API call will not return shortcuts to shared folders
/me/drive/sharedWithMe should only return files and folders explicitly shared with you directly
So you might need to query the "Special" Collection for Shortcuts which is provided by the api:
https://graph.microsoft.com/v1.0/me/drive/special/shortcuts/children (Http Get)
With the shortcut folder found, you can query its children:
https://graph.microsoft.com/v1.0/me/drive/items/{shortcut-folder-id}/children (Http Get)
But maybe it would be better to get a link to the original file in another owners onedrive.
https://graph.microsoft.com/v1.0/drives/{ownerDriveId}/items/{sharedFolderId}/children
I am not sure though if the information received by the special folder query is sufficient for that.
Upvotes: 1