From 1257f8cff3173b2a8c25194e418c2de2e2105efb Mon Sep 17 00:00:00 2001 From: alma Date: Wed, 14 Jan 2026 11:15:51 +0100 Subject: [PATCH] Vision Refactor --- N8N_ROCKETCHAT_FIX.md | 98 ++++++++++++ app/vision/page.tsx | 307 ++++++++++++++++++++++++++++++++++-- test-n8n-curl-env.sh | 52 ++++++ test-n8n-curl-precise.sh | 37 +++++ test-n8n-curl.sh | 22 +++ test-n8n-inline.sh | 86 ++++++++++ test-n8n-python.py | 87 ++++++++++ test-n8n-simple-vm.sh | 45 ++++++ test-n8n-simple.sh | 39 +++++ test-n8n-vm.sh | 158 +++++++++++++++++++ test-n8n-webhook-direct.sh | 62 ++++++++ test-n8n-webhook-env.sh | 116 ++++++++++++++ test-n8n-webhook-precise.sh | 65 ++++++++ test-n8n-webhook.sh | 84 ++++++++++ 14 files changed, 1244 insertions(+), 14 deletions(-) create mode 100644 N8N_ROCKETCHAT_FIX.md create mode 100644 test-n8n-curl-env.sh create mode 100644 test-n8n-curl-precise.sh create mode 100644 test-n8n-curl.sh create mode 100644 test-n8n-inline.sh create mode 100644 test-n8n-python.py create mode 100644 test-n8n-simple-vm.sh create mode 100644 test-n8n-simple.sh create mode 100644 test-n8n-vm.sh create mode 100644 test-n8n-webhook-direct.sh create mode 100644 test-n8n-webhook-env.sh create mode 100644 test-n8n-webhook-precise.sh create mode 100644 test-n8n-webhook.sh diff --git a/N8N_ROCKETCHAT_FIX.md b/N8N_ROCKETCHAT_FIX.md new file mode 100644 index 0000000..5768aa8 --- /dev/null +++ b/N8N_ROCKETCHAT_FIX.md @@ -0,0 +1,98 @@ +# Correction N8N - RocketChat Channel ID + +## 🔍 Problème identifié + +D'après la réponse du webhook N8N, la structure de `rocketChatChannel` est : +```json +"rocketChatChannel": { + "id": "6966cbb6c8e9627bcb87daad", + "name": "seffirouuuuuu", + "exists": true, + "error": null +} +``` + +Mais dans le node **"Save Mission To API"**, le code cherche : +``` +$node['Combine Results'].json.rocketChatChannel?.channel?._id +``` + +Ce qui ne correspond pas à la structure réelle qui est `rocketChatChannel.id` (pas `rocketChatChannel.channel._id`). + +--- + +## ✅ Solution : Modifier dans N8N + +### Étape 1 : Ouvrir le workflow N8N + +1. Connectez-vous à N8N +2. Ouvrez le workflow qui gère la création de missions +3. Trouvez le node **"Save Mission To API"** + +### Étape 2 : Modifier le paramètre `rocketchatChannelId` + +Dans le node **"Save Mission To API"**, dans la section **Body Parameters**, trouvez le paramètre : + +**Nom** : `rocketchatChannelId` + +**Valeur actuelle (INCORRECTE)** : +``` +={{ $node['Combine Results'].json.rocketChatChannel?.channel?._id || '' }} +``` + +**Valeur à mettre (CORRECTE)** : +``` +={{ $node['Combine Results'].json.rocketChatChannel?.id || $node['Combine Results'].json.rocketChatChannel?.channel?._id || '' }} +``` + +Cette expression essaie d'abord `rocketChatChannel.id` (la structure réelle), puis fait un fallback sur `rocketChatChannel.channel._id` (ancienne structure) si la première n'existe pas. + +--- + +## 🔍 Vérification dans "Combine Results" + +Vérifiez aussi que le node **"Combine Results"** structure correctement les données. + +Dans le code JavaScript de "Combine Results", la ligne qui traite RocketChat devrait extraire l'ID correctement. Vérifiez que cette partie du code gère bien les deux structures : + +```javascript +// Process RocketChat channel result +if (rocketChatResult.error?.includes('error-duplicate-channel-name')) { + console.log('RocketChat channel already exists'); + rocketChatResult = { exists: true }; +} else if (rocketChatResult.body?.channel?._id) { + resourceStatus.rocketChatChannel = true; +} + +// ... + +// Dans la construction du résultat +rocketChatChannel: rocketChatResult.error ? { error: ... } : (rocketChatResult.body || rocketChatResult || {}) +``` + +Si la réponse de RocketChat est directement dans `rocketChatResult.body.channel._id`, alors `rocketChatResult.body` contiendra `{ channel: { _id: "..." } }`. + +Mais d'après votre réponse, il semble que "Combine Results" transforme déjà la structure en `{ id: "...", name: "...", exists: true }`. + +--- + +## 🧪 Test après modification + +Après avoir modifié le node "Save Mission To API", testez avec : + +```bash +./test-n8n-python.py [MISSION_ID] [PROJECT_NAME] +``` + +Vérifiez dans les logs Next.js que `rocketchatChannelId` est bien reçu avec la valeur `"6966cbb6c8e9627bcb87daad"` (ou l'ID réel du channel). + +--- + +## 📝 Résumé des changements + +**Node à modifier** : "Save Mission To API" +**Paramètre** : `rocketchatChannelId` +**Ancienne valeur** : `={{ $node['Combine Results'].json.rocketChatChannel?.channel?._id || '' }}` +**Nouvelle valeur** : `={{ $node['Combine Results'].json.rocketChatChannel?.id || $node['Combine Results'].json.rocketChatChannel?.channel?._id || '' }}` + +Cette modification permet de supporter les deux structures (ancienne et nouvelle) pour plus de robustesse. diff --git a/app/vision/page.tsx b/app/vision/page.tsx index 1f140f1..2b0fe10 100644 --- a/app/vision/page.tsx +++ b/app/vision/page.tsx @@ -1,26 +1,305 @@ -import { getServerSession } from "next-auth/next"; -import { authOptions } from "@/app/api/auth/options"; +"use client"; + +import { useState, useEffect } from "react"; +import { useSession } from "next-auth/react"; import { redirect } from "next/navigation"; import { ResponsiveIframe } from "@/app/components/responsive-iframe"; +import { Users, FolderKanban, Video, ArrowLeft, Loader2 } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { useToast } from "@/components/ui/use-toast"; -export default async function Page() { - const session = await getServerSession(authOptions); +interface Group { + id: string; + name: string; + path: string; +} - if (!session) { - redirect("/signin"); +interface Mission { + id: string; + name: string; + logoUrl?: string | null; +} + +type ConferenceType = "group" | "mission" | null; + +export default function VisionPage() { + const { data: session, status } = useSession(); + const { toast } = useToast(); + const [groups, setGroups] = useState([]); + const [missions, setMissions] = useState([]); + const [loading, setLoading] = useState(true); + const [selectedConference, setSelectedConference] = useState<{ + type: ConferenceType; + id: string; + name: string; + } | null>(null); + const [jitsiUrl, setJitsiUrl] = useState(null); + + // Redirect if not authenticated + useEffect(() => { + if (status === "unauthenticated") { + redirect("/signin"); + } + }, [status]); + + // Fetch user groups and missions + useEffect(() => { + const fetchData = async () => { + if (status !== "authenticated" || !session?.user?.id) { + return; + } + + try { + setLoading(true); + const userId = session.user.id; + + // Fetch user groups + const groupsRes = await fetch(`/api/users/${userId}/groups`); + if (groupsRes.ok) { + const groupsData = await groupsRes.json(); + setGroups(Array.isArray(groupsData) ? groupsData : []); + } else { + console.error("Failed to fetch groups"); + } + + // Fetch all missions and filter for user's missions + const missionsRes = await fetch("/api/missions?limit=1000"); + if (missionsRes.ok) { + const missionsData = await missionsRes.json(); + const allMissions = missionsData.missions || []; + + // Filter missions where user is creator or member + const userMissions = allMissions.filter((mission: any) => { + const isCreator = mission.creator?.id === userId; + const isMember = mission.missionUsers?.some( + (mu: any) => mu.user?.id === userId + ); + return isCreator || isMember; + }); + + setMissions(userMissions); + } else { + console.error("Failed to fetch missions"); + } + } catch (error) { + console.error("Error fetching data:", error); + toast({ + title: "Erreur", + description: "Impossible de charger les données", + variant: "destructive", + }); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [session, status, toast]); + + // Handle conference selection + const handleConferenceClick = (type: ConferenceType, id: string, name: string) => { + const baseUrl = process.env.NEXT_PUBLIC_IFRAME_CONFERENCE_URL || 'https://vision.slm-lab.net'; + + let url: string; + if (type === "group") { + // URL format: https://vision.slm-lab.net/Groupe-{groupId} + url = `${baseUrl}/Groupe-${id}`; + } else { + // URL format: https://vision.slm-lab.net/{missionId} + url = `${baseUrl}/${id}`; + } + + setSelectedConference({ type, id, name }); + setJitsiUrl(url); + }; + + // Handle back to list + const handleBack = () => { + setSelectedConference(null); + setJitsiUrl(null); + }; + + // Show loading state + if (status === "loading" || loading) { + return ( +
+
+ +

