This integration was a request from a sponsor, who uses Nextcloud in a similar way to the Dropbox API example we posted recently.
Nextcloud
I didn’t know much about the Nextcloud API and despite the documentation being somehow fragmented, the interaction seemed possible using the BaseElements plugin.
The idea is the same: we want to share a folder or file in Nextcloud from within a FileMaker solution.
Nextcloud has more than one API (with different implementations) and for our project we’ll need 3 different services:
- the webDAV API to find files and folders
- the Provisioning API to manage the users
- the Share API to share the files and folders
the implementation of these web services are quite different from the ones we covered in the previous posts (Dropbox, Zendesk and Mailchimp).
First of all the format used for the response is not JSON but XML and in the case of the webDAV API we have to define a cURL option to retrieve the field list.
If you’re not familiar with cURL, it is a library used to transfer data using various protocols and it is used in the HTTP functions in the BaseElements plugin.
Authentication
The Nextcloud API provides only Basic Auth without any API keys or Token. We simply pass our username and password with the request:
https://user:password@demo.nextcloud.com/mydemo
Get the Files and Folders List
The first step in the process is to retrieve the list of files and folders hosted in our account. For this we’ll use the webDAV API.
The docs indicate that we need to perform a PROFIND
request: to do the we need to set a cURL option before calling our GET request.
The option to set is called CURLOPT_CUSTOMREQUEST
and we have to set it to the value PROPFIND
. The BaseElements plugin function to do this is
BE_Curl_Set_Option ( "CURLOPT_CUSTOMREQUEST" ; "PROPFIND" )
one thing to remember is that the effects of BE_Curl_Set_Option don’t reset after a call. We need to explicitly reset it calling the function without parameters when we don’t need the option anymore.
Once the cURL option is set we can perform our GET request. The url will be our base URL followed by /remote.php/dav/files/USERNAME/
. If our username is admin
and our domain is goyafm
the url will be
https://admin:password@demo.nextcloud.com/goyafm/remote.php/dav/files/USERNAME/
or if we want to get the list from a subfolder instead than from the root
https://admin:password@demo.nextcloud.com/goyafm/remote.php/dav/files/USERNAME/THESUBFOLDER
.
We will perform the call using the BE_HTTP_GET function
BE_HTTP_GET ( "https://admin:password@demo.nextcloud.com/goyafm/remote.php/dav/files/USERNAME/" )
The result is in XML and can be parsed using the functions BE_XPath and BE_XPathAll from the plugin.
Get the Users List
To decide who we are sharing our files with we need a way to identify them in the request, so our second step is to retrieve the list of users from the Nextcloud installation.
The Provision API uses a normal HTTP GET request to return an XML message. The HTTP Header OCS-APIRequest needs to be set to "true" and we can use BE_HTTP_Set_Custom_Header to set it
BE_HTTP_Set_Custom_Header ( "OCS-APIRequest" ; "true" )
.
The url of the GET request will be our base URL followed by /ocs/v1.php/cloud/users
which using the same example values becomes
BE_HTTP_GET ( "https://admin:password@demo.nextcloud.com/goyafm/ocs/v1.php/cloud/users" )
which for the users in this screenshot
will return
<ocs>
<meta>
<statuscode>100</statuscode>
<status>ok</status>
</meta>
<data>
<users>
<element>admin</element>
<element>nick</element>
<element>salvatore</element>
</users>
</data>
</ocs>
Share
Now we have the folder we want to share and the user identification. We can use the Share API to send a POST request to Nextcloud.
If you have used Dropbox, Box or similar in the past the terminology used in Nextcloud can be a bit confusing: every time we share a file or folder we create a new "share", which doesn't mean we are creating a new folder.
So to create a new share we can use the endpoint /ocs/v1.php/apps/files_sharing/api/v1/shares
passing 3 parameters:
- the path of the file to share
- the share type (0 = user; 1 = group; 3 = public link; 6 = federated cloud share)
- the user with which the file should be shared.
These parameters are passed as the body of the POST request. If we want to share the folder Photos
with the user salvatore
the body will be
path=/Photos/&shareType=0&&shareWith=salvatore
so the complete request using BE_HTTP_POST will be
BE_HTTP_POST ( "https://admin:password@demo.nextcloud.com/goyafm/ocs/v1.php/apps/files_sharing/api/v1/shares" ; "path=/Photos/&shareType=0&&shareWith=salvatore" )
If BE_HTTP_Response_Code returnsĀ 200, we know the share was created.
Conclusion
This API was certainly different from the ones we covered in the past and it gave us a way of looking at different functions and different implementations.
A full example file has been added to the shared folder for our sponsors.
If any other subscriber has a request for an API integration, send us your idea!
Salvatore is our web services and integration expert, passionate about linking any API useful to our clients (or us!) to FileMaker. He loves to share ideas and a good story, and as a speaker at DevCon he manages to do both.