Kapitel 13/Tutorial.md aktualisiert
This commit is contained in:
@@ -354,16 +354,15 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
|
||||
- Dieser Node löst den Workflow regelmäßig aus.
|
||||
- Stelle ein: alle **10 Minuten** ausführen.
|
||||
|
||||
2. **HTTP Request – Twitch Videos abfragen** (Node-Name: `HTTP – Get Videos`)
|
||||
- Dieser Node ruft über die Twitch-API alle VODs deines Accounts ab.
|
||||
- URL:
|
||||
```
|
||||
https://api.twitch.tv/helix/videos?user_id=<DEINE_TWITCH_USER_ID>&type=archive
|
||||
```
|
||||
- Authentifizierung: OAuth2 (Credential „Twitch API“)
|
||||
- Header: `Client-Id: <DEINE_CLIENT_ID>`
|
||||
2. **HTTP Request – Get Videos** (Node-Name: `Get Twitch VOD IDs`)
|
||||
- **Node-Typ:** HTTP Request
|
||||
- **Methode:** GET
|
||||
- **URL:** `https://api.twitch.tv/helix/videos?user_id=<DEINE_TWITCH_USER_ID>&type=archive&first=20`
|
||||
- **Authentifizierung:** OAuth2 (Credential: *Twitch API*)
|
||||
- **Header:** Client-Id: <DEINE_CLIENT_ID>
|
||||
- **Response Format:** JSON **
|
||||
|
||||
3. **SSH Credentials in n8n anlegen**
|
||||
2.1 **SSH Credentials in n8n anlegen**
|
||||
- Damit n8n mit dem Clipper kommunizieren kann, brauchst du SSH-Zugangsdaten.
|
||||
- Trage in n8n ein:
|
||||
* Name: `SSH Clipper`
|
||||
@@ -373,6 +372,10 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
|
||||
* Private Key: Inhalt von `~/.ssh/id_n8n_clipper`
|
||||
* Working Directory: `/srv/clipper`
|
||||
|
||||
3. **Split Out – vods** (Node-Name: `Split Out – Twitch VOD`)
|
||||
- Node-Typ: Split Out
|
||||
- Field to Split Out: `data`
|
||||
|
||||
4. **SSH Node – State-Datei prüfen** (Node-Name: `SSH – Check State`)
|
||||
- Dieser Schritt prüft, ob die Datei `/srv/clipper/state/vod_seen.list` bereits existiert und ob VOD-IDs eingetragen sind.
|
||||
- Command (als Expression):
|
||||
@@ -386,37 +389,49 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
|
||||
{"file_exists":true,"non_empty":true,"vods":["123456789","987654321"]}
|
||||
```
|
||||
|
||||
5. **Set Node – Ergebnisse übernehmen** (Node-Name: `Set – State Ergebnis`)
|
||||
- Ziel: die Ausgabe aus dem vorherigen Schritt in Felder umwandeln, die n8n versteht.
|
||||
- Expressions:
|
||||
* file_exists → `{{ JSON.parse($json.stdout).file_exists }}`
|
||||
* non_empty → `{{ JSON.parse($json.stdout).non_empty }}`
|
||||
* vods → `{{ JSON.parse($json.stdout).vods }}`
|
||||
5. **Set – File Information** (Node-Name: `Set – File Information`)
|
||||
- Node-Typ: Set
|
||||
- Field: file_exists
|
||||
- Type: Boolean
|
||||
- Expression: `{{ JSON.parse($json.stdout).file_exists }}`
|
||||
- Field: non_empty
|
||||
- Type: Boolean
|
||||
- Expression: `{{ JSON.parse($json.stdout).non_empty }}`
|
||||
- Field: vods
|
||||
- Type: Array
|
||||
- Expression: `{{ JSON.parse($json.stdout).vods }} `
|
||||
- Add Option: Ignore Type Conversion Errors -> "ON"
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Hier nur die Expressions eintragen, keine Typ-Konvertierungen vornehmen.
|
||||
|
||||
6. **If-Node – Entscheidung** (Node-Name: `If – State Prüfung`)
|
||||
- Dieser Node entscheidet, ob neue VODs heruntergeladen werden müssen.
|
||||
- Bedingungen:
|
||||
6. **Set – vods in Array** (Node-Name: `Set – vods in Array`)
|
||||
- Node-Typ: Set
|
||||
- Field: vods
|
||||
- Type: Array
|
||||
- Expression:
|
||||
```js
|
||||
{{ (typeof $json.vods === 'string' ? $json.vods : String($json.vods))
|
||||
.split(',')
|
||||
.map(s => s.trim())
|
||||
.filter(Boolean) }}
|
||||
```
|
||||
1. Bedingung: {{ $json.file_exists }} is true (Boolean)
|
||||
2. Bedingung: {{ $json.non_empty }} is true (Boolean)
|
||||
Operator: AND
|
||||
```
|
||||
- Ergebnis: zwei mögliche Pfade → False = neu anlegen, True = prüfen auf neue VODs.
|
||||
|
||||
---
|
||||
7. **Split Out – vods** (Node-Name: `Split Out – vods`)
|
||||
- Node-Typ: Split Out
|
||||
- Field to Split Out: `vods`
|
||||
|
||||
7. **False-Pfad – VODs herunterladen und hochladen**
|
||||
8. **Vorbereitungen für VOD Download und Speicherung**
|
||||
|
||||
> [!NOTE]
|
||||
> Dieser Pfad läuft, wenn die State-Datei nicht existiert oder leer ist. Es werden alle VODs heruntergeladen und in Nextcloud hochgeladen.
|
||||
|
||||
**A. Vorbereitung (einmalig) – rclone an Nextcloud anbinden**
|
||||
**Ort:** Clipper-LXC Shell
|
||||
**8.1 Vorbereitung (einmalig) – rclone an Nextcloud anbinden**
|
||||
Ort: Clipper-LXC Shell
|
||||
Öffne hierzu in Proxmox, Putty, oder einer anderen Konsole den Clipper LXC und gebe die folgenden Befehele ein:
|
||||
```bash
|
||||
apt update && apt install -y rclone
|
||||
```
|
||||
Hiermit installieren wie rclone, was wir später für den Upload zu Nextcloud nutzen werden
|
||||
|
||||
Wechsel dann zu dem vorhin erstellten NUtzer (in diesem Tutorial Clipper) und erstelle eine WebDAV Anbindung an deine Nextcloud.
|
||||
Hierfür verwnedest du die folgenden Befehle:
|
||||
|
||||
```bash
|
||||
su - clipper
|
||||
rclone config create nc webdav \
|
||||
url=https://DEINE_DOMAIN/remote.php/dav/files/DEIN_BENUTZERNAME/ \
|
||||
@@ -425,15 +440,16 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
|
||||
pass=$(rclone obscure 'DEIN_APP_PASSWORT')
|
||||
rclone ls nc: --config /home/clipper/.config/rclone/rclone.conf
|
||||
```
|
||||
> [!NOTE]
|
||||
> Uploads laufen im Clipper mit rclone. Das ist robuster als Upload-Nodes in n8n, vermeidet Fehler und räumt lokale Dateien auf.
|
||||
|
||||
**B. Download/Upload Skript erstellen**
|
||||
**8.2 Download/Upload Skript erstellen**
|
||||
**Ort:** Clipper-LXC Shell
|
||||
|
||||
Noch immer in der Konsole des Clipper LXC verlässt du mit `exit` den User und bist wieder root User.
|
||||
Im Anschluss erstellst du eine neue Datei mit
|
||||
```bash
|
||||
nano <clipper-ordner>/bin/clipper-vod-get
|
||||
```
|
||||
Inhalt:
|
||||
Nun befüllst du sie mit:
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
@@ -512,7 +528,9 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
|
||||
|
||||
log "=== Done VOD $ID ==="
|
||||
```
|
||||
Rechte setzen:
|
||||
Mit diesem Skript laden wir die aktuellen VODs herunter, laden sie in die Nextcloud für die weitere Verabeitung und räumen wieder auf. Zusätzlich erzeugen wir logs in `<clipper-ordner>/logs/<ID>.log`.
|
||||
|
||||
Damit die Datei auch ausgeführt werden kann, musst du die folgenden zwei Befehle eingeben:
|
||||
```bash
|
||||
chmod 755 <clipper-ordner>/bin/clipper-vod-get
|
||||
chown clipper:clipper <clipper-ordner>/bin/clipper-vod-get
|
||||
@@ -520,48 +538,27 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
|
||||
> [!NOTE]
|
||||
> Pro VOD entsteht ein Logfile in `<clipper-ordner>/logs/<ID>.log`. Du kannst es live mit `tail -f <clipper-ordner>/logs/<ID>.log` verfolgen.
|
||||
|
||||
---
|
||||
|
||||
Mit diesem Aufbau ist der **False-Pfad** fertig: Wenn die State-Datei fehlt oder leer ist, werden alle VODs verarbeitet und in Nextcloud hochgeladen. Der True-Pfad folgt im nächsten Abschnitt.
|
||||
|
||||
**C. n8n‑Verkabelung (Überblick)**
|
||||
Ort: *n8n Weboberfläche*
|
||||
|
||||
**Verkabelung (Kurzüberblick):**
|
||||
1) HTTP Request →
|
||||
2) Split Out: → 3) Merge →
|
||||
4) Split In Batches →
|
||||
5) SSH Node 1 (State-Datei schreiben) →
|
||||
6) SSH Node 2 (Download & Upload)
|
||||
---
|
||||
|
||||
** Node-Einstellungen (1:1 in n8n eintragen)**
|
||||
**1) HTTP Request – Get Videos** -
|
||||
- **Node-Typ:** HTTP Request -
|
||||
- **Methode:** GET -
|
||||
- **URL:** `https://api.twitch.tv/helix/videos?user_id=<DEINE_TWITCH_USER_ID>&type=archive&first=20`
|
||||
- **Authentifizierung:** OAuth2 (Credential: *Twitch API*)
|
||||
- **Header:** Client-Id: <DEINE_CLIENT_ID>
|
||||
- **Response Format:** JSON **
|
||||
|
||||
2) Item Lists – Split Out**
|
||||
- **Node-Typ:** Split Out
|
||||
- **Field to Split Out:** data **
|
||||
|
||||
3) Merge – Combine**
|
||||
9. **Merge – Combine** (Node-Name: `Select VODs to Download`)
|
||||
- **Node-Typ:** Merge
|
||||
- **Mode:** Combine
|
||||
- **Combine Mode:** All Possible Combinations
|
||||
- **Eingang 1:** If False Ausgang
|
||||
- **Eingang 2:** Item Lists: Split Out
|
||||
- **Combine By:** Matching Fields
|
||||
- **Fields To Match Have Different Names**: "ON"
|
||||
- **Eingang 1:** Split Out – vods
|
||||
- **Eingang 2:** Split Out – Twitch VOD
|
||||
- **Input 1 Field**: vods
|
||||
- **Input 2 Field**: data.id
|
||||
- **Output Type**: Keep Non-Matches
|
||||
- **Output Data From**: Input 2
|
||||
Mit diesem Merge Node sorgen wir dafür, dass wir nur die VODs herunter laden, die neu sind und noch nicht von Clipper bearbeitet wurden.
|
||||
|
||||
**4) Split In Batches**
|
||||
10. **Split In Batches** (Node-Name: `Einzeldurchlauf`)
|
||||
- **Node-Typ:** Split In Batches
|
||||
- **Batch Size:** 1
|
||||
Dieser Node sorgt dafür, dass wenn mal mehr wie ein VOD heruntergaladen werden muss dies nicht parallel geschieht. S sparen wir Ressourcen und sind schneller mit der Arbeit fertig.
|
||||
|
||||
**5) SSH Node 1 – State-Datei schreiben**
|
||||
11. **SSH Node 1 – State-Datei schreiben** (Node-Name: `State Datei schreiben`)
|
||||
- **Node-Typ:** SSH
|
||||
- **Credentials:** *SSH Clipper* (User = clipper)
|
||||
- **Credentials:** *SSH Clipper*
|
||||
- **Operation:** Execute Command
|
||||
- **Command is an Expression:** **ON**
|
||||
- **Command:**
|
||||
@@ -569,108 +566,27 @@ In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**. Er sorgt d
|
||||
{{`set -euo pipefail; STATE="/srv/clipper/state/vod_seen.list"; mkdir -p "$(dirname "$STATE")"; if [ -s "$STATE" ]; then printf "%s\n" "${$json.data.id}" >> "$STATE"; else printf "%s\n" "${$json.data.id}" > "$STATE"; fi`}}
|
||||
```
|
||||
|
||||
**6) SSH Node 2 – Download & Upload (Skript)**
|
||||
12. **SSH Node 2 – Download & Upload** (Node-Name: `Down 'n' Up`)
|
||||
- **Node-Typ:** SSH
|
||||
- **Credentials:** *SSH Clipper* (User = clipper)
|
||||
- **Credentials:** *SSH Clipper*
|
||||
- **Operation:** Execute Command
|
||||
- **Command is an Expression:** **ON**
|
||||
- **Command:**
|
||||
```bash
|
||||
<clipper-ordner>/bin/clipper-vod-get "{{$('Merge').item.json.data.id}}" "{{ $json.url || ('https://www.twitch.tv/videos/' + $('Merge').item.json.data.id) }}"
|
||||
```
|
||||
Diese 11 Nodes werden das gesamte Grundgerüst der gesamten Automation sein. Wie aber müssen sie verbudnen werden?
|
||||
Das folgende Schaubild zeigt dir die konkrete Verkabelung
|
||||
|
||||
---
|
||||
**Ergebnis**
|
||||
- n8n steuert den gesamten Prozess, Upload erfolgt zuverlässig im Clipper via rclone.
|
||||
- Pro VOD entsteht **eine** MP4 in Nextcloud: <gewünschter Ordner>/VODs/<ID>/.
|
||||
- Pro VOD gibt es ein eigenes Logfileverzeichnis unter <clipper-ordner>/logs/<ID>/download.log.
|
||||
- Lokaler Speicher bleibt frei (automatisches Löschen nach Upload).
|
||||
- Logs der Schritte findest du im SSH‑Node‑Output und persistent im Logfile.
|
||||
|
||||
---
|
||||
|
||||
### Schritt 8: True-Pfad – Check und ggf. Download
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
> Der **False-Pfad** wurde bereits im vorherigen Abschnitt vollständig erklärt. Viele Nodes überschneiden sich mit dem True-Pfad. Damit du nicht alles doppelt anlegen musst, verweisen wir hier auf die bereits erstellten und konfigurierten Nodes.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
**Verkabelung (Kurzüberblick):**
|
||||
1) HTTP Request →
|
||||
2) Split Out →
|
||||
3) Set – vods in Array →
|
||||
4) Split Out Array →
|
||||
5) Merge →
|
||||
6) Split In Batches →
|
||||
7) SSH – Write State →
|
||||
8) SSH – Download VOD
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Node-Einstellungen (1:1 in n8n eintragen)
|
||||
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Die folgenden Nodes haben wir im vorherigen Schritt (False-Pfad) bereits erstellt und konfiguriert. Wenn du dem Tutorial bis hierhin gefolgt bist, musst du an diesen Nodes nichts mehr verändern:
|
||||
> - **HTTP Request – Get Videos**
|
||||
> - **Split Out – data**
|
||||
> - **Split In Batches**
|
||||
> - **SSH – Write State**
|
||||
> - **SSH – Download VOD**
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
**Neu im True-Pfad:**
|
||||
|
||||
|
||||
**3) Set – vods in Array** (Node-Name: `Set – vods in Array`)
|
||||
- Node-Typ: Set
|
||||
- Field: vods
|
||||
- Expression:
|
||||
```js
|
||||
{{ (typeof $json.vods === 'string' ? $json.vods : String($json.vods))
|
||||
.split(',')
|
||||
.map(s => s.trim())
|
||||
.filter(Boolean) }}
|
||||
```bash
|
||||
--- *SSH – Check State* --- *Set – File Information* --- *Set – vods in Array* --- *Split Out – vods* ------
|
||||
| |
|
||||
*Cron – Alle 10 Min* ---- | *Select VODs to Download* --- *Einzeldurchlauf* --- *State Datei schreiben* --- *Down 'n' Up* --- (Hier folgen später weitere Nodes, aber da der Einzeldurchlauf ein Loop ist wird der letzte Node mit Einzeldurchlauf verbunden)
|
||||
| |
|
||||
--- *Get Twitch VOD IDs* --- *Split Out* – *Twitch VOD* --------------------------------------------------
|
||||
```
|
||||
|
||||
|
||||
**4) Split Out – vods** (Node-Name: `Split Out – vods`)
|
||||
- Node-Typ: Split Out
|
||||
- Field to Split Out: vods
|
||||
|
||||
|
||||
**5) Merge – Combine** (Node-Name: `Merge – Combine`)
|
||||
- Node-Typ: Merge
|
||||
- Mode: Combine
|
||||
- Combine Mode: Matching Fields
|
||||
- Fields To Match Have Different Names: ON
|
||||
- Field 1: vods
|
||||
- Field 2: data.id
|
||||
- Output Type: Keep Non-Matches
|
||||
- Output Data From: Input 2
|
||||
- Eingang 1: Split Out Array VODs
|
||||
- Eingang 2: Split Out Twitch VODs
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
### Ergebnis
|
||||
- Es werden nur **neue VODs** heruntergeladen und hochgeladen.
|
||||
- Die State-Datei wird erweitert, ohne bestehende IDs zu überschreiben.
|
||||
- Logs bleiben konsistent, Doppel-Downloads werden vermieden.
|
||||
- Jeder Node ist eindeutig benannt, was die Übersicht verbessert.
|
||||
|
||||
---
|
||||
# 🧪 Abschnitt 4 – Analyse
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user