# ๐๏ธ Dynamic Activity Management - No Rebuild Required!
## รbersicht
Dieses System erlaubt dir, alle Aktivitรคten dynamisch zu steuern **ohne die Website neu zu bauen**. Alle รnderungen werden in Echtzeit รผber die Datenbank und n8n gesteuert.
---
## ๐ฏ Konzept: Zentrales Management
```
โโโโโโโโโโโโโโโโโโโ
โ n8n Dashboard โ โ Du steuerst hier alles
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ PostgreSQL โ โ Daten werden hier gespeichert
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ API Route โ โ Website liest alle 30s
โโโโโโโโโโฌโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ ActivityFeed UI โ โ Besucher sehen live updates
โโโโโโโโโโโโโโโโโโโ
```
**Vorteile:**
- โ
Keine Website-Rebuild notwendig
- โ
Echtzeit-Updates (30 Sekunden)
- โ
Volle Kontrolle via n8n
- โ
Historische Daten verfรผgbar
- โ
Multiple Steuerungsmรถglichkeiten
---
## ๐ฎ Management Optionen
### Option 1: n8n Dashboard UI โญ EMPFOHLEN
Erstelle ein simples n8n Workflow-Dashboard mit Webhook-Buttons:
**Workflow: "Activity Manager Dashboard"**
```json
{
"nodes": [
{
"name": "HTTP Server",
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "activity-dashboard",
"method": "GET",
"responseMode": "responseNode",
"options": {}
}
},
{
"name": "HTML Dashboard",
"type": "n8n-nodes-base.respondToWebhook",
"parameters": {
"responseBody": "=\n
\n Activity Manager\n \n\n\n ๐๏ธ Activity Manager
\n \n \n
๐ต Music Control
\n
Status: Auto-syncing from Spotify
\n
\n
\n\n \n
๐ป Coding Activity
\n \n \n \n \n \n \n\n \n
๐ฎ Gaming
\n \n \n \n \n \n\n \n
๐ Mood & Status
\n \n \n \n \n\n \n
๐ Manual Activities
\n \n \n \n \n \n\n \n
๐งน Quick Actions
\n \n \n \n \n\n \n\n"
}
}
]
}
```
**Zugriff:**
```
https://your-n8n-instance.com/webhook/activity-dashboard
```
---
### Option 2: Discord Bot Commands
Erstelle einen Discord Bot fรผr schnelle Updates:
**Commands:**
```
!status ๐ป Working on new features
!coding Portfolio Next.js
!music
!gaming Elden Ring
!clear
!afk
```
**n8n Workflow:**
```json
{
"nodes": [
{
"name": "Discord Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "discord-bot"
}
},
{
"name": "Parse Command",
"type": "n8n-nodes-base.function",
"parameters": {
"functionCode": "const message = items[0].json.content;\nconst [command, ...args] = message.split(' ');\n\nswitch(command) {\n case '!status':\n return [{\n json: {\n action: 'update_status',\n mood: args[0],\n message: args.slice(1).join(' ')\n }\n }];\n \n case '!coding':\n return [{\n json: {\n action: 'update_activity',\n type: 'coding',\n details: args.join(' ')\n }\n }];\n \n case '!clear':\n return [{\n json: { action: 'clear_all' }\n }];\n}\n\nreturn [{ json: {} }];"
}
},
{
"name": "Update Database",
"type": "n8n-nodes-base.postgres"
}
]
}
```
---
### Option 3: Mobile App / Shortcut
**iOS Shortcuts:**
```
1. "Start Coding" โ POST to n8n webhook
2. "Finished Work" โ Clear activity
3. "Set Mood" โ Update status
```
**Android Tasker:**
- Similar webhooks
- Location-based triggers
- Time-based automation
---
### Option 4: CLI Tool
Erstelle ein simples CLI Tool:
```bash
#!/bin/bash
# activity.sh
N8N_URL="https://your-n8n-instance.com"
case "$1" in
status)
curl -X POST "$N8N_URL/webhook/update-status" \
-H "Content-Type: application/json" \
-d "{\"mood\":\"$2\",\"message\":\"$3\"}"
;;
coding)
curl -X POST "$N8N_URL/webhook/update-activity" \
-H "Content-Type: application/json" \
-d "{\"type\":\"coding\",\"project\":\"$2\",\"language\":\"$3\"}"
;;
clear)
curl -X POST "$N8N_URL/webhook/clear-all"
;;
*)
echo "Usage: activity.sh [status|coding|clear] [args]"
;;
esac
```
**Usage:**
```bash
./activity.sh status ๐ป "Deep work mode"
./activity.sh coding "Portfolio" "TypeScript"
./activity.sh clear
```
---
## ๐ Automatische Sync-Workflows
### Musik geht weg wenn nicht mehr lรคuft
**n8n Workflow: "Spotify Auto-Clear"**
```json
{
"nodes": [
{
"name": "Check Every 30s",
"type": "n8n-nodes-base.cron",
"parameters": {
"cronExpression": "*/30 * * * * *"
}
},
{
"name": "Get Spotify Status",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.spotify.com/v1/me/player/currently-playing"
}
},
{
"name": "Check If Playing",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.is_playing}}",
"value2": false
}
]
}
}
},
{
"name": "Clear Music from Database",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "executeQuery",
"query": "UPDATE activity_status SET music_playing = FALSE, music_track = NULL, music_artist = NULL, music_album = NULL, music_album_art = NULL, music_progress = NULL WHERE id = 1"
}
}
]
}
```
### Auto-Clear nach Zeit
**n8n Workflow: "Activity Timeout"**
```javascript
// Function Node: Check Activity Age
const lastUpdate = new Date(items[0].json.updated_at);
const now = new Date();
const hoursSinceUpdate = (now - lastUpdate) / (1000 * 60 * 60);
// Clear activity if older than 2 hours
if (hoursSinceUpdate > 2) {
return [{
json: {
should_clear: true,
reason: `Activity too old (${hoursSinceUpdate.toFixed(1)} hours)`
}
}];
}
return [{ json: { should_clear: false } }];
```
### Smart Activity Detection
**Workflow: "Detect Coding from Git Commits"**
```javascript
// When you push to GitHub
const commit = items[0].json;
const repo = commit.repository.name;
const message = commit.head_commit.message;
// Detect language from files
const files = commit.head_commit.modified;
const language = files[0]?.split('.').pop(); // Get extension
return [{
json: {
activity_type: 'coding',
activity_details: message,
activity_project: repo,
activity_language: language,
activity_repo: commit.repository.html_url,
link: commit.head_commit.url
}
}];
```
---
## ๐ Activity Analytics Dashboard
**Workflow: "Activity History & Stats"**
Speichere Historie in separater Tabelle:
```sql
CREATE TABLE activity_history (
id SERIAL PRIMARY KEY,
activity_type VARCHAR(50),
details TEXT,
duration INTEGER, -- in minutes
started_at TIMESTAMP,
ended_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
-- View fรผr Statistiken
CREATE VIEW activity_stats AS
SELECT
activity_type,
COUNT(*) as count,
SUM(duration) as total_minutes,
AVG(duration) as avg_duration,
DATE(created_at) as date
FROM activity_history
GROUP BY activity_type, DATE(created_at)
ORDER BY date DESC;
```
**Dashboard Queries:**
```sql
-- Heute
SELECT * FROM activity_stats WHERE date = CURRENT_DATE;
-- Diese Woche
SELECT activity_type, SUM(total_minutes) as minutes
FROM activity_stats
WHERE date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY activity_type;
-- Most Coded Languages
SELECT activity_language, COUNT(*)
FROM activity_history
WHERE activity_type = 'coding'
GROUP BY activity_language
ORDER BY COUNT(*) DESC;
```
---
## ๐จ Custom Activity Types
Erweitere das System mit eigenen Activity-Types:
```sql
-- Add custom columns
ALTER TABLE activity_status
ADD COLUMN custom_activity_type VARCHAR(100),
ADD COLUMN custom_activity_data JSONB;
-- Example: Workout tracking
UPDATE activity_status SET
custom_activity_type = 'workout',
custom_activity_data = '{
"exercise": "Push-ups",
"reps": 50,
"icon": "๐ช",
"color": "orange"
}'::jsonb
WHERE id = 1;
```
**Frontend Support:**
```typescript
// In ActivityFeed.tsx
interface CustomActivity {
type: string;
data: {
icon: string;
color: string;
[key: string]: any;
};
}
// Render custom activities dynamically
if (data.customActivity) {
return (
{data.customActivity.data.icon}
{data.customActivity.type}
{/* Render data fields dynamically */}
);
}
```
---
## ๐ Security & Best Practices
### 1. Webhook Authentication
```javascript
// In n8n webhook
const secret = $credentials.webhookSecret;
const providedSecret = $node["Webhook"].json.headers["x-webhook-secret"];
if (secret !== providedSecret) {
return [{
json: { error: "Unauthorized" },
statusCode: 401
}];
}
```
### 2. Rate Limiting
```sql
-- Track requests
CREATE TABLE webhook_requests (
ip_address VARCHAR(45),
endpoint VARCHAR(100),
requested_at TIMESTAMP DEFAULT NOW()
);
-- Check rate limit (max 10 requests per minute)
SELECT COUNT(*) FROM webhook_requests
WHERE ip_address = $1
AND requested_at > NOW() - INTERVAL '1 minute';
```
### 3. Input Validation
```javascript
// In n8n Function node
const validateInput = (data) => {
if (!data.type || typeof data.type !== 'string') {
throw new Error('Invalid activity type');
}
if (data.type === 'coding' && !data.project) {
throw new Error('Project name required for coding activity');
}
return true;
};
```
---
## ๐ Quick Deploy Checklist
- [ ] Datenbank Table erstellt (`setup_activity_status.sql`)
- [ ] n8n Workflows importiert
- [ ] Spotify OAuth konfiguriert
- [ ] GitHub Webhooks eingerichtet
- [ ] Dashboard-URL getestet
- [ ] API Routes deployed
- [ ] Environment Variables gesetzt
- [ ] Frontend ActivityFeed getestet
- [ ] Auto-Clear Workflows aktiviert
---
## ๐ก Pro-Tipps
1. **Backup System**: Exportiere n8n Workflows regelmรครig
2. **Monitoring**: Setup alerts wenn Workflows fehlschlagen
3. **Testing**: Nutze n8n's Test-Modus vor Produktion
4. **Logging**: Speichere alle Aktivitรคten fรผr Analyse
5. **Fallbacks**: Zeige Placeholder wenn keine Daten vorhanden
---
## ๐ Quick Support Commands
```bash
# Check database status
psql -d portfolio_dev -c "SELECT * FROM activity_status WHERE id = 1;"
# Clear all activities
psql -d portfolio_dev -c "UPDATE activity_status SET activity_type = NULL, music_playing = FALSE WHERE id = 1;"
# View recent history
psql -d portfolio_dev -c "SELECT * FROM activity_history ORDER BY created_at DESC LIMIT 10;"
# Test n8n webhook
curl -X POST https://your-n8n.com/webhook/update-activity \
-H "Content-Type: application/json" \
-d '{"type":"coding","details":"Testing","project":"Portfolio"}'
```
---
Happy automating! ๐