Neil Neil - 24 days ago 15
Javascript Question

External Sharing of Folders in SharePoint Online using REST API

I am new to SharePoint Online and REST API.

I am currently working on a SharePoint Add-In which creates folders in a document library residing in the Host Web and share the permission to specified external users. I am currently attempting to do everything using REST API.

I am successfully able to create the folders but I am currently unable to share the folders to external users.

I am having trouble resolving the following endpoints when attempting to use the host web context. The first endpoint below is for resolving the external email, and the second one is for performing the actual sharing of the folder to the external user.

[appUrl]/_api/SP.AppContextSite(@target)/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerResolveUser?@target='[hostUrl]'

[appUrl]/_api/SP.AppContextSite(@target)/SP.Web.ShareObject?@target='[hostUrl]'


I am getting the error
404 Not Found
:
Cannot find resource for the request SP.UI.ApplicationPages.ClientPeoplerPickerWebServiceInterface.clientPeoplePickerResoveUser
. The same error occurs for
SP.Web.ShareObject
when I try to force it to run.

Below is the javascript that I am using

var ShareToRecipients = function(folder, recipient, appUrl, hostUrl){

var url = appUrl = "/_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerResolveUser";
url = WebComponents().getTargetUrl(url, hostUrl);

var sharedDocUrl = hostUrl + "/ExternalShareDocLib/" + foldername;

var checkUser = $.ajax({
url: url,
type: "POST",
contentType: "application/json;odata=verbose",
data: JSON.stringify({
'queryParams': {
"__metadata": {'type': "SP.UI.ApplicationPages.ClientPeoplePickerQueryParameters"},
"AllowEmailAddresses": true,
"AllowMultipleEntities": false,
"AllUrlZones": false,
"MaximumEntitySuggestions": 50,
"PrincipalSource": 15,
"PrincipalType": 1,
"QueryString": recipient
}
}),
headers:{
"accept": "application/json;odata=verbose",
"X-RequestDigest": $('#__REQUESTDIGEST').val()
},

error: function(jqXHR, textStatus){
myapp.LogAPIError(jqXHR, textStatus)
}
});

checkUser.success(function(data){
var user = data.d.ClientPeoplePickerResolveUser;
var result = JSON.parse(users);

if(users !== undefined){
var reqUrl = appUrl + "/_api/SP.Web.ShareObject";
reqUrl = WebComponents().getTargetUrl(reqUrl, hostUrl);

var shareCall = $.ajax({
url: reqUrl,
type: "POST",
contentType: "application/json;odata=verbose",
data: JSON.stringify({
"url": reqUrl,
type: "POST",
contentType: "application/json;odata=verbose",
data: JSON.stringify({
"url": sharedDocUrl,
"peoplePickerInput": '[' + user + ']',
"roleValue": "1073741827",
"groupId": 0,
"propagateAcl": false,
"sendEmail": true,
"includeAnonymousLinkInEmail": true,
"emailSubject": "A document folder has been shared to you",
"emailBody": "A document folder has been shared to you. The folder name is " + folder
})
});
});

shareCall.success(function(data){
myApp.LogInformation("Successfully shared " + folder + " to " + recipient);
});

shareCall.error(function(jqXHR, textStatus){
myApp.LogAPIError(jqXHR, textStatus);
});
}
});}


For generating the Host URL Endpoint

var WebComponents = function(){
var getTargeturl = function (url, hostUrl){
if(hostUrl){
var api = "_api/";

var index = url.indexOf(api);
url = url.slice(0, index + api.length)+
"SP.AppContextSite(@target)" +
url.slice(index + api.length);

var connector = "?";
if(url.indexOf("?") > -1 && url.indexOf("$") > -1){
connector = "&";
}

url = url + connector + "@target='" + hostUrl + "'";
}

return url;
}

return{
getTargeturl: getTargeturl
}}


Can you help verify if I am using the endpoints correctly and if what I am trying to do is even possible?
Appreciate the help.

Cheers,
Neil

Answer

Adding my resolution just in case anyone else encounters this issue. I was able to use the API by:

  1. Removing url = WebComponents().getTargetUrl(url, hostUrl) and reqUrl = WebComponents().getTargetUrl(reqUrl, hostUrl).
  2. Giving the App Full Control in the Tenant via the AppManifest.xml
Comments