Chargement...

+
+
+ ); } - // URL Jitsi avec salle par défaut - const jitsiUrl = process.env.NEXT_PUBLIC_IFRAME_CONFERENCE_URL || 'https://vision.slm-lab.net/MonMeeting'; + // Show Jitsi iframe if conference is selected + if (selectedConference && jitsiUrl) { + return ( +
+ {/* Header with back button */} +
+ +
+

+ {selectedConference.type === "group" ? "Groupe" : "Mission"}: {selectedConference.name} +

+
+
+ + {/* Jitsi iframe */} +
+ +
+
+ ); + } + // Show list of groups and missions return ( -
+
- +
+ {/* Header */} +
+

+ Espaces de réunion +

+

+ Sélectionnez un groupe ou une mission pour accéder à son espace de réunion Jitsi +

+
+ + {/* Groups Section */} +
+
+ +

+ Groupes ({groups.length}) +

+
+ + {groups.length === 0 ? ( +
+ +

Aucun groupe disponible

+
+ ) : ( +
+ {groups.map((group) => ( +
handleConferenceClick("group", group.id, group.name)} + > +
+
+
+ +
+
+

+ {group.name} +

+

+ {group.path} +

+
+
+ +
+
+ ))} +
+ )} +
+ + {/* Missions Section */} +
+
+ +

