Vision Refactor
This commit is contained in:
parent
5e3289f0e1
commit
1257f8cff3
98
N8N_ROCKETCHAT_FIX.md
Normal file
98
N8N_ROCKETCHAT_FIX.md
Normal file
@ -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.
|
||||
@ -1,21 +1,160 @@
|
||||
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);
|
||||
|
||||
if (!session) {
|
||||
redirect("/signin");
|
||||
interface Group {
|
||||
id: string;
|
||||
name: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
// URL Jitsi avec salle par défaut
|
||||
const jitsiUrl = process.env.NEXT_PUBLIC_IFRAME_CONFERENCE_URL || 'https://vision.slm-lab.net/MonMeeting';
|
||||
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<Group[]>([]);
|
||||
const [missions, setMissions] = useState<Mission[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedConference, setSelectedConference] = useState<{
|
||||
type: ConferenceType;
|
||||
id: string;
|
||||
name: string;
|
||||
} | null>(null);
|
||||
const [jitsiUrl, setJitsiUrl] = useState<string | null>(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 (
|
||||
<main className="w-full h-screen bg-black">
|
||||
<div className="w-full h-full px-4 pt-12 pb-4">
|
||||
<main className="w-full h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<Loader2 className="h-12 w-12 animate-spin text-blue-600 mx-auto mb-4" />
|
||||
<p className="text-gray-600">Chargement...</p>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
// Show Jitsi iframe if conference is selected
|
||||
if (selectedConference && jitsiUrl) {
|
||||
return (
|
||||
<main className="w-full h-screen bg-black flex flex-col">
|
||||
{/* Header with back button */}
|
||||
<div className="bg-white border-b border-gray-200 px-4 py-3 flex items-center gap-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={handleBack}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<ArrowLeft className="h-4 w-4" />
|
||||
Retour
|
||||
</Button>
|
||||
<div className="flex-1">
|
||||
<h1 className="text-sm font-medium text-gray-900">
|
||||
{selectedConference.type === "group" ? "Groupe" : "Mission"}: {selectedConference.name}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Jitsi iframe */}
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<ResponsiveIframe
|
||||
src={jitsiUrl}
|
||||
allow="camera; microphone; fullscreen; display-capture; autoplay; clipboard-write; encrypted-media"
|
||||
@ -24,3 +163,143 @@ export default async function Page() {
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
// Show list of groups and missions
|
||||
return (
|
||||
<main className="w-full h-screen bg-gray-50">
|
||||
<div className="w-full h-full px-4 pt-12 pb-4">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900 mb-2">
|
||||
Espaces de réunion
|
||||
</h1>
|
||||
<p className="text-gray-600">
|
||||
Sélectionnez un groupe ou une mission pour accéder à son espace de réunion Jitsi
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Groups Section */}
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<Users className="h-5 w-5 text-blue-600" />
|
||||
<h2 className="text-xl font-semibold text-gray-900">
|
||||
Groupes ({groups.length})
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{groups.length === 0 ? (
|
||||
<div className="bg-white rounded-lg border border-gray-200 p-8 text-center">
|
||||
<Users className="h-12 w-12 text-gray-400 mx-auto mb-3" />
|
||||
<p className="text-gray-500">Aucun groupe disponible</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{groups.map((group) => (
|
||||
<div
|
||||
key={group.id}
|
||||
className="bg-white rounded-lg border border-gray-200 p-4 hover:shadow-md transition-shadow cursor-pointer"
|
||||
onClick={() => handleConferenceClick("group", group.id, group.name)}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3 flex-1">
|
||||
<div className="h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center">
|
||||
<Users className="h-5 w-5 text-blue-600" />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h3 className="font-medium text-gray-900 truncate">
|
||||
{group.name}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500 truncate">
|
||||
{group.path}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="ml-2 flex items-center gap-2"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleConferenceClick("group", group.id, group.name);
|
||||
}}
|
||||
>
|
||||
<Video className="h-4 w-4" />
|
||||
Réunion
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Missions Section */}
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<FolderKanban className="h-5 w-5 text-purple-600" />
|
||||
<h2 className="text-xl font-semibold text-gray-900">
|
||||
Missions ({missions.length})
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{missions.length === 0 ? (
|
||||
<div className="bg-white rounded-lg border border-gray-200 p-8 text-center">
|
||||
<FolderKanban className="h-12 w-12 text-gray-400 mx-auto mb-3" />
|
||||
<p className="text-gray-500">Aucune mission disponible</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{missions.map((mission) => (
|
||||
<div
|
||||
key={mission.id}
|
||||
className="bg-white rounded-lg border border-gray-200 p-4 hover:shadow-md transition-shadow cursor-pointer"
|
||||
onClick={() => handleConferenceClick("mission", mission.id, mission.name)}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3 flex-1">
|
||||
{mission.logoUrl ? (
|
||||
<div className="h-10 w-10 rounded-md overflow-hidden flex-shrink-0">
|
||||
<img
|
||||
src={mission.logoUrl}
|
||||
alt={mission.name}
|
||||
className="h-full w-full object-cover"
|
||||
onError={(e) => {
|
||||
(e.target as HTMLImageElement).style.display = 'none';
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="h-10 w-10 rounded-md bg-purple-100 flex items-center justify-center flex-shrink-0">
|
||||
<FolderKanban className="h-5 w-5 text-purple-600" />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 min-w-0">
|
||||
<h3 className="font-medium text-gray-900 truncate">
|
||||
{mission.name}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="ml-2 flex items-center gap-2"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleConferenceClick("mission", mission.id, mission.name);
|
||||
}}
|
||||
>
|
||||
<Video className="h-4 w-4" />
|
||||
Réunion
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
52
test-n8n-curl-env.sh
Normal file
52
test-n8n-curl-env.sh
Normal file
@ -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é"
|
||||
37
test-n8n-curl-precise.sh
Normal file
37
test-n8n-curl-precise.sh
Normal file
@ -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 '.'
|
||||
22
test-n8n-curl.sh
Normal file
22
test-n8n-curl.sh
Normal file
@ -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: <VOTRE_N8N_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
|
||||
86
test-n8n-inline.sh
Normal file
86
test-n8n-inline.sh
Normal file
@ -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
|
||||
87
test-n8n-python.py
Normal file
87
test-n8n-python.py
Normal file
@ -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)
|
||||
45
test-n8n-simple-vm.sh
Normal file
45
test-n8n-simple-vm.sh
Normal file
@ -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
|
||||
39
test-n8n-simple.sh
Normal file
39
test-n8n-simple.sh
Normal file
@ -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 '.'
|
||||
158
test-n8n-vm.sh
Normal file
158
test-n8n-vm.sh
Normal file
@ -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 <<EOF
|
||||
{
|
||||
"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}"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Essayer curl d'abord, puis wget, puis python3
|
||||
if command -v curl &> /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 <<PYTHON_SCRIPT
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import json
|
||||
import sys
|
||||
|
||||
url = "${WEBHOOK_URL}"
|
||||
data = ${JSON_DATA}
|
||||
|
||||
json_data = json.dumps(data).encode('utf-8')
|
||||
req = urllib.request.Request(url, data=json_data, headers={'Content-Type': 'application/json'})
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
print(f"Status: {response.status} {response.reason}")
|
||||
print(f"Headers: {dict(response.headers)}")
|
||||
print(f"\nResponse Body:")
|
||||
print(response.read().decode('utf-8'))
|
||||
except urllib.error.HTTPError as e:
|
||||
print(f"HTTP Error {e.code}: {e.reason}")
|
||||
print(e.read().decode('utf-8'))
|
||||
sys.exit(1)
|
||||
PYTHON_SCRIPT
|
||||
elif command -v node &> /dev/null; then
|
||||
echo "📤 Utilisation de node..."
|
||||
echo ""
|
||||
node <<NODE_SCRIPT
|
||||
const https = require('https');
|
||||
const http = require('http');
|
||||
|
||||
const url = new URL('${WEBHOOK_URL}');
|
||||
const data = ${JSON_DATA};
|
||||
|
||||
const options = {
|
||||
hostname: url.hostname,
|
||||
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
||||
path: url.pathname,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': Buffer.byteLength(JSON.stringify(data))
|
||||
}
|
||||
};
|
||||
|
||||
const client = url.protocol === 'https:' ? https : http;
|
||||
|
||||
const req = client.request(options, (res) => {
|
||||
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"
|
||||
62
test-n8n-webhook-direct.sh
Normal file
62
test-n8n-webhook-direct.sh
Normal file
@ -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."
|
||||
116
test-n8n-webhook-env.sh
Normal file
116
test-n8n-webhook-env.sh
Normal file
@ -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 ""
|
||||
65
test-n8n-webhook-precise.sh
Normal file
65
test-n8n-webhook-precise.sh
Normal file
@ -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'"
|
||||
84
test-n8n-webhook.sh
Normal file
84
test-n8n-webhook.sh
Normal file
@ -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 '.'
|
||||
Loading…
Reference in New Issue
Block a user