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