feat: Add Directus setup scripts for collections, fields, and relations
- Created setup-directus-collections.js to automate the creation of tech stack collections, fields, and relations in Directus. - Created setup-directus-hobbies.js for setting up hobbies collection with translations. - Created setup-directus-projects.js for establishing projects collection with comprehensive fields and translations. - Added setup-tech-stack-directus.js to populate tech_stack_items with predefined data.
This commit is contained in:
197
scripts/n8n-workflow-code-updated.js
Normal file
197
scripts/n8n-workflow-code-updated.js
Normal file
@@ -0,0 +1,197 @@
|
||||
// --------------------------------------------------------
|
||||
// DATEN AUS DEN VORHERIGEN NODES HOLEN
|
||||
// --------------------------------------------------------
|
||||
|
||||
// 1. Spotify Node
|
||||
let spotifyData = null;
|
||||
try {
|
||||
spotifyData = $('Spotify').first().json;
|
||||
} catch (e) {}
|
||||
|
||||
// 2. Lanyard Node (Discord)
|
||||
let lanyardData = null;
|
||||
try {
|
||||
lanyardData = $('Lanyard').first().json.data;
|
||||
} catch (e) {}
|
||||
|
||||
// 3. Wakapi Summary (Tages-Statistik)
|
||||
let wakapiStats = null;
|
||||
try {
|
||||
const wRaw = $('Wakapi').first().json;
|
||||
// Manchmal ist es direkt im Root, manchmal unter data
|
||||
wakapiStats = wRaw.grand_total ? wRaw : (wRaw.data ? wRaw.data : null);
|
||||
} catch (e) {}
|
||||
|
||||
// 4. Wakapi Heartbeats (Live Check)
|
||||
let heartbeatsList = [];
|
||||
try {
|
||||
const response = $('WakapiLast').last().json;
|
||||
if (response.data && Array.isArray(response.data)) {
|
||||
heartbeatsList = response.data;
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
// 5. Hardcover Reading (Neu!)
|
||||
let hardcoverData = null;
|
||||
try {
|
||||
// Falls du einen Node "Hardcover" hast
|
||||
hardcoverData = $('Hardcover').first().json;
|
||||
} catch (e) {}
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// LOGIK & FORMATIERUNG
|
||||
// --------------------------------------------------------
|
||||
|
||||
// --- A. SPOTIFY / MUSIC ---
|
||||
let music = null;
|
||||
|
||||
if (spotifyData && spotifyData.item && spotifyData.is_playing) {
|
||||
music = {
|
||||
isPlaying: true,
|
||||
track: spotifyData.item.name,
|
||||
artist: spotifyData.item.artists.map(a => a.name).join(', '),
|
||||
album: spotifyData.item.album.name,
|
||||
albumArt: spotifyData.item.album.images[0]?.url,
|
||||
url: spotifyData.item.external_urls.spotify
|
||||
};
|
||||
} else if (lanyardData?.listening_to_spotify && lanyardData.spotify) {
|
||||
music = {
|
||||
isPlaying: true,
|
||||
track: lanyardData.spotify.song,
|
||||
artist: lanyardData.spotify.artist.replace(/;/g, ", "),
|
||||
album: lanyardData.spotify.album,
|
||||
albumArt: lanyardData.spotify.album_art_url,
|
||||
url: `https://open.spotify.com/track/${lanyardData.spotify.track_id}`
|
||||
};
|
||||
}
|
||||
|
||||
// --- B. GAMING & STATUS ---
|
||||
let gaming = null;
|
||||
let status = {
|
||||
text: lanyardData?.discord_status || "offline",
|
||||
color: 'gray'
|
||||
};
|
||||
|
||||
// Farben mapping
|
||||
if (status.text === 'online') status.color = 'green';
|
||||
if (status.text === 'idle') status.color = 'yellow';
|
||||
if (status.text === 'dnd') status.color = 'red';
|
||||
|
||||
if (lanyardData?.activities) {
|
||||
lanyardData.activities.forEach(act => {
|
||||
// Type 0 = Game (Spotify ignorieren)
|
||||
if (act.type === 0 && act.name !== "Spotify") {
|
||||
let image = null;
|
||||
if (act.assets?.large_image) {
|
||||
if (act.assets.large_image.startsWith("mp:external")) {
|
||||
image = act.assets.large_image.replace(/mp:external\/([^\/]*)\/(https?)\/(^\/]*)\/(.*)/,"$2://$3/$4");
|
||||
} else {
|
||||
image = `https://cdn.discordapp.com/app-assets/${act.application_id}/${act.assets.large_image}.png`;
|
||||
}
|
||||
}
|
||||
gaming = {
|
||||
isPlaying: true,
|
||||
name: act.name,
|
||||
details: act.details,
|
||||
state: act.state,
|
||||
image: image
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// --- C. CODING (Wakapi Logic) ---
|
||||
let coding = null;
|
||||
|
||||
// 1. Basis-Stats von heute (Fallback)
|
||||
if (wakapiStats && wakapiStats.grand_total) {
|
||||
coding = {
|
||||
isActive: false,
|
||||
stats: {
|
||||
time: wakapiStats.grand_total.text,
|
||||
topLang: wakapiStats.languages?.[0]?.name || "Code",
|
||||
topProject: wakapiStats.projects?.[0]?.name || "Project"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 2. Live Check via Heartbeats
|
||||
if (heartbeatsList.length > 0) {
|
||||
const latestBeat = heartbeatsList[heartbeatsList.length - 1];
|
||||
|
||||
if (latestBeat && latestBeat.time) {
|
||||
const beatTime = new Date(latestBeat.time * 1000).getTime();
|
||||
const now = new Date().getTime();
|
||||
const diffMinutes = (now - beatTime) / 1000 / 60;
|
||||
|
||||
// Wenn jünger als 15 Minuten -> AKTIV
|
||||
if (diffMinutes < 15) {
|
||||
if (!coding) coding = { stats: { time: "Just started" } };
|
||||
|
||||
coding.isActive = true;
|
||||
coding.project = latestBeat.project || coding.stats?.topProject;
|
||||
|
||||
if (latestBeat.entity) {
|
||||
const parts = latestBeat.entity.split(/[/\\]/);
|
||||
coding.file = parts[parts.length - 1];
|
||||
}
|
||||
|
||||
coding.language = latestBeat.language;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- D. CUSTOM ACTIVITIES (Komplett dynamisch!) ---
|
||||
// Hier kannst du beliebige Activities hinzufügen ohne Website Code zu ändern
|
||||
let customActivities = {};
|
||||
|
||||
// Beispiel: Reading Activity (Hardcover Integration)
|
||||
if (hardcoverData && hardcoverData.user_book) {
|
||||
const book = hardcoverData.user_book;
|
||||
customActivities.reading = {
|
||||
enabled: true,
|
||||
title: book.book?.title,
|
||||
author: book.book?.contributions?.[0]?.author?.name,
|
||||
progress: book.progress_pages && book.book?.pages
|
||||
? Math.round((book.progress_pages / book.book.pages) * 100)
|
||||
: undefined,
|
||||
coverUrl: book.book?.image_url
|
||||
};
|
||||
}
|
||||
|
||||
// Beispiel: Manuell gesetzt via separatem Webhook
|
||||
// Du kannst einen Webhook erstellen der customActivities setzt:
|
||||
// POST /webhook/set-custom-activity
|
||||
// {
|
||||
// "type": "working_out",
|
||||
// "data": {
|
||||
// "enabled": true,
|
||||
// "activity": "Running",
|
||||
// "duration_minutes": 45,
|
||||
// "distance_km": 7.2,
|
||||
// "calories": 350
|
||||
// }
|
||||
// }
|
||||
// Dann hier einfach: customActivities.working_out = $('SetCustomActivity').first().json.data;
|
||||
|
||||
// WICHTIG: Du kannst auch mehrere Activities gleichzeitig haben!
|
||||
// customActivities.learning = { enabled: true, course: "Docker", platform: "Udemy", progress: 67 };
|
||||
// customActivities.streaming = { enabled: true, platform: "Twitch", viewers: 42 };
|
||||
// etc.
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// OUTPUT
|
||||
// --------------------------------------------------------
|
||||
return {
|
||||
json: {
|
||||
status,
|
||||
music,
|
||||
gaming,
|
||||
coding,
|
||||
customActivities, // NEU! Komplett dynamisch
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user