+ Missions ({missions.length}) +

+
+ + {missions.length === 0 ? ( +
+ +

Aucune mission disponible

+
+ ) : ( +
+ {missions.map((mission) => ( +
handleConferenceClick("mission", mission.id, mission.name)} + > +
+
+ {mission.logoUrl ? ( +
+ {mission.name} { + (e.target as HTMLImageElement).style.display = 'none'; + }} + /> +
+ ) : ( +
+ +
+ )} +
+

+ {mission.name} +

+
+
+ +
+
+ ))} +
+ )} +
+
); -} \ No newline at end of file +} diff --git a/test-n8n-curl-env.sh b/test-n8n-curl-env.sh new file mode 100644 index 0000000..9b33ccc --- /dev/null +++ b/test-n8n-curl-env.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Curl simple utilisant les variables d'environnement +# Charge automatiquement .env.local si présent + +# Charger .env.local +if [ -f .env.local ]; then + export $(grep -v '^#' .env.local | xargs) +fi + +# Utiliser les variables d'environnement +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" +API_KEY="${N8N_API_KEY}" + +# Vérifier que l'API key est définie +if [ -z "$API_KEY" ]; then + echo "❌ Erreur: N8N_API_KEY n'est pas définie" + echo " Vérifiez votre fichier .env.local ou exportez N8N_API_KEY" + exit 1 +fi + +# Paramètres optionnels +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +ROCKETCHAT_CHANNEL_ID="${2:-ByehQjC44FwMeiLbX}" + +echo "🧪 Test webhook N8N" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "API URL: $API_URL" +echo "Mission ID: $MISSION_ID" +echo "RocketChat Channel ID: $ROCKETCHAT_CHANNEL_ID" +echo "" + +curl -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"name\": \"SEFFIR\", + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\", + \"gitRepoUrl\": \"\", + \"leantimeProjectId\": \"517\", + \"documentationCollectionId\": \"08919836-435a-466f-a38a-014991759da2\", + \"rocketchatChannelId\": \"${ROCKETCHAT_CHANNEL_ID}\", + \"donneurDOrdre\": \"group\", + \"projection\": \"long\", + \"missionType\": \"remote\", + \"niveau\": \"s\" + }" \ + -s | jq '.' + +echo "" +echo "✅ Test terminé" diff --git a/test-n8n-curl-precise.sh b/test-n8n-curl-precise.sh new file mode 100644 index 0000000..5e3b5e4 --- /dev/null +++ b/test-n8n-curl-precise.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Version curl simple et précise +# Charge .env.local automatiquement + +if [ -f .env.local ]; then + export $(grep -v '^#' .env.local | xargs) +fi + +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" + +curl -X POST "https://brain.slm-lab.net/webhook-test/mission-created" \ + -H "Content-Type: application/json" \ + -d "{ + \"name\": \"SEFFIR\", + \"oddScope\": [\"odd-4\"], + \"niveau\": \"s\", + \"intention\": \"\", + \"missionType\": \"remote\", + \"donneurDOrdre\": \"group\", + \"projection\": \"long\", + \"services\": [], + \"participation\": \"ouvert\", + \"profils\": [], + \"guardians\": {}, + \"volunteers\": [], + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\", + \"missionId\": \"${MISSION_ID}\", + \"logoPath\": \"missions/${MISSION_ID}/logo.png\", + \"logoUrl\": \"https://hub.slm-lab.net/api/missions/image/missions/${MISSION_ID}/logo.png\", + \"config\": { + \"N8N_API_KEY\": \"${N8N_API_KEY}\", + \"MISSION_API_URL\": \"${API_URL}\" + } + }" \ + -s | jq '.' diff --git a/test-n8n-curl.sh b/test-n8n-curl.sh new file mode 100644 index 0000000..d196ea2 --- /dev/null +++ b/test-n8n-curl.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Curl simple pour tester la sortie N8N +# Remplacez les valeurs entre <...> par vos vraies valeurs + +curl -X POST "https://hub.slm-lab.net/api/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: " \ + -d '{ + "missionId": "3103ec1a-acde-4025-9ead-4e1a0ddc047c", + "name": "SEFFIR", + "creatorId": "203cbc91-61ab-47a2-95d2-b5e1159327d7", + "gitRepoUrl": "", + "leantimeProjectId": "517", + "documentationCollectionId": "08919836-435a-466f-a38a-014991759da2", + "rocketchatChannelId": "ByehQjC44FwMeiLbX", + "donneurDOrdre": "group", + "projection": "long", + "missionType": "remote", + "niveau": "s" + }' \ + -v diff --git a/test-n8n-inline.sh b/test-n8n-inline.sh new file mode 100644 index 0000000..038aecf --- /dev/null +++ b/test-n8n-inline.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Version inline avec paramètres +# Usage: ./test-n8n-inline.sh [MISSION_ID] [PROJECT_NAME] + +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +PROJECT_NAME="${2:-SEFFIR}" + +python3 << EOF +import urllib.request +import json +import os +import sys + +# Charger .env.local +env_vars = {} +if os.path.exists('.env.local'): + with open('.env.local') as f: + for line in f: + if '=' in line and not line.strip().startswith('#'): + key, value = line.strip().split('=', 1) + env_vars[key] = value + +webhook_url = "https://brain.slm-lab.net/webhook-test/mission-created" +mission_id = "${MISSION_ID}" +project_name = "${PROJECT_NAME}" +api_key = env_vars.get('N8N_API_KEY', os.environ.get('N8N_API_KEY')) +api_url = env_vars.get('NEXT_PUBLIC_API_URL', os.environ.get('NEXT_PUBLIC_API_URL', 'https://hub.slm-lab.net/api')) + +if not api_key: + print("❌ Erreur: N8N_API_KEY n'est pas définie") + sys.exit(1) + +print(f"🧪 Test du webhook N8N") +print(f"Mission ID: {mission_id}") +print(f"Project Name: {project_name}") +print("") + +data = { + "name": project_name, + "oddScope": ["odd-4"], + "niveau": "s", + "intention": "", + "missionType": "remote", + "donneurDOrdre": "group", + "projection": "long", + "services": [], + "participation": "ouvert", + "profils": [], + "guardians": {}, + "volunteers": [], + "creatorId": "203cbc91-61ab-47a2-95d2-b5e1159327d7", + "missionId": mission_id, + "logoPath": f"missions/{mission_id}/logo.png", + "logoUrl": f"https://hub.slm-lab.net/api/missions/image/missions/{mission_id}/logo.png", + "config": { + "N8N_API_KEY": api_key, + "MISSION_API_URL": api_url + } +} + +req = urllib.request.Request( + webhook_url, + data=json.dumps(data).encode('utf-8'), + headers={'Content-Type': 'application/json'} +) + +try: + with urllib.request.urlopen(req) as response: + print(f"✅ Status: {response.status} {response.reason}") + print(f"📄 Réponse:") + response_data = json.loads(response.read().decode('utf-8')) + print(json.dumps(response_data, indent=2)) +except urllib.error.HTTPError as e: + print(f"❌ HTTP Error {e.code}: {e.reason}") + try: + error_body = e.read().decode('utf-8') + print(f"📄 Corps de l'erreur:") + print(json.dumps(json.loads(error_body), indent=2)) + except: + print(error_body) + sys.exit(1) +except Exception as e: + print(f"❌ Erreur: {e}") + sys.exit(1) +EOF diff --git a/test-n8n-python.py b/test-n8n-python.py new file mode 100644 index 0000000..67bb349 --- /dev/null +++ b/test-n8n-python.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +""" +Script pour tester le webhook N8N +Usage: python3 test-n8n-python.py [MISSION_ID] [PROJECT_NAME] +""" + +import urllib.request +import json +import os +import sys + +# Charger .env.local +env_vars = {} +if os.path.exists('.env.local'): + with open('.env.local') as f: + for line in f: + if '=' in line and not line.strip().startswith('#'): + key, value = line.strip().split('=', 1) + env_vars[key] = value + +# Paramètres depuis la ligne de commande ou variables d'environnement +mission_id = sys.argv[1] if len(sys.argv) > 1 else os.environ.get('MISSION_ID', '3103ec1a-acde-4025-9ead-4e1a0ddc047c') +project_name = sys.argv[2] if len(sys.argv) > 2 else os.environ.get('PROJECT_NAME', 'SEFFIR') + +webhook_url = "https://brain.slm-lab.net/webhook-test/mission-created" +api_key = env_vars.get('N8N_API_KEY', os.environ.get('N8N_API_KEY')) +api_url = env_vars.get('NEXT_PUBLIC_API_URL', os.environ.get('NEXT_PUBLIC_API_URL', 'https://hub.slm-lab.net/api')) + +if not api_key: + print("❌ Erreur: N8N_API_KEY n'est pas définie") + print(" Vérifiez votre fichier .env.local ou exportez N8N_API_KEY") + sys.exit(1) + +print(f"🧪 Test du webhook N8N") +print(f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") +print(f"Webhook URL: {webhook_url}") +print(f"Mission ID: {mission_id}") +print(f"Project Name: {project_name}") +print(f"") + +data = { + "name": project_name, + "oddScope": ["odd-4"], + "niveau": "s", + "intention": "", + "missionType": "remote", + "donneurDOrdre": "group", + "projection": "long", + "services": [], + "participation": "ouvert", + "profils": [], + "guardians": {}, + "volunteers": [], + "creatorId": "203cbc91-61ab-47a2-95d2-b5e1159327d7", + "missionId": mission_id, + "logoPath": f"missions/{mission_id}/logo.png", + "logoUrl": f"https://hub.slm-lab.net/api/missions/image/missions/{mission_id}/logo.png", + "config": { + "N8N_API_KEY": api_key, + "MISSION_API_URL": api_url + } +} + +req = urllib.request.Request( + webhook_url, + data=json.dumps(data).encode('utf-8'), + headers={'Content-Type': 'application/json'} +) + +try: + with urllib.request.urlopen(req) as response: + print(f"✅ Status: {response.status} {response.reason}") + print(f"📄 Réponse:") + response_data = json.loads(response.read().decode('utf-8')) + print(json.dumps(response_data, indent=2)) +except urllib.error.HTTPError as e: + print(f"❌ HTTP Error {e.code}: {e.reason}") + try: + error_body = e.read().decode('utf-8') + print(f"📄 Corps de l'erreur:") + print(json.dumps(json.loads(error_body), indent=2)) + except: + print(error_body) + sys.exit(1) +except Exception as e: + print(f"❌ Erreur: {e}") + sys.exit(1) diff --git a/test-n8n-simple-vm.sh b/test-n8n-simple-vm.sh new file mode 100644 index 0000000..beb8381 --- /dev/null +++ b/test-n8n-simple-vm.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# Version simple pour la VM - utilise curl si disponible +# Usage: ./test-n8n-simple-vm.sh [MISSION_ID] + +# Charger .env.local +if [ -f .env.local ]; then + export $(grep -v '^#' .env.local | xargs) +fi + +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" + +if [ -z "$N8N_API_KEY" ]; then + echo "❌ N8N_API_KEY non définie" + exit 1 +fi + +echo "🧪 Test webhook N8N: https://brain.slm-lab.net/webhook-test/mission-created" +echo "" + +curl -X POST "https://brain.slm-lab.net/webhook-test/mission-created" \ + -H "Content-Type: application/json" \ + -d "{ + \"name\": \"SEFFIR\", + \"oddScope\": [\"odd-4\"], + \"niveau\": \"s\", + \"missionType\": \"remote\", + \"donneurDOrdre\": \"group\", + \"projection\": \"long\", + \"services\": [], + \"participation\": \"ouvert\", + \"profils\": [], + \"guardians\": {}, + \"volunteers\": [], + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\", + \"missionId\": \"${MISSION_ID}\", + \"logoPath\": \"missions/${MISSION_ID}/logo.png\", + \"logoUrl\": \"https://hub.slm-lab.net/api/missions/image/missions/${MISSION_ID}/logo.png\", + \"config\": { + \"N8N_API_KEY\": \"${N8N_API_KEY}\", + \"MISSION_API_URL\": \"${API_URL}\" + } + }" \ + -s | python3 -m json.tool 2>/dev/null || cat diff --git a/test-n8n-simple.sh b/test-n8n-simple.sh new file mode 100644 index 0000000..a430d14 --- /dev/null +++ b/test-n8n-simple.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Version simple - charge .env.local automatiquement +# Usage: ./test-n8n-simple.sh [MISSION_ID] [ROCKETCHAT_CHANNEL_ID] + +# Charger .env.local +if [ -f .env.local ]; then + set -a + source .env.local + set +a +fi + +# Variables +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" +API_KEY="${N8N_API_KEY}" +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +ROCKETCHAT_CHANNEL_ID="${2:-ByehQjC44FwMeiLbX}" + +if [ -z "$API_KEY" ]; then + echo "❌ N8N_API_KEY non définie" + exit 1 +fi + +echo "🧪 Test avec RocketChat Channel ID: $ROCKETCHAT_CHANNEL_ID" +echo "" + +curl -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"name\": \"SEFFIR\", + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\", + \"gitRepoUrl\": \"\", + \"leantimeProjectId\": \"517\", + \"documentationCollectionId\": \"08919836-435a-466f-a38a-014991759da2\", + \"rocketchatChannelId\": \"${ROCKETCHAT_CHANNEL_ID}\" + }" \ + -s | jq '.' diff --git a/test-n8n-vm.sh b/test-n8n-vm.sh new file mode 100644 index 0000000..32e3933 --- /dev/null +++ b/test-n8n-vm.sh @@ -0,0 +1,158 @@ +#!/bin/bash + +# Script pour tester le webhook N8N depuis la VM +# Utilise les outils disponibles: curl, wget, python3, node + +# Charger .env.local si présent +if [ -f .env.local ]; then + export $(grep -v '^#' .env.local | xargs) +fi + +# Variables +WEBHOOK_URL="https://brain.slm-lab.net/webhook-test/mission-created" +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" +API_KEY="${N8N_API_KEY}" + +# Vérifier que l'API key est définie +if [ -z "$API_KEY" ]; then + echo "❌ Erreur: N8N_API_KEY n'est pas définie" + echo " Vérifiez votre fichier .env.local ou exportez N8N_API_KEY" + exit 1 +fi + +echo "🧪 Test du webhook N8N depuis la VM" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "Webhook URL: $WEBHOOK_URL" +echo "Mission ID: $MISSION_ID" +echo "API URL: $API_URL" +echo "" + +# Préparer le JSON +JSON_DATA=$(cat < /dev/null; then + echo "📤 Utilisation de curl..." + echo "" + curl -X POST "${WEBHOOK_URL}" \ + -H "Content-Type: application/json" \ + -d "$JSON_DATA" \ + -v +elif command -v wget &> /dev/null; then + echo "📤 Utilisation de wget..." + echo "" + echo "$JSON_DATA" | wget --method=POST \ + --header="Content-Type: application/json" \ + --body-data=- \ + --output-document=- \ + --server-response \ + "${WEBHOOK_URL}" 2>&1 +elif command -v python3 &> /dev/null; then + echo "📤 Utilisation de python3..." + echo "" + python3 < /dev/null; then + echo "📤 Utilisation de node..." + echo "" + node < { + console.log(\`Status: \${res.statusCode} \${res.statusMessage}\`); + console.log(\`Headers:\`, res.headers); + console.log(\`\nResponse Body:\`); + + let body = ''; + res.on('data', (chunk) => { body += chunk; }); + res.on('end', () => { + try { + console.log(JSON.stringify(JSON.parse(body), null, 2)); + } catch (e) { + console.log(body); + } + }); +}); + +req.on('error', (e) => { + console.error(\`Erreur: \${e.message}\`); + process.exit(1); +}); + +req.write(JSON.stringify(data)); +req.end(); +NODE_SCRIPT +else + echo "❌ Aucun outil disponible (curl, wget, python3, node)" + exit 1 +fi + +echo "" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "✅ Test terminé" +echo "" +echo "💡 Vérifiez les logs N8N pour voir la structure de la réponse RocketChat" diff --git a/test-n8n-webhook-direct.sh b/test-n8n-webhook-direct.sh new file mode 100644 index 0000000..f1ccb3c --- /dev/null +++ b/test-n8n-webhook-direct.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# Test direct du webhook N8N +# Usage: ./test-n8n-webhook-direct.sh [MISSION_ID] [ROCKETCHAT_CHANNEL_ID] + +# Charger .env.local si présent +if [ -f .env.local ]; then + export $(grep -v '^#' .env.local | xargs) +fi + +# URL du webhook N8N +WEBHOOK_URL="https://brain.slm-lab.net/webhook-test/mission-created" + +# Paramètres optionnels +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +ROCKETCHAT_CHANNEL_ID="${2:-ByehQjC44FwMeiLbX}" + +echo "🧪 Test du webhook N8N directement" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "Webhook URL: $WEBHOOK_URL" +echo "Mission ID: $MISSION_ID" +echo "RocketChat Channel ID: $ROCKETCHAT_CHANNEL_ID" +echo "" + +# Test avec tous les champs (simule ce que Next.js envoie à N8N) +echo "📤 Envoi de la requête complète au webhook N8N..." +echo "" + +curl -X POST "${WEBHOOK_URL}" \ + -H "Content-Type: application/json" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"name\": \"SEFFIR\", + \"oddScope\": [\"odd-4\"], + \"niveau\": \"s\", + \"missionType\": \"remote\", + \"donneurDOrdre\": \"group\", + \"projection\": \"long\", + \"services\": [], + \"participation\": \"ouvert\", + \"profils\": [], + \"hasGuardians\": true, + \"volunteersCount\": 0, + \"hasLogo\": true, + \"config\": { + \"MISSION_API_URL\": \"${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}\", + \"N8N_API_KEY\": \"${N8N_API_KEY}\", + \"ROCKETCHAT_API_URL\": \"${ROCKET_CHAT_API_URL:-https://parole.slm-lab.net}\", + \"ROCKETCHAT_AUTH_TOKEN\": \"${ROCKET_CHAT_TOKEN}\", + \"ROCKETCHAT_USER_ID\": \"${ROCKET_CHAT_USER_ID}\" + }, + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\" + }" \ + -v + +echo "" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "✅ Test terminé" +echo "" +echo "💡 Note: Ce test déclenche le workflow N8N complet." +echo " Vérifiez les logs N8N pour voir la structure exacte de la réponse RocketChat." diff --git a/test-n8n-webhook-env.sh b/test-n8n-webhook-env.sh new file mode 100644 index 0000000..6612122 --- /dev/null +++ b/test-n8n-webhook-env.sh @@ -0,0 +1,116 @@ +#!/bin/bash + +# Script pour tester le webhook N8N en utilisant les variables d'environnement +# Usage: source .env.local && ./test-n8n-webhook-env.sh [MISSION_ID] [ROCKETCHAT_CHANNEL_ID] + +# Charger les variables d'environnement depuis .env.local si elles existent +if [ -f .env.local ]; then + export $(grep -v '^#' .env.local | xargs) +fi + +# Configuration depuis les variables d'environnement +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" +API_KEY="${N8N_API_KEY}" + +# Vérifier que l'API key est définie +if [ -z "$API_KEY" ]; then + echo "❌ Erreur: N8N_API_KEY n'est pas définie dans les variables d'environnement" + echo " Assurez-vous d'avoir chargé .env.local ou défini N8N_API_KEY" + exit 1 +fi + +# Paramètres (utiliser ceux fournis ou des valeurs par défaut pour test) +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +ROCKETCHAT_CHANNEL_ID="${2:-ByehQjC44FwMeiLbX}" + +echo "🧪 Test du webhook N8N mission-created" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "API URL: $API_URL" +echo "Mission ID: $MISSION_ID" +echo "RocketChat Channel ID: $ROCKETCHAT_CHANNEL_ID" +echo "API Key: ${API_KEY:0:10}... (masquée)" +echo "" + +# Test principal avec tous les champs +echo "📤 Envoi de la requête avec RocketChat Channel ID..." +echo "" + +RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"name\": \"SEFFIR\", + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\", + \"gitRepoUrl\": \"\", + \"leantimeProjectId\": \"517\", + \"documentationCollectionId\": \"08919836-435a-466f-a38a-014991759da2\", + \"rocketchatChannelId\": \"${ROCKETCHAT_CHANNEL_ID}\", + \"donneurDOrdre\": \"group\", + \"projection\": \"long\", + \"missionType\": \"remote\", + \"niveau\": \"s\" + }") + +HTTP_CODE=$(echo "$RESPONSE" | tail -n1) +BODY=$(echo "$RESPONSE" | sed '$d') + +echo "📥 Réponse HTTP: $HTTP_CODE" +echo "📄 Corps de la réponse:" +echo "$BODY" | jq '.' 2>/dev/null || echo "$BODY" +echo "" + +if [ "$HTTP_CODE" = "200" ]; then + echo "✅ Succès! La mission a été mise à jour." +else + echo "❌ Erreur HTTP $HTTP_CODE" +fi + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "🔍 Tests supplémentaires avec différents formats de rocketchatChannelId:" +echo "" + +# Test 1: ID valide +echo "=== Test 1: ID RocketChat valide ===" +curl -s -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"rocketchatChannelId\": \"ByehQjC44FwMeiLbX\" + }" | jq '.' || echo "Erreur de parsing JSON" +echo "" + +# Test 2: null +echo "=== Test 2: ID RocketChat null ===" +curl -s -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"rocketchatChannelId\": null + }" | jq '.' || echo "Erreur de parsing JSON" +echo "" + +# Test 3: chaîne vide +echo "=== Test 3: ID RocketChat chaîne vide ===" +curl -s -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"rocketchatChannelId\": \"\" + }" | jq '.' || echo "Erreur de parsing JSON" +echo "" + +# Test 4: non fourni +echo "=== Test 4: ID RocketChat non fourni ===" +curl -s -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\" + }" | jq '.' || echo "Erreur de parsing JSON" +echo "" diff --git a/test-n8n-webhook-precise.sh b/test-n8n-webhook-precise.sh new file mode 100644 index 0000000..43b4e38 --- /dev/null +++ b/test-n8n-webhook-precise.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Test précis du webhook N8N avec la structure exacte envoyée par Next.js +# Usage: ./test-n8n-webhook-precise.sh [MISSION_ID] [ROCKETCHAT_CHANNEL_ID] + +# Charger .env.local +if [ -f .env.local ]; then + export $(grep -v '^#' .env.local | xargs) +fi + +# URL du webhook N8N +WEBHOOK_URL="https://brain.slm-lab.net/webhook-test/mission-created" + +# Variables d'environnement +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" +API_KEY="${N8N_API_KEY}" + +# Paramètres optionnels +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +ROCKETCHAT_CHANNEL_ID="${2:-ByehQjC44FwMeiLbX}" + +echo "🧪 Test précis du webhook N8N" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "Webhook URL: $WEBHOOK_URL" +echo "Mission ID: $MISSION_ID" +echo "RocketChat Channel ID: $ROCKETCHAT_CHANNEL_ID" +echo "" + +# Structure exacte envoyée par Next.js (après nettoyage dans n8n-service.ts) +curl -X POST "${WEBHOOK_URL}" \ + -H "Content-Type: application/json" \ + -d "{ + \"name\": \"SEFFIR\", + \"oddScope\": [\"odd-4\"], + \"niveau\": \"s\", + \"intention\": \"\", + \"missionType\": \"remote\", + \"donneurDOrdre\": \"group\", + \"projection\": \"long\", + \"services\": [], + \"participation\": \"ouvert\", + \"profils\": [], + \"guardians\": {}, + \"volunteers\": [], + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\", + \"missionId\": \"${MISSION_ID}\", + \"logoPath\": \"missions/${MISSION_ID}/logo.png\", + \"logoUrl\": \"https://hub.slm-lab.net/api/missions/image/missions/${MISSION_ID}/logo.png\", + \"config\": { + \"N8N_API_KEY\": \"${API_KEY}\", + \"MISSION_API_URL\": \"${API_URL}\" + } + }" \ + -v + +echo "" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "✅ Test terminé" +echo "" +echo "💡 Ce test déclenche le workflow N8N complet." +echo " Vérifiez les logs N8N pour voir:" +echo " 1. La structure de la réponse RocketChat" +echo " 2. Le chemin exact pour accéder à channel._id" +echo " 3. La valeur exacte de rocketchatChannelId dans 'Save Mission To API'" diff --git a/test-n8n-webhook.sh b/test-n8n-webhook.sh new file mode 100644 index 0000000..7e88a7a --- /dev/null +++ b/test-n8n-webhook.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +# Script pour tester le webhook N8N mission-created +# Usage: ./test-n8n-webhook.sh [MISSION_ID] [ROCKETCHAT_CHANNEL_ID] + +# Configuration +API_URL="${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net/api}" +API_KEY="${N8N_API_KEY:-your-api-key-here}" + +# Paramètres (utiliser ceux fournis ou des valeurs par défaut pour test) +MISSION_ID="${1:-3103ec1a-acde-4025-9ead-4e1a0ddc047c}" +ROCKETCHAT_CHANNEL_ID="${2:-ByehQjC44FwMeiLbX}" + +echo "Testing N8N webhook output..." +echo "API URL: $API_URL" +echo "Mission ID: $MISSION_ID" +echo "RocketChat Channel ID: $ROCKETCHAT_CHANNEL_ID" +echo "" + +curl -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"name\": \"SEFFIR\", + \"creatorId\": \"203cbc91-61ab-47a2-95d2-b5e1159327d7\", + \"gitRepoUrl\": \"\", + \"leantimeProjectId\": \"517\", + \"documentationCollectionId\": \"08919836-435a-466f-a38a-014991759da2\", + \"rocketchatChannelId\": \"${ROCKETCHAT_CHANNEL_ID}\", + \"donneurDOrdre\": \"group\", + \"projection\": \"long\", + \"missionType\": \"remote\", + \"niveau\": \"s\" + }" \ + -v + +echo "" +echo "" +echo "Test avec différents formats de rocketchatChannelId:" +echo "" + +# Test 1: ID valide +echo "=== Test 1: ID RocketChat valide ===" +curl -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"rocketchatChannelId\": \"ByehQjC44FwMeiLbX\" + }" \ + -s | jq '.' + +echo "" +echo "=== Test 2: ID RocketChat null ===" +curl -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"rocketchatChannelId\": null + }" \ + -s | jq '.' + +echo "" +echo "=== Test 3: ID RocketChat chaîne vide ===" +curl -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\", + \"rocketchatChannelId\": \"\" + }" \ + -s | jq '.' + +echo "" +echo "=== Test 4: ID RocketChat non fourni ===" +curl -X POST "${API_URL}/missions/mission-created" \ + -H "Content-Type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d "{ + \"missionId\": \"${MISSION_ID}\" + }" \ + -s | jq '.'