Add node docs, collabora purple UI, and portable install env

Human-readable help in all six palette nodes, docs/NODES.md with usage examples, expanded example flows, and auto-detect NODERED_DIR plus CODE bridge IP from .env on any VM.
This commit is contained in:
root
2026-08-22 17:10:34 +02:00
parent 5d4d7a58e6
commit 4fb614be87
13 changed files with 558 additions and 50 deletions
+20 -4
View File
@@ -1,7 +1,23 @@
# Genereras av bootstrap-install.sh eller manuellt # Miljövariabler för install.sh / integrate-into-nodered.sh
NC_HOST=cloud.hannesahlin.se # Kopiera till .env och justera per VM.
NC_HOST_IP=192.168.1.26
# Nextcloud (visas i exempelflöden och dokumentation — påverkar inte själva nodkoden)
NEXTCLOUD_URL=https://cloud.hannesahlin.se NEXTCLOUD_URL=https://cloud.hannesahlin.se
COLLABORA_URL=http://172.17.0.2:9980 NEXTCLOUD_PUBLIC_URL=https://cloud.hannesahlin.se
# Collabora CODE — IP detekteras automatiskt från Docker bridge om du utelämnar COLLABORA_IP
CODE_CONTAINER=code
COLLABORA_IP=
COLLABORA_URL=
# Befintlig Node-RED-installation (integrate-läge)
NODERED_DIR=
NODERED_CONTAINER=nextcloud-node-red
NODERED_PORT=1880
INSTALL_USER=
# Sidecar-läge (ej standard)
NC_HOST=cloud.hannesahlin.se
NC_HOST_IP=
TZ=Europe/Stockholm TZ=Europe/Stockholm
NODERED_CREDENTIAL_SECRET=byt-den-här-hemligheten-vid-produktion NODERED_CREDENTIAL_SECRET=byt-den-här-hemligheten-vid-produktion
+23
View File
@@ -47,8 +47,31 @@ INSTALL_MODE=sidecar docker compose --profile sidecar up -d --build
## Noder ## Noder
Palett: **nextcloud collabora** — sex noder i samma lila, alla kopplade till **nc-collab-config** (kugghjul, inte flödesnod).
`nc-collab-config` · `collabora-bridge` · `nc-office` · `collabora-convert` · `collabora-extract` · `collabora-transform` · `collabora-wopi` `nc-collab-config` · `collabora-bridge` · `nc-office` · `collabora-convert` · `collabora-extract` · `collabora-transform` · `collabora-wopi`
Full förklaring och exempel: **[docs/NODES.md](docs/NODES.md)** · importera **[flows/example-flows.json](flows/example-flows.json)**
## Installera på valfri Nextcloud-VM
Kopiera `.env.example` → `.env` och sätt minst `NEXTCLOUD_URL`. Resten detekteras:
| Variabel | Default / auto |
|----------|----------------|
| `NODERED_DIR` | compose-label eller `/home/ncadmin/nextcloud-node-red` |
| `CODE_CONTAINER` | `code` |
| `COLLABORA_IP` | bridge-IP via `docker inspect` |
| `NODERED_CONTAINER` | `nextcloud-node-red` |
| `NODERED_PORT` | `1880` |
```bash
cd /home/ncadmin/nextcloud-collabora-nodered
cp .env.example .env # justera NEXTCLOUD_URL per VM
git pull
./install.sh # root/sudo för docker compose
```
## Repo ## Repo
https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered https://kode.hannesahlin.se/n3wk/nextcloud-collabora-nodered
+174
View File
@@ -0,0 +1,174 @@
# Noder — nextcloud collabora
Sex flödesnoder i paletten + en config. Alla sex pekar på samma **nc-collab-config** (kugghjul, inte i paletten). Utan config händer inget.
## Backends
| Backend | Typisk adress | Roll |
|---------|---------------|------|
| Nextcloud | `https://cloud.hannesahlin.se` | Filer (WebDAV) + Office-API (OCS) |
| Collabora CODE | `https://172.17.0.2:9980` | Konvertering (`/cool/...`) på Docker bridge |
Auth: **användarnamn + app-lösenord**. Inte kontolösen.
Standardutdata om du inte anger sökväg: `/Dokument/OfficeOut/`
---
## Så hänger de ihop
```
nc-collab-config (URL + app-lösen)
│
┌────┼────┬────────────┐
▼ ▼ ▼ ▼
collabora-* nc-office collabora-wopi collabora-bridge
(direkt CODE) (NC OCS) (health/WOPI) (kedjor + sparar)
```
**Tumregel**
- PDF i Nextcloud → `collabora-bridge` **ncFileToPdf**
- Fylla mall i NC → **fillTemplateSave** eller `nc-office template:fillFields`
- Öppna i webbläsaren → `nc-office` **document:direct**
- Bara byta format i minnet → `collabora-convert`
- Se fältnamn → `collabora-extract` eller bridge **extractToPayload**
- Kolla att CODE lever → `collabora-wopi` **capabilities**
---
## Gemensamma fält i msg
| Fält | Betydelse |
|------|-----------|
| `ncPath` | Sökväg i användarens filer, t.ex. `/Dokument/avtal.docx` |
| `fileId` | NC fil-id (slås upp från ncPath om saknas) |
| `payload` | Rådata redan i flödet (Buffer eller HTML) |
| `format` | pdf, png, docx, html, … |
| `destNcPath` | Exakt målsökväg |
| `destFolder` / `destName` | Mapp + namn (default `/Dokument/OfficeOut/`) |
| `fields` / `transform` | JSON att skriva in i mall |
| `templateNcPath` | Extra mall till convert |
| `compareNcPath` | Gammal version för diff-PDF |
| `operation` | Överstyr dropdown på noden |
Fel → `msg.error` + röd nod. Flödet dör inte tyst.
---
## 1. collabora-convert
Gör om fil till annat format via CODE. Sparar **inte** i Nextcloud — utdata i `msg.payload` (Buffer).
**In:** `msg.payload` eller WebDAV GET `msg.ncPath`. Valfritt `templateNcPath`, `compareNcPath`, `format`.
**Ut:** `payload`, `filename`, `format`, `contentType`, `statusCode`.
```
inject { ncPath: "/Dokument/avtal.docx", format: "pdf" }
→ collabora-convert → debug
```
---
## 2. collabora-extract
Lista struktur (content controls, fält …). JSON ut, ingen fil.
**In:** samma källa som convert. Filter: nod eller `msg.filter` (default `contentcontrol`).
```
inject { ncPath: "/Mallar/avtal.docx" }
→ collabora-extract → function → collabora-transform
```
---
## 3. collabora-transform
Skriv värden i dokument via CODE. Kräver `msg.fields` eller `msg.transform`.
```
msg.ncPath = "/Mallar/avtal.docx"
msg.fields = { "Kund": "AB Exempel", "Datum": "2026-08-22" }
→ collabora-transform
```
Spara själv efteråt om filen ska ligga i NC.
---
## 4. collabora-wopi
Hälsokoll och WOPI — inte konvertering.
| Operation | Syfte |
|-----------|--------|
| `capabilities` | Första test att CODE svarar |
| `discovery` | mime → editor-URL |
| `buildEditor` | `wopiSrc` + `token` → `editorUrl` |
| `checkFileInfo` / `getFile` | Felsökning |
Publik editor-URL går via Nextcloud (`collaboraPublicUrl`), inte intern IP.
---
## 5. nc-office
Nextcloud richdocuments OCS — mallar, fält, editor-URL, assets.
| Operation | Kort |
|-----------|------|
| `templates:list` | Lista mallar |
| `templates:create` | Ny fil från mall |
| `template:extractFields` | Fält-JSON via NC |
| `template:fillFields` | Fyll + spara i NC |
| `document:direct` | `editorUrl` för inloggad användare |
| `document:public` | Samma med shareToken |
| `files:convert` | NC → NC konvertering |
| `assets:create` | Infogningslänk till öppen editor |
```
inject { ncPath: "/Dokument/avtal.docx" }
→ nc-office (document:direct) → debug editorUrl
```
---
## 6. collabora-bridge
Färdiga pipelines — det mesta i vardagsflöden.
| Operation | Gör |
|-----------|-----|
| `ncFileToPdf` | NC-fil → PDF i OfficeOut |
| `ncFileToPng` | Förhandsvisning |
| `ncFileToHtml` | HTML-export |
| `htmlToOffice` | HTML → docx/pdf … |
| `fillTemplateSave` | Mall + fält → spara i NC |
| `compareVersionsPdf` | Diff-PDF |
| `extractToPayload` | Fält-JSON i msg |
| `createAssetLink` | assetUrl |
```
inject { ncPath: "/Dokument/avtal.docx" }
→ collabora-bridge (ncFileToPdf)
→ debug destNcPath
```
Efter bridge kan du koppla dina befintliga OCS-noder (Talk, Mail, dela länk): först PDF i `/Dokument/OfficeOut/`, sedan dela.
---
## Config: nc-collab-config
Skapas under kugghjul i Node-RED. Alla sex noder väljer samma config-instans.
| Fält | Exempel |
|------|---------|
| nextcloudUrl | `https://cloud.hannesahlin.se` |
| collaboraUrl | `https://172.17.0.2:9980` (bridge-IP, verifyTls=false) |
| collaboraPublicUrl | `https://cloud.hannesahlin.se` |
| username + app-lösenord | Nextcloud-inloggning |
IP för CODE detekteras vid `./install.sh` — se `.env.example`.
+95 -10
View File
@@ -2,16 +2,16 @@
{ {
"id": "collab_tab", "id": "collab_tab",
"type": "tab", "type": "tab",
"label": "NC Collabora — acceptans", "label": "NC Collabora — exempel",
"disabled": false, "disabled": false,
"info": "Version 1.0 — Hälsokoll + testkonvertering till /Dokument/OfficeOut/" "info": "Skapa nc-collab-config först (kugghjul). Byt FILL_IN_USER och app-lösenord.\n\n1. capabilities — CODE lever?\n2. ncFileToPdf — PDF i OfficeOut\n3. document:direct — editorUrl\n\nSe docs/NODES.md"
}, },
{ {
"id": "nc_collab_cfg", "id": "nc_collab_cfg",
"type": "nc-collab-config", "type": "nc-collab-config",
"name": "cloud.hannesahlin.se", "name": "cloud.hannesahlin.se",
"nextcloudUrl": "https://cloud.hannesahlin.se", "nextcloudUrl": "https://cloud.hannesahlin.se",
"collaboraUrl": "http://172.17.0.2:9980", "collaboraUrl": "https://172.17.0.2:9980",
"collaboraPublicUrl": "https://cloud.hannesahlin.se", "collaboraPublicUrl": "https://cloud.hannesahlin.se",
"username": "FILL_IN_USER", "username": "FILL_IN_USER",
"verifyTls": false "verifyTls": false
@@ -65,11 +65,6 @@
"p": "ncPath", "p": "ncPath",
"v": "/Dokument/test.docx", "v": "/Dokument/test.docx",
"vt": "str" "vt": "str"
},
{
"p": "destNcPath",
"v": "/Dokument/OfficeOut/test.pdf",
"vt": "str"
} }
], ],
"repeat": "", "repeat": "",
@@ -95,14 +90,104 @@
"id": "dbg_pdf", "id": "dbg_pdf",
"type": "debug", "type": "debug",
"z": "collab_tab", "z": "collab_tab",
"name": "destNcPath (inga hemligheter)", "name": "destNcPath",
"active": true, "active": true,
"tosidebar": true, "tosidebar": true,
"console": false, "console": false,
"tostatus": false, "tostatus": false,
"complete": "destNcPath", "complete": "destNcPath",
"x": 620, "x": 590,
"y": 160, "y": 160,
"wires": [] "wires": []
},
{
"id": "inj_editor",
"type": "inject",
"z": "collab_tab",
"name": "3. Öppna i Office",
"props": [
{
"p": "ncPath",
"v": "/Dokument/test.docx",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"topic": "",
"x": 150,
"y": 240,
"wires": [["office_direct"]]
},
{
"id": "office_direct",
"type": "nc-office",
"z": "collab_tab",
"name": "document:direct",
"config": "nc_collab_cfg",
"operation": "document:direct",
"x": 380,
"y": 240,
"wires": [["dbg_editor"]]
},
{
"id": "dbg_editor",
"type": "debug",
"z": "collab_tab",
"name": "editorUrl",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "editorUrl",
"x": 590,
"y": 240,
"wires": []
},
{
"id": "inj_extract",
"type": "inject",
"z": "collab_tab",
"name": "4. Fält i mall",
"props": [
{
"p": "ncPath",
"v": "/Mallar/avtal.docx",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"topic": "",
"x": 150,
"y": 320,
"wires": [["bridge_extract"]]
},
{
"id": "bridge_extract",
"type": "collabora-bridge",
"z": "collab_tab",
"name": "extractToPayload",
"config": "nc_collab_cfg",
"operation": "extractToPayload",
"x": 390,
"y": 320,
"wires": [["dbg_fields"]]
},
{
"id": "dbg_fields",
"type": "debug",
"z": "collab_tab",
"name": "fields / structure",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "fields",
"x": 610,
"y": 320,
"wires": []
} }
] ]
+29 -1
View File
@@ -4,15 +4,39 @@
# Standard: INSTALL_MODE=integrate (ingen ny container, ingen port 1881) # Standard: INSTALL_MODE=integrate (ingen ny container, ingen port 1881)
# Sidecar (endast om du uttryckligen vill): INSTALL_MODE=sidecar # Sidecar (endast om du uttryckligen vill): INSTALL_MODE=sidecar
# #
# Miljövariabler (valfria — .env i reporoten laddas automatiskt):
# NODERED_DIR Sökväg till befintlig nextcloud-node-red (auto-detekteras om tom)
# NODERED_CONTAINER Docker-namn, default nextcloud-node-red
# NODERED_PORT default 1880
# CODE_CONTAINER Docker-namn för Collabora CODE, default code
# COLLABORA_IP CODE:s bridge-IP (auto-detekteras om tom)
# NEXTCLOUD_URL t.ex. https://cloud.hannesahlin.se (hints i slutet)
# INSTALL_USER filägare vid chown, default ncadmin
# FORCE_REBUILD=1 docker compose build --no-cache
#
set -euo pipefail set -euo pipefail
VERSION="1.0.0" VERSION="1.0.0"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="${INSTALL_DIR:-$SCRIPT_DIR}" INSTALL_DIR="${INSTALL_DIR:-$SCRIPT_DIR}"
INSTALL_MODE="${INSTALL_MODE:-integrate}" INSTALL_MODE="${INSTALL_MODE:-integrate}"
# Ladda .env om den finns (inga hemligheter krävs här)
if [ -f "${INSTALL_DIR}/.env" ]; then
set -a
# shellcheck disable=SC1091
. "${INSTALL_DIR}/.env"
set +a
fi
NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}" NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}"
[ -n "${NODERED_DIR}" ] || NODERED_DIR="/home/ncadmin/nextcloud-node-red"
NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}"
NODERED_PORT="${NODERED_PORT:-1880}"
CODE_CONTAINER="${CODE_CONTAINER:-code}" CODE_CONTAINER="${CODE_CONTAINER:-code}"
COLLABORA_IP="${COLLABORA_IP:-172.17.0.2}" COLLABORA_IP="${COLLABORA_IP:-}"
NEXTCLOUD_URL="${NEXTCLOUD_URL:-https://cloud.hannesahlin.se}"
[ -n "${NEXTCLOUD_URL}" ] || NEXTCLOUD_URL="https://cloud.hannesahlin.se"
log() { printf '[install] %s\n' "$*"; } log() { printf '[install] %s\n' "$*"; }
die() { printf '[install] FEL: %s\n' "$*" >&2; exit 1; } die() { printf '[install] FEL: %s\n' "$*" >&2; exit 1; }
@@ -41,8 +65,12 @@ fi
chmod +x "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh" chmod +x "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh"
PKG_SRC="${INSTALL_DIR}" \ PKG_SRC="${INSTALL_DIR}" \
NODERED_DIR="${NODERED_DIR}" \ NODERED_DIR="${NODERED_DIR}" \
NODERED_CONTAINER="${NODERED_CONTAINER}" \
NODERED_PORT="${NODERED_PORT}" \
CODE_CONTAINER="${CODE_CONTAINER}" \ CODE_CONTAINER="${CODE_CONTAINER}" \
COLLABORA_IP="${COLLABORA_IP}" \ COLLABORA_IP="${COLLABORA_IP}" \
NEXTCLOUD_URL="${NEXTCLOUD_URL}" \
INSTALL_USER="${INSTALL_USER:-}" \
bash "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh" bash "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh"
log "Klart." log "Klart."
+24 -4
View File
@@ -1,7 +1,7 @@
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType('collabora-bridge', { RED.nodes.registerType('collabora-bridge', {
category: 'nextcloud collabora', category: 'nextcloud collabora',
color: '#e67e22', color: '#7950a2',
defaults: { defaults: {
name: { value: '' }, name: { value: '' },
config: { type: 'nc-collab-config', required: true }, config: { type: 'nc-collab-config', required: true },
@@ -41,7 +41,27 @@
</script> </script>
<script type="text/html" data-help-name="collabora-bridge"> <script type="text/html" data-help-name="collabora-bridge">
<p>Agent-pipelines: NC-fil → konvertering → WebDAV PUT under <code>/Dokument/OfficeOut/</code>.</p> <p><strong>Färdiga pipelines.</strong> Kedjar WebDAV + CODE + (ibland) OCS och skriver oftast tillbaka till Nextcloud. Det här är noden du når efter oftast.</p>
<p>Skriver aldrig över original. Sätt <code>msg.allowOverwrite=true</code> för annan destNcPath.</p> <p>Defaultmål: <code>/Dokument/OfficeOut/</code> om du inte sätter <code>destNcPath</code> / <code>destFolder</code> / <code>destName</code>.</p>
<p>Överstyr via <code>msg.operation</code>. Standardfält: <code>ncPath</code>, <code>destNcPath</code>, <code>format</code>, <code>fields</code>, <code>compareNcPath</code>.</p>
<table style="width:100%; font-size:11px;">
<tr><th>Operation</th><th>Resultat</th></tr>
<tr><td><code>ncFileToPdf</code></td><td>PDF i NC</td></tr>
<tr><td><code>ncFileToPng</code></td><td>Förhandsvisning PNG</td></tr>
<tr><td><code>ncFileToHtml</code></td><td>HTML i NC</td></tr>
<tr><td><code>htmlToOffice</code></td><td>HTML/text → docx/pdf …</td></tr>
<tr><td><code>fillTemplateSave</code></td><td>Fyll mall via OCS, spara i NC</td></tr>
<tr><td><code>compareVersionsPdf</code></td><td>Diff-PDF (ny + <code>compareNcPath</code>)</td></tr>
<tr><td><code>extractToPayload</code></td><td>JSON i <code>msg.fields</code> / <code>msg.structure</code></td></tr>
<tr><td><code>createAssetLink</code></td><td><code>msg.assetUrl</code> för infogning</td></tr>
</table>
<p>Överstyr via <code>msg.operation</code>. Skriver inte över original utan <code>msg.allowOverwrite=true</code>.</p>
<p>De andra noderna i paletten är byggstenar när bridge inte räcker.</p>
<pre>inject { ncPath: "/Dokument/avtal.docx" }
→ collabora-bridge (ncFileToPdf)
→ debug { destNcPath: "/Dokument/OfficeOut/avtal.pdf" }</pre>
<p><strong>Tumregel:</strong> PDF i Nextcloud → <code>ncFileToPdf</code>. Mall + spara → <code>fillTemplateSave</code>. Öppna i webbläsare → <code>nc-office document:direct</code>.</p>
</script> </script>
+23 -4
View File
@@ -1,7 +1,7 @@
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType('collabora-convert', { RED.nodes.registerType('collabora-convert', {
category: 'nextcloud collabora', category: 'nextcloud collabora',
color: '#0082c9', color: '#7950a2',
defaults: { defaults: {
name: { value: '' }, name: { value: '' },
config: { type: 'nc-collab-config', required: true }, config: { type: 'nc-collab-config', required: true },
@@ -42,7 +42,26 @@
</script> </script>
<script type="text/html" data-help-name="collabora-convert"> <script type="text/html" data-help-name="collabora-convert">
<p>Låg nivå: <code>/cool/convert-to</code> mot CODE.</p> <p><strong>Gör om filen till annat format.</strong> Skickar dokument till CODE och får tillbaka binär data (pdf, png, docx, odt, html, xlsx, pptx …). Sparar inte i Nextcloud — resultatet ligger i <code>msg.payload</code> som Buffer.</p>
<p>Ingång: <code>msg.ncPath</code> eller <code>msg.payload</code> (Buffer). Valfritt <code>msg.format</code>, <code>msg.templateNcPath</code>, <code>msg.compareNcPath</code>.</p>
<p>Utdata: <code>msg.payload</code> (Buffer). Sparar inte till Nextcloud — använd bridge eller WebDAV PUT efteråt.</p> <h4>Varifrån</h4>
<p>Filinnehåll, i ordning:</p>
<ol>
<li><code>msg.payload</code> om det redan är Buffer/text</li>
<li>annars WebDAV GET av <code>msg.ncPath</code></li>
</ol>
<p>Valfritt: <code>msg.templateNcPath</code> (mall), <code>msg.compareNcPath</code> (jämförelsefil).</p>
<h4>Vart</h4>
<p>POST multipart → <code>/cool/convert-to/&lt;format&gt;</code> på CODE. Fält: <code>data</code> = källfilen.</p>
<h4>Ut</h4>
<p><code>msg.payload</code>, <code>msg.filename</code>, <code>msg.format</code>, <code>msg.contentType</code>, <code>msg.statusCode</code></p>
<h4>När</h4>
<p>När du själv styr nästa steg: spara med WebDAV/OCS, mejla, Talk, eller skicka vidare. Vill du ha PDF i Nextcloud direkt — använd <code>collabora-bridge</code> (<code>ncFileToPdf</code>).</p>
<pre>inject { ncPath: "/Dokument/avtal.docx", format: "pdf" }
→ collabora-convert
→ debug (payload = PDF-bytes)</pre>
</script> </script>
+20 -3
View File
@@ -1,7 +1,7 @@
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType('collabora-extract', { RED.nodes.registerType('collabora-extract', {
category: 'nextcloud collabora', category: 'nextcloud collabora',
color: '#0082c9', color: '#7950a2',
defaults: { defaults: {
name: { value: '' }, name: { value: '' },
config: { type: 'nc-collab-config', required: true }, config: { type: 'nc-collab-config', required: true },
@@ -32,6 +32,23 @@
</script> </script>
<script type="text/html" data-help-name="collabora-extract"> <script type="text/html" data-help-name="collabora-extract">
<p><code>/cool/extract-document-structure</code></p> <p><strong>Lista vad som finns i dokumentet.</strong> Content controls, fält, ev. annan struktur beroende på filter. Returnerar JSON — ingen ny fil.</p>
<p>Ingång: <code>msg.ncPath</code> eller Buffer i <code>msg.payload</code>. Valfritt <code>msg.filter</code>.</p>
<h4>Varifrån</h4>
<p>Samma som convert: <code>msg.payload</code> eller WebDAV GET <code>msg.ncPath</code>.</p>
<p>Filter: dropdown eller <code>msg.filter</code>. Default <code>contentcontrol</code>.</p>
<h4>Vart</h4>
<p>POST multipart → <code>/cool/extract-document-structure</code></p>
<h4>Ut</h4>
<p><code>msg.payload</code> och <code>msg.structure</code> = struktur-JSON</p>
<h4>När</h4>
<p>Innan du fyller en mall. Du får fältnamnen (Kund, Datum …) så nästa nod vet vad den ska slå in.</p>
<pre>inject { ncPath: "/Mallar/avtal.docx" }
→ collabora-extract (filter: contentcontrol)
→ function (mappa data till fältnamn)
→ collabora-transform / nc-office / bridge fillTemplateSave</pre>
</script> </script>
+22 -3
View File
@@ -1,7 +1,7 @@
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType('collabora-transform', { RED.nodes.registerType('collabora-transform', {
category: 'nextcloud collabora', category: 'nextcloud collabora',
color: '#0082c9', color: '#7950a2',
defaults: { defaults: {
name: { value: '' }, name: { value: '' },
config: { type: 'nc-collab-config', required: true } config: { type: 'nc-collab-config', required: true }
@@ -27,6 +27,25 @@
</script> </script>
<script type="text/html" data-help-name="collabora-transform"> <script type="text/html" data-help-name="collabora-transform">
<p><code>/cool/transform-document-structure</code></p> <p><strong>Skriv in värden i dokumentet.</strong> Tar dokument + JSON med fält/transform och ber CODE fylla i. Resultat = ny dokument-binär, inte JSON.</p>
<p>Ingång: källa via <code>msg.ncPath</code> eller <code>msg.payload</code>, plus <code>msg.transform</code> (JSON).</p>
<h4>Varifrån</h4>
<ul>
<li>Dokument: <code>msg.payload</code> eller <code>msg.ncPath</code> (WebDAV)</li>
<li>Instruktion: <code>msg.transform</code> eller <code>msg.fields</code> — måste finnas</li>
</ul>
<h4>Vart</h4>
<p>POST multipart → <code>/cool/transform-document-structure</code>. Fält: <code>data</code> = filen, <code>transform</code> = JSON.</p>
<h4>Ut</h4>
<p><code>msg.payload</code> = ändrad fil (Buffer), plus <code>contentType</code></p>
<h4>När</h4>
<p>Fylla mall via CODE direkt, inte Nextclouds mall-API. Spara själv efteråt (WebDAV PUT / bridge / nc-office) om filen ska ligga i molnet.</p>
<pre>msg.ncPath = "/Mallar/avtal.docx"
msg.fields = { "Kund": "AB Exempel", "Datum": "2026-08-22" }
→ collabora-transform
→ (spara eller konvertera till PDF)</pre>
</script> </script>
+24 -3
View File
@@ -1,7 +1,7 @@
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType('collabora-wopi', { RED.nodes.registerType('collabora-wopi', {
category: 'nextcloud collabora', category: 'nextcloud collabora',
color: '#0082c9', color: '#7950a2',
defaults: { defaults: {
name: { value: '' }, name: { value: '' },
config: { type: 'nc-collab-config', required: true }, config: { type: 'nc-collab-config', required: true },
@@ -38,6 +38,27 @@
</script> </script>
<script type="text/html" data-help-name="collabora-wopi"> <script type="text/html" data-help-name="collabora-wopi">
<p>WOPI discovery/capabilities och editor-URL. Agenten ska nästan aldrig PutFile — använd WebDAV PUT.</p> <p>Inte filkonvertering — hälsokoll och WOPI-hjälp mot CODE.</p>
<p><code>buildEditor</code>: <code>msg.wopiSrc</code> + <code>msg.token</code> → <code>msg.editorUrl</code>.</p>
<table style="width:100%; font-size:12px;">
<tr><th>Operation</th><th>Du får</th></tr>
<tr><td><code>capabilities</code></td><td>JSON: vad CODE kan (convert-to m.m.)</td></tr>
<tr><td><code>discovery</code></td><td>XML: mime → editor-URL</td></tr>
<tr><td><code>buildEditor</code></td><td><code>msg.editorUrl</code> från <code>msg.wopiSrc</code> + <code>msg.token</code></td></tr>
<tr><td><code>checkFileInfo</code></td><td>JSON om filen (WOPI-host, oftast Nextcloud)</td></tr>
<tr><td><code>getFile</code></td><td>filbytes via WOPI GET</td></tr>
</table>
<p><code>buildEditor</code> sätter ungefär:<br>
<code>{collaboraPublicUrl}/browser/dist/cool.html?WOPISrc=...&amp;access_token=...</code><br>
Publik URL = Nextcloud/proxy (<code>https://cloud.hannesahlin.se</code>), inte intern CODE-IP.</p>
<h4>När</h4>
<ul>
<li>Första test att CODE lever → <code>capabilities</code></li>
<li>WOPI-token från <code>nc-office document:direct</code> → bygg iframe-URL</li>
<li>Felsökning. Spara filer via WebDAV, inte WOPI PutFile.</li>
</ul>
<pre>inject → collabora-wopi (capabilities) → debug</pre>
</script> </script>
+14 -4
View File
@@ -4,7 +4,7 @@
defaults: { defaults: {
name: { value: '' }, name: { value: '' },
nextcloudUrl: { value: 'https://cloud.hannesahlin.se', required: true }, nextcloudUrl: { value: 'https://cloud.hannesahlin.se', required: true },
collaboraUrl: { value: 'http://172.17.0.2:9980', required: true }, collaboraUrl: { value: 'https://172.17.0.2:9980', required: true },
collaboraPublicUrl: { value: 'https://cloud.hannesahlin.se' }, collaboraPublicUrl: { value: 'https://cloud.hannesahlin.se' },
username: { value: '', required: true }, username: { value: '', required: true },
verifyTls: { value: false } verifyTls: { value: false }
@@ -50,7 +50,17 @@
</script> </script>
<script type="text/html" data-help-name="nc-collab-config"> <script type="text/html" data-help-name="nc-collab-config">
<p>En instans per miljö. Använd <strong>app-lösenord</strong>, aldrig vanligt kontolösen.</p> <p>Config-nod — syns inte i paletten som flödesnod, men alla sex Collabora-noder behöver en sådan här.</p>
<p><code>collaboraUrl</code>: <code>http://172.17.0.2:9980</code> (CODE på Docker bridge). Host-loopback 127.0.0.1:9980 når sidecar inte.</p> <p>Utan config gör inget av dem något.</p>
<p><code>collaboraPublicUrl</code>: publik WOPI-värd, t.ex. <code>https://cloud.hannesahlin.se</code>.</p>
<h4>Två backender</h4>
<ul>
<li><strong>Nextcloud</strong> (<code>nextcloudUrl</code>) — filer via WebDAV + Office-API (OCS richdocuments). T.ex. <code>https://cloud.hannesahlin.se</code></li>
<li><strong>Collabora CODE</strong> (<code>collaboraUrl</code>) — konverteringsmotorn (<code>/cool/...</code>). Intern Docker bridge, t.ex. <code>https://172.17.0.2:9980</code>. IP hämtas vid install med <code>docker inspect</code> — hardkoda inte blint.</li>
</ul>
<p><strong>Auth:</strong> användarnamn + <em>app-lösenord</em>. Inte vanligt kontolösen.</p>
<p><code>collaboraPublicUrl</code> — vad webbläsaren ska se vid WOPI/editor-länkar (proxad CODE via Nextcloud). Intern IP funkar inte i iframe.</p>
<p><code>verifyTls</code> — stäng av mot intern CODE om cert inte matchar IP/host.</p>
<p>Standardutdata i bridge om du inte anger mål: <code>/Dokument/OfficeOut/</code></p>
</script> </script>
+21 -2
View File
@@ -1,7 +1,7 @@
<script type="text/javascript"> <script type="text/javascript">
RED.nodes.registerType('nc-office', { RED.nodes.registerType('nc-office', {
category: 'nextcloud collabora', category: 'nextcloud collabora',
color: '#46ba61', color: '#7950a2',
defaults: { defaults: {
name: { value: '' }, name: { value: '' },
config: { type: 'nc-collab-config', required: true }, config: { type: 'nc-collab-config', required: true },
@@ -41,6 +41,25 @@
</script> </script>
<script type="text/html" data-help-name="nc-office"> <script type="text/html" data-help-name="nc-office">
<p>Richdocuments OCS — mallar, fält, direkt-URL, assets.</p> <p><strong>Nextcloud Office-API.</strong> Trafik till Nextcloud OCS richdocuments — inte direkt till <code>/cool</code> (utom <code>files:convert</code> som internt kör WebDAV + CODE + WebDAV).</p>
<p>Bas: <code>.../ocs/v2.php/apps/richdocuments/api/v1/...</code></p>
<table style="width:100%; font-size:11px;">
<tr><th>Operation</th><th>Gör</th></tr>
<tr><td><code>templates:list</code></td><td>Lista mallar (ev. <code>templateType</code>)</td></tr>
<tr><td><code>templates:create</code></td><td>Ny fil från NC-mall</td></tr>
<tr><td><code>template:extractFields</code></td><td>Fält-JSON (som extract, via NC)</td></tr>
<tr><td><code>template:fillFields</code></td><td>Fyll mall, spara i NC</td></tr>
<tr><td><code>document:direct</code></td><td><code>editorUrl</code> — öppna fil i Office</td></tr>
<tr><td><code>document:public</code></td><td>Samma via <code>shareToken</code></td></tr>
<tr><td><code>files:convert</code></td><td>NC-fil → ny NC-fil (t.ex. PDF)</td></tr>
<tr><td><code>assets:create</code></td><td>Engångslänk för infogning i öppen editor</td></tr>
</table>
<p><code>fileId</code> kan saknas — slås upp med WebDAV PROPFIND från <code>ncPath</code>.</p>
<p>Överstyr via <code>msg.operation</code>. Gemensamma fält: <code>ncPath</code>, <code>fileId</code>, <code>destNcPath</code>, <code>fields</code>.</p> <p>Överstyr via <code>msg.operation</code>. Gemensamma fält: <code>ncPath</code>, <code>fileId</code>, <code>destNcPath</code>, <code>fields</code>.</p>
<pre>inject { ncPath: "/Dokument/avtal.docx" }
→ nc-office (document:direct)
→ debug (editorUrl)</pre>
</script> </script>
+69 -12
View File
@@ -9,7 +9,8 @@ NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}"
NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}" NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}"
NODERED_PORT="${NODERED_PORT:-1880}" NODERED_PORT="${NODERED_PORT:-1880}"
CODE_CONTAINER="${CODE_CONTAINER:-code}" CODE_CONTAINER="${CODE_CONTAINER:-code}"
COLLABORA_IP="${COLLABORA_IP:-172.17.0.2}" COLLABORA_IP="${COLLABORA_IP:-}"
NEXTCLOUD_URL="${NEXTCLOUD_URL:-https://cloud.hannesahlin.se}"
MARKER="nextcloud-collabora-nodered" MARKER="nextcloud-collabora-nodered"
log() { printf '[integrate] %s\n' "$*"; } log() { printf '[integrate] %s\n' "$*"; }
@@ -141,11 +142,66 @@ compose_run() {
run_as_root env DOCKER_BUILDKIT=1 ${compose} "$@" run_as_root env DOCKER_BUILDKIT=1 ${compose} "$@"
} }
code_bridge_ip() {
docker inspect -f '{{range $k,$v := .NetworkSettings.Networks}}{{if eq $k "bridge"}}{{$v.IPAddress}}{{end}}{{end}}' "${CODE_CONTAINER}" 2>/dev/null
}
detect_code_ip() {
local ip
ip="$(code_bridge_ip)"
if [ -n "${ip}" ]; then
COLLABORA_IP="${ip}"
log "CODE bridge-IP: ${COLLABORA_IP} (container ${CODE_CONTAINER})"
return 0
fi
if [ -n "${COLLABORA_IP}" ]; then
warn "Kunde inte läsa bridge-IP — använder COLLABORA_IP=${COLLABORA_IP}"
return 0
fi
die "CODE bridge-IP saknas — sätt COLLABORA_IP eller kontrollera att ${CODE_CONTAINER} kör på Docker bridge"
}
detect_nodered_dir() {
if [ -d "${NODERED_DIR}" ] && [ -f "${NODERED_DIR}/Dockerfile" ]; then
return 0
fi
local from_compose
from_compose="$(docker inspect -f '{{index .Config.Labels "com.docker.compose.project.working_dir"}}' "${NODERED_CONTAINER}" 2>/dev/null || true)"
if [ -n "${from_compose}" ] && [ -f "${from_compose}/Dockerfile" ]; then
NODERED_DIR="${from_compose}"
log "Node-RED-katalog från compose-label: ${NODERED_DIR}"
return 0
fi
for candidate in \
"/home/ncadmin/nextcloud-node-red" \
"/opt/nextcloud-node-red"; do
if [ -f "${candidate}/Dockerfile" ]; then
NODERED_DIR="${candidate}"
log "Node-RED-katalog hittad: ${NODERED_DIR}"
return 0
fi
done
die "NODERED_DIR saknas eller ogiltig — sätt sökväg till befintlig nextcloud-node-red (Dockerfile + entrypoint.sh)"
}
resolve_paths() { resolve_paths() {
if [ -f "${PKG_SRC}/.env" ]; then
set -a
# shellcheck disable=SC1091
. "${PKG_SRC}/.env"
set +a
fi
if [ "$(id -u)" -eq 0 ] && [ -d "/home/ncadmin/nextcloud-node-red" ]; then if [ "$(id -u)" -eq 0 ] && [ -d "/home/ncadmin/nextcloud-node-red" ]; then
NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}" NODERED_DIR="${NODERED_DIR:-/home/ncadmin/nextcloud-node-red}"
PKG_SRC="${PKG_SRC:-/home/ncadmin/nextcloud-collabora-nodered}" PKG_SRC="${PKG_SRC:-/home/ncadmin/nextcloud-collabora-nodered}"
fi fi
detect_nodered_dir
detect_code_ip
} }
stop_sidecar_if_any() { stop_sidecar_if_any() {
@@ -293,10 +349,6 @@ wait_nodered() {
warn "Node-RED svarade inte inom 60 s" warn "Node-RED svarade inte inom 60 s"
} }
code_bridge_ip() {
docker inspect -f '{{range $k,$v := .NetworkSettings.Networks}}{{if eq $k "bridge"}}{{$v.IPAddress}}{{end}}{{end}}' "${CODE_CONTAINER}" 2>/dev/null
}
verify_code_from_nodered() { verify_code_from_nodered() {
local code_ip local code_ip
code_ip="$(code_bridge_ip)" code_ip="$(code_bridge_ip)"
@@ -328,21 +380,26 @@ main() {
wait_nodered wait_nodered
verify_code_from_nodered verify_code_from_nodered
local host_ip local host_ip code_ip nc_url
host_ip="$(hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1")" host_ip="$(hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1")"
code_ip="$(code_bridge_ip)"
[ -n "${code_ip}" ] || code_ip="${COLLABORA_IP}"
nc_url="${NEXTCLOUD_URL:-https://cloud.hannesahlin.se}"
cat <<EOF cat <<EOF
Integrering klar — samma Node-RED på port ${NODERED_PORT} Integrering klar — samma Node-RED på port ${NODERED_PORT}
UI: http://${host_ip}:${NODERED_PORT} UI: http://${host_ip}:${NODERED_PORT}
Noder: nc-collab-config, collabora-bridge, nc-office, ... Noder: palett "nextcloud collabora" (6 st + config)
Nästa steg: Skapa config först (kugghjul → nc-collab-config):
1. nc-collab-config → app-lösenord, collaboraUrl=https://172.17.0.2:9980 (verifyTls=false) Nextcloud: ${nc_url}
2. Importera flows/example-flows.json från ${PKG_SRC} (valfritt) Collabora: https://${code_ip}:9980 (verifyTls=false)
3. Test: capabilities → ncFileToPdf Publik WOPI: ${nc_url}
Auth: användarnamn + app-lösenord
Ingen ny container skapad. odds-scraper orörd. Testa: collabora-wopi (capabilities) → collabora-bridge (ncFileToPdf)
Exempelflöde: flows/example-flows.json
EOF EOF
} }