diff --git a/.env.example b/.env.example
index 6277966..8c288c0 100644
--- a/.env.example
+++ b/.env.example
@@ -1,7 +1,23 @@
-# Genereras av bootstrap-install.sh eller manuellt
-NC_HOST=cloud.domain.name
-NC_HOST_IP=192.168.1.10
+# Miljövariabler för install.sh / integrate-into-nodered.sh
+# Kopiera till .env och justera per VM.
+
+# Nextcloud (visas i exempelflöden och dokumentation — påverkar inte själva nodkoden)
NEXTCLOUD_URL=https://cloud.domain.name
-COLLABORA_URL=http://172.17.0.2:9980
+NEXTCLOUD_PUBLIC_URL=https://cloud.domain.name
+
+# 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.domain.name
+NC_HOST_IP=
TZ=Europe/Stockholm
NODERED_CREDENTIAL_SECRET=byt-den-här-hemligheten-vid-produktion
diff --git a/README.md b/README.md
index f2c2e80..a0818e8 100644
--- a/README.md
+++ b/README.md
@@ -47,8 +47,31 @@ INSTALL_MODE=sidecar docker compose --profile sidecar up -d --build
## 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`
+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/ncdeploy/nextcloud-node-red` |
+| `CODE_CONTAINER` | `code` |
+| `COLLABORA_IP` | bridge-IP via `docker inspect` |
+| `NODERED_CONTAINER` | `nextcloud-node-red` |
+| `NODERED_PORT` | `1880` |
+
+```bash
+cd /home/ncdeploy/nextcloud-collabora-nodered
+cp .env.example .env # justera NEXTCLOUD_URL per VM
+git pull
+./install.sh # root/sudo för docker compose
+```
+
## Repo
https://git.domain.name/your-user/nextcloud-collabora-nodered
diff --git a/docs/NODES.md b/docs/NODES.md
new file mode 100644
index 0000000..5163290
--- /dev/null
+++ b/docs/NODES.md
@@ -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.domain.name` | 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.domain.name` |
+| collaboraUrl | `https://172.17.0.2:9980` (bridge-IP, verifyTls=false) |
+| collaboraPublicUrl | `https://cloud.domain.name` |
+| username + app-lösenord | Nextcloud-inloggning |
+
+IP för CODE detekteras vid `./install.sh` — se `.env.example`.
diff --git a/flows/example-flows.json b/flows/example-flows.json
index 29e3eec..e089e7b 100644
--- a/flows/example-flows.json
+++ b/flows/example-flows.json
@@ -2,16 +2,16 @@
{
"id": "collab_tab",
"type": "tab",
- "label": "NC Collabora — acceptans",
+ "label": "NC Collabora — exempel",
"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",
"type": "nc-collab-config",
"name": "cloud.domain.name",
"nextcloudUrl": "https://cloud.domain.name",
- "collaboraUrl": "http://172.17.0.2:9980",
+ "collaboraUrl": "https://172.17.0.2:9980",
"collaboraPublicUrl": "https://cloud.domain.name",
"username": "FILL_IN_USER",
"verifyTls": false
@@ -65,11 +65,6 @@
"p": "ncPath",
"v": "/Dokument/test.docx",
"vt": "str"
- },
- {
- "p": "destNcPath",
- "v": "/Dokument/OfficeOut/test.pdf",
- "vt": "str"
}
],
"repeat": "",
@@ -95,14 +90,104 @@
"id": "dbg_pdf",
"type": "debug",
"z": "collab_tab",
- "name": "destNcPath (inga hemligheter)",
+ "name": "destNcPath",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "destNcPath",
- "x": 620,
+ "x": 590,
"y": 160,
"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": []
}
]
diff --git a/install.sh b/install.sh
index b0d3f7c..f05c5c9 100755
--- a/install.sh
+++ b/install.sh
@@ -4,15 +4,39 @@
# Standard: INSTALL_MODE=integrate (ingen ny container, ingen port 1881)
# 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.domain.name (hints i slutet)
+# INSTALL_USER filägare vid chown, default ncdeploy
+# FORCE_REBUILD=1 docker compose build --no-cache
+#
set -euo pipefail
VERSION="1.0.0"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INSTALL_DIR="${INSTALL_DIR:-$SCRIPT_DIR}"
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/ncdeploy/nextcloud-node-red}"
+[ -n "${NODERED_DIR}" ] || NODERED_DIR="/home/ncdeploy/nextcloud-node-red"
+NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}"
+NODERED_PORT="${NODERED_PORT:-1880}"
CODE_CONTAINER="${CODE_CONTAINER:-code}"
-COLLABORA_IP="${COLLABORA_IP:-172.17.0.2}"
+COLLABORA_IP="${COLLABORA_IP:-}"
+NEXTCLOUD_URL="${NEXTCLOUD_URL:-https://cloud.domain.name}"
+[ -n "${NEXTCLOUD_URL}" ] || NEXTCLOUD_URL="https://cloud.domain.name"
log() { printf '[install] %s\n' "$*"; }
die() { printf '[install] FEL: %s\n' "$*" >&2; exit 1; }
@@ -41,8 +65,12 @@ fi
chmod +x "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh"
PKG_SRC="${INSTALL_DIR}" \
NODERED_DIR="${NODERED_DIR}" \
+ NODERED_CONTAINER="${NODERED_CONTAINER}" \
+ NODERED_PORT="${NODERED_PORT}" \
CODE_CONTAINER="${CODE_CONTAINER}" \
COLLABORA_IP="${COLLABORA_IP}" \
+ NEXTCLOUD_URL="${NEXTCLOUD_URL}" \
+ INSTALL_USER="${INSTALL_USER:-}" \
bash "${SCRIPT_DIR}/scripts/integrate-into-nodered.sh"
log "Klart."
diff --git a/nodes/collabora-bridge.html b/nodes/collabora-bridge.html
index 47d13f0..74fc670 100644
--- a/nodes/collabora-bridge.html
+++ b/nodes/collabora-bridge.html
@@ -1,7 +1,7 @@
diff --git a/nodes/collabora-convert.html b/nodes/collabora-convert.html
index 41e2b88..fb47aa6 100644
--- a/nodes/collabora-convert.html
+++ b/nodes/collabora-convert.html
@@ -1,7 +1,7 @@
diff --git a/nodes/collabora-extract.html b/nodes/collabora-extract.html
index 98c91ea..7cb616c 100644
--- a/nodes/collabora-extract.html
+++ b/nodes/collabora-extract.html
@@ -1,7 +1,7 @@
diff --git a/nodes/collabora-transform.html b/nodes/collabora-transform.html
index c90c58c..4695d39 100644
--- a/nodes/collabora-transform.html
+++ b/nodes/collabora-transform.html
@@ -1,7 +1,7 @@
diff --git a/nodes/collabora-wopi.html b/nodes/collabora-wopi.html
index c6bcaee..5ad7558 100644
--- a/nodes/collabora-wopi.html
+++ b/nodes/collabora-wopi.html
@@ -1,7 +1,7 @@
diff --git a/nodes/nc-collab-config.html b/nodes/nc-collab-config.html
index c687e2b..ba6cf2e 100644
--- a/nodes/nc-collab-config.html
+++ b/nodes/nc-collab-config.html
@@ -4,7 +4,7 @@
defaults: {
name: { value: '' },
nextcloudUrl: { value: 'https://cloud.domain.name', 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.domain.name' },
username: { value: '', required: true },
verifyTls: { value: false }
@@ -50,7 +50,17 @@
diff --git a/nodes/nc-office.html b/nodes/nc-office.html
index 1966ce7..f6a9f47 100644
--- a/nodes/nc-office.html
+++ b/nodes/nc-office.html
@@ -1,7 +1,7 @@
diff --git a/scripts/integrate-into-nodered.sh b/scripts/integrate-into-nodered.sh
index 58d65f8..b96b54b 100755
--- a/scripts/integrate-into-nodered.sh
+++ b/scripts/integrate-into-nodered.sh
@@ -9,7 +9,8 @@ NODERED_DIR="${NODERED_DIR:-/home/ncdeploy/nextcloud-node-red}"
NODERED_CONTAINER="${NODERED_CONTAINER:-nextcloud-node-red}"
NODERED_PORT="${NODERED_PORT:-1880}"
CODE_CONTAINER="${CODE_CONTAINER:-code}"
-COLLABORA_IP="${COLLABORA_IP:-172.17.0.2}"
+COLLABORA_IP="${COLLABORA_IP:-}"
+NEXTCLOUD_URL="${NEXTCLOUD_URL:-https://cloud.domain.name}"
MARKER="nextcloud-collabora-nodered"
log() { printf '[integrate] %s\n' "$*"; }
@@ -141,11 +142,66 @@ compose_run() {
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/ncdeploy/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() {
+ if [ -f "${PKG_SRC}/.env" ]; then
+ set -a
+ # shellcheck disable=SC1091
+ . "${PKG_SRC}/.env"
+ set +a
+ fi
+
if [ "$(id -u)" -eq 0 ] && [ -d "/home/ncdeploy/nextcloud-node-red" ]; then
NODERED_DIR="${NODERED_DIR:-/home/ncdeploy/nextcloud-node-red}"
PKG_SRC="${PKG_SRC:-/home/ncdeploy/nextcloud-collabora-nodered}"
fi
+
+ detect_nodered_dir
+ detect_code_ip
}
stop_sidecar_if_any() {
@@ -293,10 +349,6 @@ wait_nodered() {
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() {
local code_ip
code_ip="$(code_bridge_ip)"
@@ -328,21 +380,26 @@ main() {
wait_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")"
+ code_ip="$(code_bridge_ip)"
+ [ -n "${code_ip}" ] || code_ip="${COLLABORA_IP}"
+ nc_url="${NEXTCLOUD_URL:-https://cloud.domain.name}"
cat <