Overview
Client-mode connector for a self-hosted Nextcloud server that moves plant files and messages between the broker and Nextcloud. A typical flow writes a shift report, batch record or alarm snapshot as a JSON or CSV file into a plant folder (the folder is created on the fly), writes today’s setpoint table over yesterday’s while Nextcloud keeps the old one as a version, reads a recipe back when a line changes over, comments on a batch record when QA releases it, shares a weekly report with a public link that expires, and sends an alarm to the maintenance team as a Nextcloud notification or a message in a Talk conversation. New files can be picked up from the activity stream or with a webhook listener that calls the broker. The template fileNextcloudRestApi.lot holds one connector, NextcloudRestApi, with 43 events (29 GET, 9 POST, 5 PUT; 13 writes, no delete). Files go through WebDAV (/remote.php/dav/files/...), everything else through the OCS API (/ocs/v2.php/...) of the server and its apps: provisioning, sharing, notifications, activity, user status, calendar (dav), Talk (spreed) and webhook listeners. Topics use storage/nextcloud/<object>/<verb>; each response is published on <source topic>/response.
The connector was checked against the Nextcloud OpenAPI specs (server core, provisioning, files, sharing, dav, user status and webhook listeners; notifications and Talk) for method, path, path parameters, required headers and query parameters and every example body, against the Nextcloud developer manual for WebDAV, comments and activity, and against a local mock. It was then run live against a local Nextcloud 35.0.1 server (official Docker image) with Talk 25.0.5: all 43 events answered as expected, including a file created, read back, overwritten as a new version and shared by public link, a notification, a Talk conversation with a message and a webhook listener. Every authenticated event answered
401 to a wrong app password. The local test used plain HTTP on localhost and called the server directly, not through a broker.Setup
- Point the connector at your server: replace
BASE_ADDRESS(https://nextcloud.example.comin the template) with your Nextcloud address, including the web root if Nextcloud does not run at the domain root (for examplehttps://cloud.example.comorhttps://example.com/nextcloud), without a trailing slash. Keep this value asNEXTCLOUD_BASE_URLin your deployment notes. For plain HTTP on a plant LAN usehttp://...and setUSE_SSL "false". The host name must be in the server’strusted_domains. - Create a dedicated account for the broker, for example
plant-bot, and give it a storage quota. Share the plant folders with it, or let it own them. - Log in as that account and create an app password under Personal settings > Security > Devices & sessions > Create new app password. Use the app password, never the login password: accounts with two-factor authentication refuse login passwords, and you can revoke an app password on its own.
- Admin-only events (
UsersList,GroupsList,GroupUsersList,AdminNotificationSendand the webhook events) need an app password of an administrator. Group sub-admins can list the users and groups they manage. Webhook listeners can also be delegated to a group through the Webhooks admin privilege. - Talk events need the Talk app, webhook events the Webhook listeners app (Nextcloud 30 and later, shipped but check that it is enabled), and activity events the Activity app.
- Keep
NEXTCLOUD_USER,NEXTCLOUD_APP_PASSWORDand the derivedNEXTCLOUD_BASIC_AUTH(see below) in broker secrets and inject them withGET SECRET.
Authentication
Every event exceptStatusGet sends Authorization: Basic <credentials>, built from the basic_auth field of the payload. basic_auth is the Base64 of <NEXTCLOUD_USER>:<NEXTCLOUD_APP_PASSWORD>, for example plant-bot:Ab12C-dE34f-.... Store that value as the secret NEXTCLOUD_BASIC_AUTH:
OCS-APIRequest: true (without it Nextcloud answers 412 CSRF check failed) and ask for JSON with ?format=json. OCS answers in an envelope: the result is in ocs.data, the status in ocs.meta.
As an alternative, the connector can carry the credentials itself with WITH USERNAME and WITH PASSWORD in REST_API_CONFIG. In that case, remove the Authorization header lines from the events.
Payloads
Send
query as an empty string when you need no parameters; the request then ends with &, which Nextcloud ignores.
Uploading files
FileUpload writes a new file with WebDAV PUT. It sends If-None-Match: *, so an existing file is never overwritten: Nextcloud answers 412 Precondition Failed instead. It also sends X-NC-WebDAV-Auto-Mkcol: 1, so Nextcloud 32 and later create missing parent folders. Older servers answer 404 or 409 when the folder does not exist yet; create it by hand once.
201 Created with an empty body. The new file id is in the OC-FileId response header (00000091oc...: the number before the instance suffix is the file id). Use Search (provider files) or ActivityList to find file ids later.
FileVersionUpload writes a file whether it exists or not (201 for a new file, 204 when it replaced one). With the Versions app, the previous content stays in the file’s version history, so writing today’s setpoint table over yesterday’s keeps yesterday’s as a version. FileDownload returns the raw file content. Keep files to text, CSV or JSON that fits an MQTT message.
Build the payload in a LoT action:
Examples
Health check without credentials (storage/nextcloud/status/get), for example from a timer:
installed, maintenance, needsDbUpgrade and versionstring.
Read a recipe back on changeover (storage/nextcloud/files/download):
storage/nextcloud/folders/tree/get):
storage/nextcloud/search/query); each entry carries the path in subline and the file id in attributes.fileId:
storage/nextcloud/shares/create); the answer carries url, token and id:
shareType is 0 for a user, 1 for a group, 3 for a public link and 4 for email; permissions adds up 1 read, 2 update, 4 create, 8 delete and 16 share. End a link early with ShareUpdate and an expireDate of today instead of deleting it.
Comment on a batch record when QA releases it (storage/nextcloud/files/comments/create):
storage/nextcloud/notifications/admin/send, admin only):
storage/nextcloud/talk/messages/send). Create the conversation once with TalkRoomCreate ({"roomType": 2, "roomName": "Line 2 alarms"}), add people with TalkParticipantAdd, and keep its token:
storage/nextcloud/user-status/set, then storage/nextcloud/user-status/message/set):
storage/nextcloud/activity/list): ask for filter files with query since=<last activity_id>&sort=asc&limit=50, store the X-Activity-Last-Given id (or the last activity_id), and treat 304 as nothing new. Use filter filter with object_type=files&object_id=<id> for the history of one file.
Or let Nextcloud call the broker when a file is created in the plant folder (storage/nextcloud/webhooks/create, admin only). The uri is a broker REST_API server connector that Nextcloud can reach; authData sets a header the receiver checks:
Events
Limits
- WebDAV
PUThas no size limit of its own, but the web server and PHP limits apply (upload_max_filesize,post_max_size, proxy body size). Keep MQTT payloads small. Larger files need chunked uploads, which are not packaged. X-NC-WebDAV-Auto-Mkcolneeds Nextcloud 32 or later. Admin notifications use the v3 API:subjectup to 255 characters,messageup to 4000. Talk messages are limited to 32000 characters.- Nextcloud’s brute-force protection delays and then blocks (
429) an IP address after repeated failed logins. In the local test it blocked the client after 11 wrong passwords. - Shares can have an enforced maximum expiry and password policy (see
CapabilitiesGet,files_sharing). A share that breaks the policy answers400or403. FolderTreeGetlists folders only, andSearchonly matches names. File listings with sizes and dates need WebDAVPROPFIND, which is not a REST_API method.
Not packaged
- Delete events on purpose: files, folders, shares, notifications, Talk conversations and participants, status messages and webhook listeners.
- WebDAV methods that REST_API does not offer (it supports
GET,POST,PUT,DELETEandPATCH):PROPFIND(folder listing and file properties),MKCOL(create folder;FileUploadcreates parents instead),MOVEandCOPY(rename, archive, copy),PROPPATCH(favorites, tags),REPORTandSEARCH(filtered listings, comment lists), and theMOVE-based trash and version restore. - Chunked uploads (v2) and bulk upload, public share (
/public.php) uploads, folder downloads as ZIP or TAR, previews and thumbnails. - User and group administration (create, edit, disable, wipe), app passwords and login flow, app config, Talk calls, polls, bots and breakout rooms, calendar and contacts writes (CalDAV and CardDAV), Deck, Forms and Tables.
- The webhook receiver. A receiver would be a separate
ENABLE_SERVERREST_API connector that checks theauthDataheader.
Suggested branches
feat/rest-api-route-nextcloud for the broker template and feat/docs-rest-api-nextcloud for this page.
