812 lines
34 KiB
Markdown
812 lines
34 KiB
Markdown
# Kapitel 10 – n8n (Free)
|
||
|
||
## Einleitung
|
||
|
||
Mit dem Tool **n8n** (gesprochen: „n‑n“) führst du eine zentrale Komponente für Automatisierungen in dein UCC-System ein. Das Ziel ist, wiederkehrende Aufgaben wie Erinnerungen, Uploads oder Social-Media-Posts nicht manuell erledigen zu müssen – sondern automatisiert, nachvollziehbar und kontrolliert im Hintergrund ablaufen zu lassen.
|
||
|
||
n8n ist eine sogenannte Low-Code-Automatisierungsplattform. Du erstellst Abläufe („Workflows“) visuell, indem du vordefinierte Funktionen – sogenannte „Nodes“ – miteinander verbindest. Es gibt Nodes für Zeitpläne, HTTP-Requests, Datenbanken, Social Media, Kalender, E-Mail, Twitch, Discord und viele weitere Dienste. Gleichzeitig kannst du eigene JavaScript-Logik ergänzen, wenn du mehr Kontrolle brauchst.
|
||
|
||
Im Gegensatz zu externen Diensten wie Zapier, Make oder IFTTT läuft n8n vollständig lokal – in einem eigenen Container auf deinem Server. Das bedeutet:
|
||
|
||
- keine Daten verlassen dein Netzwerk,
|
||
- keine Anmeldung oder Drittanbieter-Abhängigkeit,
|
||
- keine Einschränkungen bei der Anpassung.
|
||
|
||
[!NOTE]
|
||
Wir verwenden in diesem Tutorial ausschließlich die kostenfreie **Community Edition** von n8n. Diese wird lokal installiert, läuft dauerhaft im eigenen Container und stellt alle für den Einstieg relevanten Funktionen bereit.
|
||
|
||
Dieses Kapitel behandelt ausschließlich die Grundlagen:
|
||
- Installation von n8n auf einem dedizierten Ubuntu-Container,
|
||
- Konfiguration und Start als systemweiter Dienst,
|
||
- Integration über Nginx Proxy Manager mit Subdomain und HTTPS,
|
||
- Erstellung eines ersten produktiven Workflows (Stream-Reminder + Social Post).
|
||
|
||
Das hier erstellte Setup bildet die technische Basis für spätere Erweiterungen, z. B. das automatische Auslesen von Twitch-Kalenderdaten (ICS-Dateien), das Erzeugen und Planen von Social-Media-Inhalten oder automatisierte Uploads in deine Nextcloud. Diese folgen im Premium-Kapitel.
|
||
|
||
Wie immer setzen wir kein technisches Vorwissen voraus. Alles, was du für dieses Kapitel brauchst, hast du in den vorherigen Schritten bereits eingerichtet: Proxmox, LXC, Proxy, Domain und grundlegende Netzwerkstruktur. Wenn du diesen Abschnitt erfolgreich abgeschlossen hast, kannst du erste Automatisierungen vollständig eigenständig umsetzen – mit deinem eigenen System und ohne Drittanbieter.
|
||
|
||
---
|
||
|
||
## Voraussetzungen & Ressourcen
|
||
|
||
Bevor du mit der Installation von n8n beginnst, solltest du sicherstellen, dass dein System korrekt vorbereitet ist. In diesem Abschnitt definieren wir die nötigen Ressourcen für den LXC-Container und klären, welche technischen Voraussetzungen erfüllt sein müssen, damit alle späteren Schritte funktionieren.
|
||
|
||
### Container-Ressourcen
|
||
|
||
Für den n8n-Container legen wir folgende Ausstattung fest:
|
||
|
||
* **CPU: 2 vCPUs**
|
||
Zwei virtuelle Prozessoren reichen für die Ausführung typischer n8n‑Workflows im Hintergrund.
|
||
Falls du später viele parallele Abläufe oder aufwendige API-Abfragen nutzen möchtest, kannst du die CPU-Zahl bei Bedarf erhöhen.
|
||
|
||
* **RAM: 2 GB**
|
||
Der Node.js-Prozess von n8n benötigt vergleichsweise wenig Arbeitsspeicher.
|
||
Mit 2 GB läuft das System auch bei mehreren gleichzeitig aktiven Workflows stabil.
|
||
Nur bei sehr großen Datenverarbeitungen (z. B. viele gleichzeitige Uploads oder komplexe Datenmanipulationen) kann mehr RAM sinnvoll sein.
|
||
|
||
* **Speicherplatz: 10 GB**
|
||
Dieser Platz reicht für die Grundinstallation, Logdateien und temporäre Workflow-Daten.
|
||
Da n8n keine großen Medien speichert, ist der Speicherbedarf überschaubar.
|
||
Wenn du viele eigene Skripte oder große JSON-Daten verarbeitest, kannst du den Container später vergrößern.
|
||
|
||
* **Betriebssystem: Ubuntu 24.04 LTS (64‑Bit)**
|
||
Wir setzen hier auf Ubuntu, da es moderne Pakete für Node.js bereitstellt und sich gut für die manuelle Installation eignet.
|
||
Zudem verwenden wir Node.js ≥ 18.x, was unter Ubuntu besonders gut unterstützt wird.
|
||
|
||
* **Netzwerk: Feste IP-Adresse per DHCP-Reservierung**
|
||
Wie in Kapitel 1 beschrieben, richtest du im Router eine DHCP-Reservierung für den Container ein.
|
||
So bleibt er immer unter derselben Adresse erreichbar und kann später korrekt im Proxy Manager eingebunden werden.
|
||
|
||
[!TIP]
|
||
Plane beim Erstellen des Containers genug Reserven ein – auch wenn n8n anfangs wenig verbraucht.
|
||
Gerade wenn du das System später für Uploads, VOD-Verarbeitung oder komplexe Kalenderanalysen nutzt, steigen RAM- und CPU-Anforderungen deutlich.
|
||
|
||
### Technische Voraussetzungen
|
||
|
||
Dieses Kapitel baut auf der bestehenden UCC-Grundstruktur auf. Folgende Komponenten solltest du bereits eingerichtet haben:
|
||
|
||
* **Proxmox läuft stabil** (Kapitel 1)
|
||
Der LXC-Container für n8n wird direkt dort erstellt und verwaltet.
|
||
|
||
* **Nginx Proxy Manager ist eingerichtet** (Kapitel 3)
|
||
Darüber wird n8n später mit Subdomain, HTTPS und Zertifikat erreichbar gemacht.
|
||
|
||
* **Domain oder DynDNS-Adresse ist vorhanden** (Kapitel 4)
|
||
Für die öffentliche Erreichbarkeit und Let's Encrypt brauchst du eine gültige Subdomain, z. B. `n8n.deinprojekt.de`.
|
||
|
||
* **Zugriff auf das Container-Terminal**
|
||
Du benötigst entweder direkten Zugriff über die Proxmox-Konsole oder per SSH auf den Container.
|
||
|
||
[!IMPORTANT]
|
||
Wenn du n8n nur im lokalen Netzwerk einsetzen möchtest, kannst du den Container auch ohne Domain und HTTPS betreiben. Die Anleitung funktioniert in diesem Fall ebenfalls – du musst später lediglich eigene Proxy-Regeln anpassen.
|
||
|
||
### Software und Versionen
|
||
|
||
In diesem Kapitel installierst du alle benötigten Komponenten manuell – ohne Docker, vollständig nachvollziehbar:
|
||
|
||
* **Node.js** – ab Version 18.x (erforderlich für aktuelle n8n-Releases)
|
||
* **npm** – Node Package Manager, wird automatisch mit Node.js installiert
|
||
* **n8n** – Automatisierungstool, wird systemweit per `npm install -g` eingerichtet
|
||
* **PM2** – Prozessmanager, sorgt für dauerhaften Hintergrundbetrieb und Autostart
|
||
|
||
Alle Schritte erfolgen in der richtigen Reihenfolge und mit ausführlichen Erklärungen – du brauchst keine Vorkenntnisse im Umgang mit Node.js oder JavaScript.
|
||
|
||
[!TIP]
|
||
Die direkte Installation ohne Docker erhöht die Transparenz. Du behältst volle Kontrolle über die Dateien, Logs und Prozesse – und kannst das System bei Bedarf gezielt sichern oder migrieren.
|
||
|
||
---
|
||
|
||
## Schritt 1 – Grundsystem aktualisieren
|
||
|
||
Bevor wir mit der Installation von n8n beginnen, sorgen wir dafür, dass das Betriebssystem im Container auf dem neuesten Stand ist.
|
||
Das ist wichtig, um Fehler durch veraltete Pakete zu vermeiden und eine stabile Grundlage für die weiteren Schritte zu schaffen.
|
||
|
||
Öffne dazu in Proxmox die **Shell** des n8n-Containers.
|
||
Wähle in der linken Seitenleiste den Container aus und klicke auf **Shell**.
|
||
|
||
👉 Screenshot geeignet: Proxmox – Container ausgewählt und Konsole geöffnet
|
||
|
||
Gib anschließend den folgenden Befehl ein, um alle Paketlisten zu aktualisieren und die verfügbaren Updates zu installieren.
|
||
Starte danach den Container neu, damit die Aktualisierungen aktiv werden:
|
||
|
||
```bash
|
||
apt update && apt upgrade -y
|
||
reboot
|
||
```
|
||
|
||
[!NOTE]
|
||
Führe diesen Schritt auch dann durch, wenn der Container gerade erst erstellt wurde.
|
||
Ein aktuelles Grundsystem verhindert spätere Konflikte bei der Installation von Node.js und n8n.
|
||
|
||
## Schritt 2 – Node.js & n8n installieren
|
||
|
||
Nach dem Update ist das System bereit für die Installation der benötigten Software.
|
||
n8n basiert auf Node.js, daher müssen wir zunächst Node.js und den zugehörigen Paketmanager **npm** einrichten.
|
||
Anschließend installieren wir n8n selbst sowie den Prozessmanager **PM2**, damit n8n dauerhaft im Hintergrund laufen kann.
|
||
|
||
### Benutzer wechseln
|
||
|
||
Wir installieren n8n nicht mit Administrator-Rechten, sondern unter einem eigenen Benutzerkonto.
|
||
Melde dich daher mit dem Benutzer an, den du in Schritt 1 erstellt hast:
|
||
|
||
```bash
|
||
su - n8nuser
|
||
```
|
||
|
||
👉 Screenshot geeignet: Konsole – Anmeldung als Benutzer `n8nuser`
|
||
|
||
### Node.js installieren
|
||
|
||
Zuerst fügen wir das offizielle NodeSource-Repository hinzu, um die aktuelle Version (mindestens 18.x) zu erhalten, und installieren dann Node.js und npm:
|
||
|
||
```bash
|
||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||
sudo apt install -y nodejs
|
||
```
|
||
|
||
Prüfe nach der Installation die Versionen:
|
||
|
||
```bash
|
||
node -v
|
||
npm -v
|
||
```
|
||
|
||
Die angezeigten Versionsnummern sollten mindestens `v18.x` für Node.js und eine aktuelle npm-Version zeigen.
|
||
|
||
[!NOTE]
|
||
Falls eine deutlich ältere Version angezeigt wird, wiederhole die Installation oder kontrolliere die Repository-Adresse.
|
||
|
||
### n8n und PM2 installieren
|
||
|
||
Installiere nun n8n und den Prozessmanager PM2 global über npm:
|
||
|
||
```bash
|
||
sudo npm install -g n8n pm2
|
||
```
|
||
|
||
Mit PM2 stellst du sicher, dass n8n auch nach einem Neustart automatisch startet.
|
||
|
||
Überprüfe anschließend, ob n8n korrekt installiert wurde:
|
||
|
||
```bash
|
||
n8n --version
|
||
```
|
||
|
||
Die Ausgabe zeigt die aktuell installierte n8n-Version an.
|
||
|
||
[!TIP]
|
||
PM2 sorgt dafür, dass n8n später automatisch als Hintergrunddienst läuft.
|
||
Die Konfiguration dafür nehmen wir im nächsten Schritt vor.
|
||
|
||
## Schritt 3 – n8n als Dienst einrichten und starten
|
||
|
||
Damit n8n nicht nur manuell über die Konsole gestartet werden kann, richten wir den automatischen Start mit **PM2** ein.
|
||
So läuft n8n dauerhaft im Hintergrund und wird bei jedem Neustart des Containers automatisch geladen.
|
||
|
||
### n8n erstmals starten
|
||
|
||
Starte n8n zunächst einmalig, um sicherzustellen, dass es fehlerfrei läuft:
|
||
|
||
```bash
|
||
n8n
|
||
```
|
||
|
||
Die Konsole zeigt nun Startmeldungen von n8n an und wartet anschließend auf Anfragen.
|
||
Beende den Prozess wieder mit der Tastenkombination `Strg + C`.
|
||
|
||
👉 Screenshot geeignet: Konsole – n8n erfolgreich gestartet und wartet auf Anfragen
|
||
|
||
### PM2 einrichten
|
||
|
||
Mit PM2 starten wir n8n als Hintergrundprozess:
|
||
|
||
```bash
|
||
pm2 start n8n
|
||
```
|
||
|
||
Damit n8n automatisch beim Systemstart geladen wird, registriere den PM2-Startdienst:
|
||
|
||
```bash
|
||
pm2 startup
|
||
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u n8nuser --hp /home/n8nuser
|
||
pm2 save
|
||
```
|
||
|
||
* `pm2 startup` zeigt den notwendigen Befehl für den Autostart an.
|
||
* Mit `pm2 save` speicherst du die aktuelle PM2-Prozessliste.
|
||
|
||
### Dienststatus prüfen
|
||
|
||
Überprüfe, ob n8n nun im Hintergrund läuft:
|
||
|
||
```bash
|
||
pm2 list
|
||
```
|
||
|
||
Die Ausgabe sollte den Prozess `n8n` mit dem Status **online** anzeigen.
|
||
|
||
[!NOTE]
|
||
Ab diesem Punkt läuft n8n automatisch im Hintergrund und wird bei jedem Neustart des Containers selbstständig gestartet.
|
||
|
||
## Schritt 4 – n8n im Nginx Proxy Manager einbinden
|
||
|
||
Öffne den **Nginx Proxy Manager** und lege einen neuen Proxy-Host für n8n an.
|
||
|
||
1) **Anmelden** im NPM-Dashboard
|
||
👉 Screenshot geeignet: NPM – Dashboard nach Login
|
||
|
||
2) Klicke auf **Add Proxy Host**
|
||
|
||
3) Trage im Reiter **Details** folgende Werte ein:
|
||
|
||
| Feld | Wert / Auswahl |
|
||
|--------------------------------|------------------------------------------|
|
||
| **Domain Names** | `n8n.deinedomain.tld` |
|
||
| **Scheme** | `http` |
|
||
| **Forward Hostname / IP** | IP-Adresse des n8n-Containers |
|
||
| **Forward Port** | `5678` |
|
||
| **Block Common Exploits** | aktivieren |
|
||
| **Websockets Support** | aktivieren |
|
||
|
||
👉 Screenshot geeignet: Formular „Add Proxy Host“ mit IP des n8n-Containers und Port 5678
|
||
|
||
4) Wechsle zu **SSL** und setze:
|
||
|
||
| Feld | Einstellung |
|
||
|-----------------------------------|----------------------------|
|
||
| **Request a new SSL Certificate** | aktivieren |
|
||
| **Force SSL** | aktivieren |
|
||
| **HTTP/2 Support** | aktivieren |
|
||
|
||
👉 Screenshot geeignet: SSL-Tab mit aktivierter Option „Force SSL“
|
||
|
||
5) Klicke **Save**, um den Proxy-Host anzulegen.
|
||
|
||
Nach wenigen Sekunden ist n8n über die gewählte Subdomain erreichbar, z. B.:
|
||
`https://n8n.deinedomain.tld`
|
||
|
||
👉 Screenshot geeignet: Browser – n8n-Anmeldeseite über die Subdomain aufgerufen
|
||
|
||
[!TIP]
|
||
Falls der Zugriff auch von außen möglich sein soll, muss im Router Port 443 auf den NPM-Host weitergeleitet werden.
|
||
|
||
## Schritt 5 – Vorbereitung: X-App und Credentials anlegen
|
||
|
||
In diesem Schritt richten wir die Verbindung zwischen **n8n** und **X (ehemals Twitter)** ein, damit später automatisch Beiträge gepostet werden können.
|
||
|
||
### 5.1 – X-Entwicklerkonto erstellen und Free-Plan aktivieren
|
||
1) Gehe zu [https://developer.x.com/](https://developer.x.com/) und melde dich mit deinem normalen X-Account an.
|
||
2) Öffne im linken Menü **Products → X API**.
|
||
3) Scrolle zu **API Tiers & Pricing** und wähle **Free**.
|
||
4) Klicke auf **„Sign Up for Free Account“** (der Button ist etwas unscheinbar).
|
||
5) Im Formular die **Use Cases** eintragen – mindestens 250 Zeichen.
|
||
Beispiel (englisch, ausreichend allgemein):
|
||
> We use the API to read and write posts programmatically in order to build community engagement and automate simple posting flows for our streams.
|
||
6) Alle Häkchen für die Bedingungen setzen und die Anmeldung abschließen.
|
||
|
||
👉 Screenshot geeignet: Developer-Portal mit ausgewähltem Free-Plan
|
||
|
||
[!NOTE]
|
||
Mit dem Free-Plan steht genau **eine App** zur Verfügung.
|
||
Dieser Plan erlaubt bis zu **500 Posts (Write) und 100 gelesene Posts (Read) pro Monat** – für Streaming-Ankündigungen reicht das in der Regel völlig aus.
|
||
|
||
### 5.2 – Überblick im Developer-Dashboard
|
||
Nach der Anmeldung erscheint im **Dashboard → Projects & Apps** automatisch ein erstes Projekt mit einer App.
|
||
|
||
👉 Screenshot geeignet: Dashboard mit Projekt-Kachel und Post-Limit-Anzeige
|
||
|
||
### 5.3 – Keys und Tokens vorbereiten
|
||
1) Klicke in der App-Kachel auf das **Zahnrad-Symbol → Keys and Tokens**.
|
||
2) Hier später **API Key & Secret** sowie **Bearer Token** generieren – diese brauchen wir gleich in n8n.
|
||
|
||
👉 Screenshot geeignet: Bereich „Keys and Tokens“ vor dem Generieren der Keys
|
||
|
||
[!WARNING]
|
||
Diese Schlüssel sind vertraulich und dürfen nicht öffentlich geteilt oder im Code abgelegt werden.
|
||
Speichere sie sicher ab.
|
||
|
||
### 5.4 – n8n-Credentials anlegen
|
||
1) Öffne in **n8n** das linke Menü **Credentials → + Neu**.
|
||
2) Wähle **„X OAuth 2.0 API“** als Typ.
|
||
3) Kopiere im geöffneten Fenster die angezeigte **OAuth Redirect URL** – diese wird gleich im Developer-Portal benötigt.
|
||
4) Lasse dieses Credentials-Fenster in n8n geöffnet.
|
||
|
||
👉 Screenshot geeignet: n8n – neues Credentials-Fenster mit sichtbarer Redirect-URL
|
||
|
||
[!TIP]
|
||
Die Redirect-URL immer aus dem geöffneten n8n-Fenster kopieren, nicht manuell eintippen.
|
||
|
||
### 5.5 – User-Authentication in X einrichten
|
||
1) Zurück im **Developer-Portal → Projects & Apps → App Details** wechseln.
|
||
2) Bei **User Authentication Settings** auf **„Set Up“** klicken.
|
||
3) **App Permissions:** „Read and Write“ auswählen.
|
||
4) **Type of App:** „Web App, Automated App or Bot“ auswählen.
|
||
5) Bei **Callback URL** die zuvor aus n8n kopierte Redirect-URL einfügen.
|
||
6) Bei **Homepage URL** die eigene Domain (z. B. `https://deinedomain.tld`) angeben.
|
||
7) **Save** klicken und die folgende Warnung bestätigen.
|
||
|
||
👉 Screenshot geeignet: Formular „User Authentication Settings“ mit ausgewählter Berechtigung „Read and Write“ und Callback-URL
|
||
|
||
[!IMPORTANT]
|
||
Falls die Berechtigung nicht auf „Read and Write“ steht, können später keine Posts veröffentlicht werden.
|
||
|
||
### 5.6 – Client-Daten in n8n eintragen und Account verknüpfen
|
||
1) Nach dem Speichern erscheinen im Developer-Portal **Client ID** und **Client Secret**.
|
||
2) Zurück in das noch geöffnete Credentials-Fenster in n8n wechseln.
|
||
3) **Client ID** und **Client Secret** dort eintragen.
|
||
4) Auf **„Account verknüpfen“** klicken.
|
||
5) Es öffnet sich ein Pop-up-Fenster mit der X-Login-Seite.
|
||
6) Mit dem normalen X-Konto anmelden und die App **autorisieren**.
|
||
|
||
[!WARNING]
|
||
Falls statt „Authorize App“ das X-Dashboard erscheint, das Fenster schließen und den Schritt „Account verknüpfen“ in n8n erneut ausführen.
|
||
|
||
👉 Screenshot geeignet: Pop-up mit X-Login und „Authorize App“
|
||
|
||
Damit sind die **X-Credentials** in n8n eingerichtet und einsatzbereit.
|
||
|
||
### 5.7 – Twitch-Auth-Credentials anlegen
|
||
|
||
Damit n8n die geplanten Streams abrufen kann, brauchen wir eine eigene **Twitch-Anwendung** mit User-Token (Authorization-Code-Flow).
|
||
Die benötigte **OAuth-Redirect-URL** kommt direkt aus n8n, deshalb beginnen wir dort.
|
||
|
||
#### 5.7.1 – Redirect-URL aus n8n kopieren
|
||
1) n8n öffnen → links **Credentials → + Neu**.
|
||
2) **„Twitch OAuth2 API“** als Typ auswählen.
|
||
3) Im sich öffnenden Fenster die angezeigte **OAuth Redirect URL** vollständig kopieren.
|
||
4) Fenster offenlassen, da wir gleich hierher zurückkehren.
|
||
|
||
👉 Screenshot geeignet: n8n – neues Twitch-Credential mit sichtbarer Redirect-URL
|
||
|
||
[!TIP]
|
||
Die Redirect-URL immer direkt aus n8n kopieren, nicht manuell eintippen – sonst schlägt die Authentifizierung fehl.
|
||
|
||
#### 5.7.2 – Neue Anwendung in der Twitch-Developer-Console anlegen
|
||
1) Twitch-Developer-Console öffnen: [https://dev.twitch.tv/console/apps](https://dev.twitch.tv/console/apps).
|
||
2) Mit dem Twitch-Konto anmelden, das später für die Streams genutzt wird.
|
||
3) Auf **„Register Your Application“** klicken
|
||
*(in der deutschen Oberfläche: **„Deine Anwendung registrieren“**).*
|
||
4) Einen aussagekräftigen Namen vergeben, z. B. `n8n-stream-schedule`.
|
||
5) Unter **OAuth Redirect URLs** die zuvor aus n8n kopierte URL einfügen.
|
||
6) Unter **Category** „Application Integration“ auswählen.
|
||
7) Bei **Public / Öffentlich** die Option **„Öffentlich“** aktivieren.
|
||
8) Auf **Create** klicken.
|
||
|
||
👉 Screenshot geeignet: Twitch-Developer-Console – Formular „Register Your Application / Deine Anwendung registrieren“ mit eingetragener Redirect-URL und aktivierter Option „Öffentlich“
|
||
|
||
[!IMPORTANT]
|
||
Die Redirect-URL muss exakt der aus n8n entsprechen, sonst schlägt die spätere Verknüpfung fehl.
|
||
|
||
#### 5.7.3 – Client-ID und Secret sichern
|
||
1) Nach dem Erstellen erscheint die Anwendung in der Übersicht.
|
||
2) Auf **Manage** klicken.
|
||
3) Die **Client ID** kopieren.
|
||
4) Über **New Secret** einen neuen **Client Secret** erzeugen und kopieren.
|
||
5) Beide Werte sicher speichern.
|
||
|
||
👉 Screenshot geeignet: Twitch-Developer-Console – App-Details mit sichtbarer Client ID und Button „New Secret“
|
||
|
||
[!WARNING]
|
||
Der Client Secret ist nur einmal sichtbar. Nicht öffentlich teilen und sicher aufbewahren.
|
||
|
||
#### 5.7.4 – Credential in n8n fertigstellen
|
||
1) Zurück zu n8n in das noch geöffnete Credential-Fenster wechseln.
|
||
2) Folgende Felder ausfüllen:
|
||
* **Client ID:** Wert aus der Twitch-Anwendung einfügen
|
||
* **Client Secret:** Wert aus der Twitch-Anwendung einfügen
|
||
* **Auth URL:** `https://id.twitch.tv/oauth2/authorize`
|
||
* **Access Token URL:** `https://id.twitch.tv/oauth2/token`
|
||
* **Grant Type:** `Authorization Code`
|
||
* **Scope:** `user:read:broadcast`
|
||
* **Auth URI Query Parameters:** leer lassen
|
||
* **Authentication:** `Body`
|
||
3) Auf **„Account verknüpfen“** klicken.
|
||
4) Im neuen Fenster mit dem Twitch-Konto anmelden und die Anwendung **autorisieren**.
|
||
5) Falls statt „Authorize App“ das Twitch-Dashboard erscheint, Fenster schließen und den Vorgang **„Account verknüpfen“** erneut ausführen.
|
||
|
||
👉 Screenshot geeignet: Twitch – OAuth-Freigabeseite mit „Authorize App“
|
||
|
||
[!NOTE]
|
||
Der Scope `user:read:broadcast` erlaubt n8n, die geplanten Streams des angegebenen Kanals über die Helix-API abzurufen.
|
||
|
||
### 5.8 – Hinweis zu Access Tokens
|
||
|
||
Mit den bisher eingerichteten **Credentials** für X und Twitch sind zwar die Schnittstellen verbunden, aber das reicht für den geplanten Workflow noch nicht aus.
|
||
Viele API-Endpunkte – insbesondere bei Twitch – benötigen zusätzlich einen **Access Token** (Bearer-Token) für jeden Abruf.
|
||
|
||
Zwar kann dieser Token theoretisch auch manuell über die Developer-Seiten erzeugt und in n8n eingetragen werden, doch solche Tokens laufen nach kurzer Zeit ab (bei Twitch z. B. meist nach 60 Tagen oder früher).
|
||
Ein händisches Nachtragen würde bedeuten, dass der Workflow regelmäßig ausfällt und manuell nachgepflegt werden muss.
|
||
|
||
[!IMPORTANT]
|
||
Wir werden deshalb im **Verlauf des Workflows** einen eigenen Node hinzufügen, der den Access Token automatisch anfordert und bei Bedarf erneuert.
|
||
So bleibt der Workflow stabil und benötigt keine manuelle Pflege.
|
||
|
||
## Schritt 6 – Workflow in n8n aufbauen
|
||
|
||
In diesem Schritt erstellen wir den eigentlichen Workflow in **n8n**.
|
||
Wir fügen die benötigten Nodes hinzu und konfigurieren sie so, dass der Workflow regelmäßig die geplanten Twitch-Streams prüft und bei Bedarf automatisch Ankündigungen auf X erstellt.
|
||
|
||
### 6.1 – Cron Trigger (Workflow alle 30 Minuten starten)
|
||
|
||
**Zweck:**
|
||
Der Cron-Trigger ist der Startpunkt des Workflows.
|
||
Er sorgt dafür, dass alle 30 Minuten geprüft wird, ob ein geplanter Stream in Kürze startet.
|
||
|
||
**Node-Typ:** `Schedule Trigger`
|
||
**Name:** `Cron – Workflow alle 30 Minuten starten`
|
||
|
||
**Einstellungen im Node:**
|
||
- **Trigger Interval:** `Minutes`
|
||
- **Minutes Between Triggers:** `30`
|
||
|
||
👉 Screenshot geeignet: n8n – Schedule Trigger mit „Trigger Interval: Minutes“ und Wert „30“
|
||
|
||
[!NOTE]
|
||
Die Zeitzone wird nicht im Node eingestellt.
|
||
Sie richtet sich nach der **Workflow-Zeitzone** (oben rechts im Workflow → *Settings → Time Zone*).
|
||
Ist dort nichts gesetzt, gilt die Zeitzone des Servers, auf dem n8n läuft.
|
||
|
||
[!TIP]
|
||
Die Intervalldauer (hier 30 Minuten) kann bei Bedarf angepasst werden. Für Ankündigungen kurz vor dem Stream reicht ein Intervall von 30 Minuten in der Regel aus.
|
||
|
||
### 6.2 – Code Node: Access Token prüfen
|
||
|
||
**Zweck:**
|
||
Dieser Node prüft bei jedem Durchlauf, ob bereits ein gültiger Twitch-Access-Token vorhanden ist und wie lange er noch gültig ist.
|
||
Wenn kein Token existiert oder die Restlaufzeit unter 24 Stunden liegt, markieren wir das für die nächste Stufe (Token erneuern).
|
||
|
||
**Node-Typ:** `Code`
|
||
**Programmiersprache:** `JavaScript`
|
||
**Name:** `Code – Access Token prüfen`
|
||
|
||
**Einstellungen:**
|
||
- **Language:** `JavaScript`
|
||
- Den folgenden Code einfügen:
|
||
|
||
```javascript
|
||
// Liest gespeicherten Token aus den globalen Workflow-Daten
|
||
const sd = $getWorkflowStaticData('global');
|
||
const token = sd.twitch_token || '';
|
||
const expISO = sd.twitch_expires_at || '';
|
||
const expMs = expISO ? new Date(expISO).getTime() : 0;
|
||
|
||
const now = Date.now();
|
||
const msLeft = expMs ? (expMs - now) : 0;
|
||
const hoursLeft = msLeft > 0 ? (msLeft / (1000*60*60)) : 0;
|
||
|
||
// true, wenn kein Token vorhanden ist oder wenn er in <24h abläuft
|
||
const needsRefresh = !token || !expMs || hoursLeft < 24;
|
||
|
||
return [{
|
||
json: {
|
||
needsRefresh,
|
||
token,
|
||
expires_at: expISO,
|
||
hoursLeft: Number(hoursLeft.toFixed(2))
|
||
}
|
||
}];
|
||
```
|
||
|
||
👉 Screenshot geeignet: n8n – Code-Node mit eingefügtem JavaScript-Code
|
||
|
||
[!NOTE]
|
||
Dieser Node speichert nichts, sondern liefert nur Statusdaten (`needsRefresh`, `hoursLeft`, `expires_at`).
|
||
Die tatsächliche Erneuerung des Tokens erfolgt später im Workflow.
|
||
|
||
### 6.3 – IF Node: Access Token erneuern?
|
||
|
||
**Zweck:**
|
||
Dieser Node prüft, ob aus dem vorherigen Code-Node das Flag `needsRefresh` auf **true** steht.
|
||
Nur in diesem Fall wird im nächsten Schritt ein neuer Access-Token angefordert.
|
||
|
||
**Node-Typ:** `IF`
|
||
**Name:** `IF – Access Token erneuern?`
|
||
|
||
**Einstellungen:**
|
||
- **Conditions:**
|
||
- `{{$json.needsRefresh}}`
|
||
- `is true` *(Type: Boolean)*
|
||
|
||
👉 Screenshot geeignet: n8n – IF-Node mit Bedingung `{{$json.needsRefresh}}` → `is true (Boolean)`
|
||
|
||
[!IMPORTANT]
|
||
Stelle sicher, dass der Vergleichs-Typ auf **Boolean** gesetzt ist, sonst wird der Wert eventuell als Text interpretiert und die Abfrage funktioniert nicht korrekt.
|
||
|
||
[!NOTE]
|
||
- **TRUE-Pfad:** Token wird im nächsten Schritt erneuert.
|
||
- **FALSE-Pfad:** Es wird mit dem bestehenden Token fortgefahren.
|
||
|
||
### 6.4 – HTTP Request: Neuen Twitch-Access-Token anfordern *(TRUE-Pfad)*
|
||
|
||
**Zweck:**
|
||
Fordert über die Twitch-API einen neuen Access-Token an, wenn der IF-Node festgestellt hat, dass keiner vorhanden ist oder der aktuelle bald abläuft.
|
||
|
||
**Node-Typ:** `HTTP Request`
|
||
**Name:** `HTTP – Access Token anfordern`
|
||
|
||
**Einstellungen:**
|
||
- **Method:** `POST`
|
||
- **URL:** `https://id.twitch.tv/oauth2/token`
|
||
- **Send Body:** aktivieren
|
||
- **Content Type:** `Form-URL-Encoded`
|
||
- **Body Parameters:**
|
||
- `client_id` → Wert aus den in n8n hinterlegten Twitch-Credentials
|
||
- `client_secret` → Wert aus den Twitch-Credentials
|
||
- `grant_type` → `client_credentials`
|
||
|
||
👉 Screenshot geeignet: n8n – HTTP-Request-Node mit konfigurierten Body-Parametern
|
||
|
||
[!NOTE]
|
||
Der Node gibt als Antwort ein JSON-Objekt mit `access_token` und `expires_in` zurück.
|
||
Diese Werte werden im nächsten Node gespeichert.
|
||
|
||
### 6.5 – Code Node: Neuen Access-Token speichern *(TRUE-Pfad)*
|
||
|
||
**Zweck:**
|
||
Speichert den vom HTTP-Request erhaltenen Twitch-Access-Token und dessen Ablaufzeitpunkt in den globalen Workflow-Daten.
|
||
So bleibt der Token auch für spätere Workflow-Durchläufe verfügbar.
|
||
|
||
**Node-Typ:** `Code`
|
||
**Programmiersprache:** `JavaScript`
|
||
**Name:** `Code – Access Token speichern`
|
||
|
||
**Einstellungen:**
|
||
- **Language:** `JavaScript`
|
||
- Den folgenden Code einfügen:
|
||
|
||
```javascript
|
||
// Speichert neuen Token + Ablaufzeit in Workflow-Static-Data
|
||
const sd = $getWorkflowStaticData('global');
|
||
|
||
const access = $json.access_token;
|
||
const ttlSec = Number($json.expires_in || 0);
|
||
|
||
// Ablaufzeitpunkt berechnen und speichern
|
||
const expISO = new Date(Date.now() + ttlSec * 1000).toISOString();
|
||
|
||
sd.twitch_token = access;
|
||
sd.twitch_expires_at = expISO;
|
||
|
||
// Optional: verbleibende Stunden ausgeben
|
||
const msLeft = (new Date(expISO).getTime() - Date.now());
|
||
const hoursLeft = msLeft / (1000 * 60 * 60);
|
||
|
||
return [{
|
||
json: {
|
||
token: access,
|
||
expires_at: expISO,
|
||
hoursLeft: Number(hoursLeft.toFixed(2))
|
||
}
|
||
}];
|
||
```
|
||
|
||
👉 Screenshot geeignet: n8n – Code-Node mit eingefügtem JavaScript-Code
|
||
|
||
[!NOTE]
|
||
Dieser Node speichert den neuen Token und gibt ihn zusätzlich mit seiner Restlaufzeit (`hoursLeft`) aus, sodass nachfolgende Nodes die Werte sofort verwenden können.
|
||
|
||
### 6.6 – Set Node: Token aus Cache bereitstellen *(FALSE-Pfad)*
|
||
|
||
**Zweck:**
|
||
Wenn der IF-Node feststellt, dass der vorhandene Token noch gültig ist, brauchen wir keinen neuen anzufordern.
|
||
Dieser Node liest die bereits gespeicherten Token-Daten aus den globalen Workflow-Daten und stellt sie den nachfolgenden Nodes zur Verfügung.
|
||
|
||
**Node-Typ:** `Set`
|
||
**Name:** `Set – Token aus Cache bereitstellen`
|
||
|
||
**Einstellungen:**
|
||
- **Mode:** `Add Field`
|
||
- **Felder hinzufügen:**
|
||
- `token` → `{{$json.token}}`
|
||
- `expires_at` → `{{$json.expires_at}}`
|
||
- `hoursLeft` → `{{$json.hoursLeft}}`
|
||
|
||
👉 Screenshot geeignet: n8n – Set-Node mit eingetragenen drei Feldern (token, expires_at, hoursLeft)
|
||
|
||
[!NOTE]
|
||
Der Set-Node wird nur im **FALSE-Pfad** des IF-Nodes ausgeführt.
|
||
Er sorgt dafür, dass auch ohne Erneuerung dieselben Felder (`token`, `expires_at`, `hoursLeft`) für die nächsten Schritte bereitstehen.
|
||
|
||
### 6.7 – Merge Node: Token-Ströme zusammenführen
|
||
|
||
**Zweck:**
|
||
Führt die beiden möglichen Pfade aus dem IF-Node wieder zusammen:
|
||
- TRUE-Pfad: liefert den **neu angeforderten Token** aus dem Code-Node „Access Token speichern“.
|
||
- FALSE-Pfad: liefert den **bereits vorhandenen Token** aus dem Set-Node „Token aus Cache bereitstellen“.
|
||
|
||
So steht dem Workflow anschließend unabhängig vom Pfad derselbe Datensatz für die weiteren Schritte zur Verfügung.
|
||
|
||
**Node-Typ:** `Merge`
|
||
**Name:** `Merge – Token zusammenführen`
|
||
|
||
**Einstellungen:**
|
||
- **Mode:** `Append`
|
||
- **Number of Inputs:** `2`
|
||
|
||
👉 Screenshot geeignet: n8n – Merge-Node mit „Mode: Append“ und „Number of Inputs: 2“
|
||
|
||
[!NOTE]
|
||
Da jeweils nur einer der beiden Pfade aktiv ist, genügt der Append-Modus, um den ausgegebenen Datensatz an den Hauptfluss zurückzugeben.
|
||
|
||
### 6.8 – HTTP Request: Twitch-Termine laden
|
||
|
||
**Zweck:**
|
||
Dieser Node ruft über die Twitch-Helix-API den aktuellen Stream-Zeitplan des Kanals ab, um zu prüfen, ob innerhalb der nächsten 30 Minuten ein Stream startet.
|
||
|
||
**Node-Typ:** `HTTP Request`
|
||
**Name:** `HTTP – Twitch-Termine laden`
|
||
|
||
#### Twitch-User-ID ermitteln (ohne Programmierung)
|
||
Die `broadcaster_id` ist eine **numerische ID**, die jedem Twitch-Kanal zugeordnet ist.
|
||
Du brauchst diese Zahl (nicht den Kanalnamen), um die API-Abfrage auszuführen.
|
||
|
||
**So findest du sie leicht:**
|
||
|
||
1) Öffne im Browser die Seite
|
||
[https://streamscharts.com/tools/convert-username](https://streamscharts.com/tools/convert-username)
|
||
2) Gib deinen Twitch-Kanalnamen ein (z. B. `bratonien_tv`).
|
||
3) Klicke auf **Convert**.
|
||
4) Die angezeigte Zahl unter „Channel ID“ ist deine `broadcaster_id`.
|
||
5) Kopiere diese Zahl und trage sie später im HTTP-Request-Node in das Feld **broadcaster_id** ein.
|
||
|
||
👉 Screenshot geeignet: StreamsCharts-Tool mit eingegebenem Kanalnamen und angezeigter Channel-ID
|
||
|
||
[!TIP]
|
||
Dieses Tool verwendet offiziell die Twitch-API, du brauchst dort keine eigenen Entwickler-Anmeldungen.
|
||
|
||
#### Einstellungen im Node
|
||
- **Method:** `GET`
|
||
- **URL:** `https://api.twitch.tv/helix/schedule`
|
||
- **Send Query:** aktivieren
|
||
- **Query Parameters:**
|
||
- `broadcaster_id` → `<Twitch-User-ID>` des Kanals
|
||
- `start_time` → `{{$now.toUTC().startOf('day').toISO()}}`
|
||
- **Send Headers:** aktivieren
|
||
- **Header Parameters:**
|
||
- `Authorization` → `Bearer {{$json.token}}`
|
||
- `Client-ID` → `<deine Client-ID aus Twitch-Credentials>`
|
||
|
||
👉 Screenshot geeignet: n8n – HTTP-Request-Node mit eingetragenen Query- und Header-Parametern
|
||
|
||
[!NOTE]
|
||
Die `broadcaster_id` ist die eindeutige numerische ID des Kanals.
|
||
Der Header **Authorization** enthält den Access-Token aus dem Merge-Node.
|
||
Der Header **Client-ID** ist zwingend erforderlich, sonst verweigert die Helix-API den Zugriff.
|
||
|
||
### 6.8 – HTTP Request: Twitch-Termine laden
|
||
|
||
**Zweck:**
|
||
Dieser Node ruft über die Twitch-Helix-API den aktuellen Stream-Zeitplan des Kanals ab, um zu prüfen, ob innerhalb der nächsten 30 Minuten ein Stream startet.
|
||
|
||
**Node-Typ:** `HTTP Request`
|
||
**Name:** `HTTP – Twitch-Termine laden`
|
||
|
||
#### Twitch-User-ID ermitteln (ohne Programmierung)
|
||
Die `broadcaster_id` ist eine **numerische ID**, die jedem Twitch-Kanal zugeordnet ist.
|
||
Du brauchst diese Zahl (nicht den Kanalnamen), um die API-Abfrage auszuführen.
|
||
|
||
**So findest du sie leicht:**
|
||
|
||
1) Öffne im Browser die Seite
|
||
[https://streamscharts.com/tools/convert-username](https://streamscharts.com/tools/convert-username)
|
||
2) Gib deinen Twitch-Kanalnamen ein (z. B. `bratonien_tv`).
|
||
3) Klicke auf **Convert**.
|
||
4) Die angezeigte Zahl unter „Channel ID“ ist deine `broadcaster_id`.
|
||
5) Kopiere diese Zahl und trage sie später im HTTP-Request-Node in das Feld **broadcaster_id** ein.
|
||
|
||
👉 Screenshot geeignet: StreamsCharts-Tool mit eingegebenem Kanalnamen und angezeigter Channel-ID
|
||
|
||
[!TIP]
|
||
Dieses Tool verwendet offiziell die Twitch-API und erfordert keine eigenen Entwickler-Anmeldungen.
|
||
|
||
#### Einstellungen im Node
|
||
- **Method:** `GET`
|
||
- **URL:** `https://api.twitch.tv/helix/schedule`
|
||
- **Authentication:** `Generic Credential Type`
|
||
- **Generic Auth Type:** `OAuth2 API` → wähle hier die zuvor in n8n angelegten **Twitch-Credentials** aus
|
||
- **Send Query Parameters:** aktivieren
|
||
- **Query Parameters:**
|
||
- **Name:** `broadcaster_id` → `<deine Twitch-User-ID>`
|
||
- **Name:** `start_time` → `{{ $now.toUTC().startOf('day').toISO() }}`
|
||
- **Send Headers:** aktivieren
|
||
- **Header Parameters:**
|
||
- **Name:** `Client-ID` → `<deine Client-ID aus den Twitch-Credentials>`
|
||
|
||
👉 Screenshot geeignet: n8n – HTTP-Request-Node mit allen sichtbaren Parametern wie auf den beiden Referenz-Screenshots
|
||
|
||
[!NOTE]
|
||
Der Access-Token wird über die ausgewählte OAuth2-Credential automatisch mitgesendet.
|
||
Zusätzlich ist nur der **Client-ID**-Header notwendig.
|
||
Die Option **Never Error** bleibt deaktiviert, da sie hier nicht benötigt wird.
|
||
|
||
### 6.9 – Code-Node: „Parse ICS“
|
||
|
||
**Zweck:**
|
||
Dieser Node verarbeitet die Antwort des Nodes **„Twitch-Termine laden“**.
|
||
Er liest das JSON aus der Helix-API und erzeugt für jedes Stream-Segment ein einheitliches Objekt mit Start- und Endzeit, Titel, Beschreibung und einer Hash-ID.
|
||
So können wir die Termine später leichter filtern und weiterverarbeiten.
|
||
|
||
**Node-Typ:** `Code`
|
||
**Name:** `Parse ICS`
|
||
|
||
👉 Screenshot geeignet: n8n – geöffneter Code-Node mit eingefügtem Skript
|
||
|
||
#### Node-Einstellungen
|
||
- **Programming Language:** `JavaScript`
|
||
- Weitere Einstellungen bleiben auf Standard.
|
||
|
||
#### Eingabe
|
||
Der Node erwartet die Antwort des HTTP-Requests **„Twitch-Termine laden“**.
|
||
Der Inhalt liegt meist als Text-String in `items[0].json.body` vor.
|
||
|
||
#### Code-Inhalt
|
||
Kopiere den folgenden Code komplett in das Editorfeld des Code-Nodes:
|
||
|
||
```
|
||
/**
|
||
* INPUT: items[0].json ODER items[0].json.body (String) vom HTTP Request /helix/schedule
|
||
* OUTPUT: pro Segment ein Item in folgendem Schema:
|
||
* { uid, cancelled, title, description, startIso, endIso, tz, hash }
|
||
*/
|
||
|
||
const input = items[0]?.json ?? {};
|
||
let payload;
|
||
|
||
if (typeof input.body === 'string') {
|
||
// HTTP-Node hat "Response Format: Text" -> JSON-String in body
|
||
try { payload = JSON.parse(input.body); }
|
||
catch (e) { throw new Error('HTTP body ist kein gültiges JSON'); }
|
||
} else if (input.data) {
|
||
// HTTP-Node hat "Response Format: JSON"
|
||
payload = input;
|
||
} else if (typeof input === 'string') {
|
||
payload = JSON.parse(input);
|
||
} else {
|
||
throw new Error('Unerwartete Eingabeform. Erwartet JSON oder body-String.');
|
||
}
|
||
|
||
const segments = Array.isArray(payload.data?.segments) ? payload.data.segments : [];
|
||
|
||
// Hash für eindeutige Segmentkennung
|
||
function hashHex(s) {
|
||
let h = 5381;
|
||
for (let i = 0; i < s.length; i++) h = ((h << 5) + h) ^ s.charCodeAt(i);
|
||
return (h >>> 0).toString(16).padStart(8, '0');
|
||
}
|
||
|
||
function buildTitle() { return 'Streamtime'; }
|
||
|
||
function buildDesc(seg) {
|
||
const lines = [];
|
||
if (seg.title) lines.push(`Originaltitel: ${seg.title}`);
|
||
if (seg.category?.name) lines.push(`Kategorie/Game: ${seg.category.name}`);
|
||
return lines.join('\n');
|
||
}
|
||
|
||
const tz = 'Europe/Berlin';
|
||
|
||
const out = segments.map(seg => {
|
||
const startIso = seg.start_time; // ISO-UTC laut Twitch
|
||
const endIso = seg.end_time;
|
||
const title = buildTitle();
|
||
const description = buildDesc(seg);
|
||
const hash = hashHex(`${title}|${startIso}|${endIso}|${description}`);
|
||
|
||
return {
|
||
json: {
|
||
uid: seg.id,
|
||
cancelled: Boolean(seg.canceled_until),
|
||
title, description,
|
||
startIso, endIso, tz,
|
||
hash
|
||
}
|
||
};
|
||
});
|
||
|
||
return out;
|
||
```
|
||
|
||
[!NOTE]
|
||
- `tz` ist fest auf `Europe/Berlin` gesetzt, kann aber bei Bedarf angepasst werden.
|
||
- Das Feld `cancelled` wird genutzt, um abgesagte Streams zu kennzeichnen.
|
||
- Jeder Stream-Eintrag erhält einen Hash, der später als eindeutiger Schlüssel dient. |