@ulyxie/n8n-nodes-otex-cs (0.0.2-dev.6)
Installation
@ulyxie:registry=npm install @ulyxie/n8n-nodes-otex-cs@0.0.2-dev.6"@ulyxie/n8n-nodes-otex-cs": "0.0.2-dev.6"About this package
@ulyxie/n8n-nodes-otex-cs
n8n community nodes for OpenText Content Server. Read, create, update and delete nodes, move documents in and out as binary data, and run Web Reports from your n8n workflows.
n8n is a fair-code licensed workflow automation platform.
Installation · Credentials · Node resource · Document resource · Web Report · Behaviour · Development
Installation
Important
This package has a runtime dependency (
@ulyxie/cs-rest) and is therefore self-hosted only — it is not eligible for n8n Cloud.
Follow the community nodes installation guide. In your n8n instance go to Settings → Community Nodes → Install and enter:
@ulyxie/n8n-nodes-otex-cs
Or install manually into a self-hosted instance:
npm install @ulyxie/n8n-nodes-otex-cs
The package ships two nodes and one credential type.
Credentials
Both nodes use the OpenText Content Server API credential (otexContentServerApi).
| Field | Required | Notes |
|---|---|---|
| Base URL | yes | The REST entry point including the cs.exe (or equivalent) suffix, e.g. https://server/otcs/cs.exe. Trailing slashes are stripped before use. |
| Username | yes | Content Server user name. |
| Password | yes | Stored masked. |
Authentication is username/password; the Content Server issues an OTCSTicket which the client library manages per request. A fresh session is created for each input item.
The credential's Test button issues POST {baseUrl}/api/v1/auth as application/x-www-form-urlencoded and treats a 200 as success. This is a connectivity/credential check only — actual node operations authenticate through @ulyxie/cs-rest, not through that request.
Node: OpenText Content Server
Internal name otexContentServer. Marked usableAsTool, so it can be attached to an AI Agent node. Operations are grouped under two resources; the node subtitle shows <operation>: <resource>.
Resource: Node
Working with nodes in the Content Server tree. This is the default resource.
| Operation | Value | Calls | Returns |
|---|---|---|---|
| Get | get |
nodes.node (API v2) |
The node object |
| List Children | list |
nodes.children |
One output item per child |
| Create Folder | createFolder |
nodes.addFolder |
The created folder |
| Update | update |
PUT api/v2/nodes/{id} |
The updated node, or { "id": … } if the API returns no body |
| Delete | delete |
nodes.delete |
{ "id": …, "deleted": true } |
Default operation is Get.
| Parameter | Type | Default | Shown for |
|---|---|---|---|
| Node ID | number | 0 |
Get, List Children, Update, Delete |
| Parent ID | number | 0 |
Create Folder |
| Name | string | — | Create Folder |
| Return All | boolean | false |
List Children |
| Limit | number | 50 |
List Children, when Return All is off |
| Additional Fields | collection | {} |
Create Folder (Description), Update (Name, Description) |
For List Children, Node ID is the parent container whose children you want. Update requires at least one Additional Field.
Resource: Document
Moving file content in and out of Content Server.
| Operation | Value | Calls | Returns |
|---|---|---|---|
| Download | download |
GET api/v1/nodes/{id}/content |
{ "id": … } plus a binary field |
| Upload | upload |
nodes.addDocument |
The created document |
Default operation is Download.
| Parameter | Type | Default | Shown for |
|---|---|---|---|
| Node ID | number | 0 |
Download |
| Parent ID | number | 0 |
Upload |
| Input Binary Field | string | data |
Upload |
| Put Output Binary Field | string | data |
Download |
| Additional Fields | collection | {} |
Upload — Name (defaults to the input file name) and Description |
Node: OpenText Content Server Web Report
Internal name otexContentServerWebReport. Also usableAsTool. Subtitle shows Run: <id>.
| Parameter | Type | Default | Notes |
|---|---|---|---|
| Operation | options | run |
Only Run exists today |
| Web Report ID | number | 0 |
Node ID of the Web Report |
| Parameters | fixed collection | {} |
Name/value pairs passed as query string values |
Parameter rows with an empty Name are skipped.
Output shape depends on what the report returns: a plain object is emitted as the item JSON unchanged; anything else — a string, a number, an array — is wrapped as { "output": … } so the item is always a valid JSON object.
Behaviour notes
These are worth knowing before you wire the nodes into a workflow.
Pagination. List Children always paginates. With Return All off it fetches a single page sized to your Limit and slices the result to that many items. With Return All on it walks pages at 200 per request until it has seen page_total pages or a page comes back empty. The paging metadata is read from either collection.paging or a top-level paging, so both response shapes work. Each child becomes its own output item, not an array on one item.
Uploads go through a temporary file. The client library takes a file path rather than a buffer, so the binary field is written to a uniquely-named file in the OS temp directory, uploaded, then deleted — including if the upload throws. The n8n process needs write access to os.tmpdir().
Download file names. The name is parsed out of the response's Content-Disposition header (both plain and UTF-8''-encoded forms) and URL-decoded. If the header is missing or unparseable, the node ID is used as the file name.
Update needs something to change. Supplying neither Name nor Description in Additional Fields raises an error rather than sending an empty request. An empty-string description is treated as "not supplied".
API versions are mixed. Get and Update use v2 endpoints; Download uses v1. That reflects what Content Server actually exposes, not an oversight.
Resource and operation are checked together. Execution dispatches on the pair, so driving either field by expression into a combination that doesn't exist — say resource document with operation get — raises Unsupported operation "get" for resource "document" rather than quietly running the Node branch.
Per-item error handling. Every operation runs once per input item. With Continue On Fail enabled a failing item emits { "error": "<message>" } and the run continues; otherwise the error is thrown with the offending item index attached. All output items — including error items — carry pairedItem references back to their input.
Compatibility
- n8n: nodes API version 1; both nodes are at node version 1.
- Node.js: 20 or newer, matching n8n's own requirement.
- Content Server: REST API v1 and v2, as described above.
Development
npm install
npm run dev # starts n8n with these nodes loaded, hot reload enabled
| Script | Does |
|---|---|
npm run build |
Compiles TypeScript into dist/ and copies static files (icons, .node.json) |
npm run lint |
Runs the n8n community-node linter |
npm run lint:fix |
Autofixes what it can |
Layout
credentials/OtexContentServerApi.credentials.ts credential type + connection test
nodes/OtexContentServer/ the general node
nodes/OtexContentServerWebReport/ the Web Report node
nodes/shared/session.ts the only @ulyxie/cs-rest import
icons/ light + dark SVGs
nodes/shared/session.ts is deliberately the single import boundary for the client library — it reads the credential, normalises the base URL and returns a Session. If the dependency is ever swapped for a fork, that is the only module to change.
The eslint config extends configWithoutCloudSupport and disables no-runtime-dependencies, because the runtime dependency on @ulyxie/cs-rest is intentional and rules this package out of n8n Cloud anyway.
Releasing
Two channels, both automated:
| Channel | Trigger | Target | Secret |
|---|---|---|---|
| Release | push a v* tag |
npmjs.com, latest — staged, pending approval |
NPM_TOKEN |
| Dev | push to main |
Forgejo registry, dev dist-tag |
CI |
The release version comes from the tag, so package.json is never hand-edited:
git tag v0.0.2 && git push origin v0.0.2
A tag push does not make the version live. CI runs npm stage publish, which uploads the tarball to npm's staging area without needing 2FA — that is what lets a Forgejo runner do it. A maintainer then approves it:
npm stage list @ulyxie/n8n-nodes-otex-cs
npm stage view <stage-id>
npm stage approve <stage-id>
npm stage approve prompts for 2FA; that is the point of the design. Approval also works from the package page on npmjs.com, and npm stage reject <stage-id> throws the build away. Staging needs npm ≥ 11.15.0 and Node ≥ 22.14.0, so the workflow upgrades npm before running it.
Note
v0.0.1was published directly from a maintainer's machine. Staging cannot create a package that does not yet exist on the registry, so a first release always has to be done by hand.
Dev builds are versioned <version>-dev.<run number> and never move latest. To install one, point npm at the Forgejo registry:
npm install @ulyxie/n8n-nodes-otex-cs@dev --registry https://git.derg.cz/api/packages/content-server/npm/
Note
Releases are published with an access token rather than npm provenance. Provenance requires an OIDC token that only GitHub Actions and GitLab CI/CD can mint for npm, and this repository runs on Forgejo Actions.
Resources
License
Dependencies
Dependencies
| ID | Version |
|---|---|
| @ulyxie/cs-rest | ^3.1.4 |
Development dependencies
| ID | Version |
|---|---|
| @n8n/node-cli | * |
| eslint | 9.29.0 |
| prettier | 3.8.3 |
| release-it | 20.2.0 |
| typescript | 5.9.3 |
Peer dependencies
| ID | Version |
|---|---|
| n8n-workflow | * |