RESTful API bridge for EcoleDirecte, powered by wrapdirecte and Cloudflare Workers.
Le bridge peut être utilisé de deux manières :
Vous pouvez utiliser bridgedirecte comme une bibliothèque dans votre propre Worker Cloudflare.
import { createBridge } from 'bridgedirecte'
// Exportation de l'instance configurée
export default createBridge({
allowedOrigins: ['https://votre-site.com'], // défaut ["*"]
appName: 'monApplication', // défaut: nom dans package.json
appVersion: '1.0.0', // défaut: version dans package.json
forceHttps: true, // refuse les requêtes non sécurisées, défaut true
})Si vous souhaitez simplement faire une nouvelle instance vierge :
git clone https://bridge.directe.qzz.io/new
npm i
npx wrangler deployVous pourrez modifier les paramètres de configuration dans le fichier worker.js.
git clone https://bridge.directe.qzz.io/sourcecodeSi vous clonez le code source directement, vous pouvez configurer l'instance via un fichier bridgedirecte.config.jsonc à la racine du projet :
| Réglage | Description | Défaut |
|---|---|---|
allowedOrigins |
Liste des origines autorisées (CORS) | ["*"] |
appName |
Nom de l'application (User-Agent) | package.json |
appVersion |
Version de l'application (User-Agent) | package.json |
forceHttps |
Exiger HTTPS (sauf localhost) | true |
Caution
Si vous fournissez des réglages à createBridge() ET qu'un fichier bridgedirecte.config.jsonc est présent, le bridge renverra une erreur "Bad config".
Le bridge est stateless. Chaque requête (sauf /login et /login/2fa) nécessite :
| Header | Description | Exemple |
|---|---|---|
Authorization |
Token Bearer obtenu après /login |
Bearer eyJhbGci... |
Account-ID |
ID numérique du compte élève à utiliser | 1234 |
Connexion avec identifiants EcoleDirecte.
Query (Optionnel) : ?direct=true pour bypasser le 2FA si vous avez un 2faProof.
Body :
{
"username": "mon.identifiant",
"password": "monMotDePasse",
"2faProof": "mon2faProof (requis si direct=true)",
"uuid": "optionnel-uuid",
"preferredAccountId": 123456
}Réponse (succès) :
{
"success": true,
"status": "authenticated",
"token": "eyJhbGci...",
"faProof": "leProofAStocker",
"accounts": [{ "id": 123456, "firstName": "Jean", "lastName": "Dupont" }]
}Réponse (2FA requis) :
{
"success": true,
"status": "needs_2fa",
"challenge": {
"question": "Quel est le prénom de votre professeur principal ?",
"proposals": []
},
"partialToken": "eyJhbGci..."
}Soumettre la réponse 2FA.
Headers requis : Authorization: Bearer <partial_token>
Body :
{
"answer": "reponse",
"username": "votre_username",
"password": "votre_password",
"uuid": "optionnel"
}Réponse :
{
"success": true,
"status": "authenticated",
"token": "eyJhbGci...",
"faProof": "leProofAStocker",
"accounts": [{ "id": 123456 }]
}Vérifier le statut d'authentification de la session en cours.
Headers requis : Authorization: Bearer <token>
Réponse :
{
"success": true,
"isAuthenticated": true,
"accountId": 123456
}Headers : Authorization, Account-ID
Query : ?year=2025-2026 (défaut : année scolaire en cours)
Réponse :
{
"grades": [...],
"periods": [...],
"settings": {}
}Headers : Authorization, Account-ID
Query : ?date=2026-04-08 (défaut : aujourd'hui)
Réponse : CleanHomework[]
Marquer un devoir comme fait ou non fait.
Headers : Authorization, Account-ID
Query : ?id=<homeworkId>
Body :
{ "done": true }Réponse :
{ "success": true, "id": 987654, "done": true }Ajouter un commentaire à un devoir.
Headers : Authorization, Account-ID
Body :
{ "content": "Mon commentaire" }Réponse :
{ "success": true, "commentId": 111 }Headers : Authorization, Account-ID
Query : ?from=2026-04-01&to=2026-04-07 (défaut : semaine courante)
Réponse : CleanCourse[]
Headers : Authorization, Account-ID
Réponse :
{ "success": true, "url": "https://api.ecoledirecte.com/ical/..." }Headers : Authorization, Account-ID
Réponse : CleanAbsence[]
Timeline personnelle de l'élève.
Headers : Authorization, Account-ID
Réponse : CleanTimelineEvent[]
Timeline commune (toute l'école).
Headers : Authorization, Account-ID
Réponse :
{
"events": [...],
"postits": [...]
}Headers : Authorization, Account-ID
Réponse :
{
"factures": [...],
"notes": [...]
}Headers : Authorization, Account-ID
Query : ?depth=3 (défaut : 3)
Réponse : CleanCloudNode[]
Créer un dossier.
Headers : Authorization, Account-ID
Body :
{ "path": "parent/chemin", "name": "nouveauDossier" }Copier des fichiers/dossiers.
Body :
{ "destination": "dest/chemin", "nodes": [...] }Déplacer des fichiers/dossiers.
Body :
{ "destination": "dest/chemin", "nodes": [...] }Supprimer des fichiers/dossiers.
Body :
{ "nodes": [...] }Restaurer des fichiers/dossiers supprimés.
Body :
{ "nodes": [...] }Exporter un fichier vers le cloud.
Body :
{
"fileId": "abc123",
"source": "CAHIER_DE_TEXTES"
}source : "CAHIER_DE_TEXTES" ou "MESSAGERIE"
Téléverser un fichier vers le cloud.
Headers requis : Authorization, Account-ID
Body (multipart/form-data) :
file: Le fichier à téléverser.dest(oudestPath, optionnel) : Le chemin de destination dans le cloud (défaut :/).
Réponse :
{
"success": true,
"message": "Fichier téléversé avec succès"
}Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{
"received": [...],
"sent": [...],
"draft": [...],
"archived": [...],
"folders": [...]
}Contenu complet d'un message.
Headers : Authorization, Account-ID
Query : ?year=2025-2026&glance=true (glance=true marque le message comme non lu lors de l'ouverture)
Réponse : CleanMessage avec champ content
Messages d'un dossier spécifique.
Headers : Authorization, Account-ID
Réponse : CleanMessage[]
Récupérer les contacts.
Headers : Authorization, Account-ID
Paramètre : :type = professeurs | personnels | entreprises
Réponse : Contact[]
Envoyer un message.
Headers : Authorization, Account-ID
Body :
{
"subject": "Objet du message",
"content": "Contenu du message",
"recipients": [{ "id": 123, "type": "P" }],
"year": "2025-2026"
}Réponse :
{ "success": true, "messageId": 456789 }Marquer un message comme lu.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }Marquer un message comme non lu.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }Archiver un message.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }Désarchiver un message.
Headers : Authorization, Account-ID
Query : ?year=2025-2026
Réponse :
{ "success": true }Déplacer un message vers un autre dossier.
Headers : Authorization, Account-ID
Body :
{ "folder": 12345 }Réponse :
{ "success": true }Créer un nouveau dossier.
Headers : Authorization, Account-ID
Body :
{ "name": "Nom du dossier" }Réponse :
{ "success": true, "id": 12345 }Supprimer un dossier.
Headers : Authorization, Account-ID
Réponse :
{ "success": true }Headers : Authorization, Account-ID
Query : ?loginId=123 (optionnel)
Mettre à jour les paramètres du compte.
Headers : Authorization, Account-ID
Body :
{
"identifiant": "nouvelIdentifiant",
"nouveauMotDePasse": "nouveauMotDePasse",
"confirmationMotDePasse": "nouveauMotDePasse",
"email": "nouveau@email.com",
"portable": "0612345678",
"questionSecrete": "Question secrète",
"reponse": "Réponse",
"uuid": "optionnel"
}Mettre à jour un paramètre individuel.
Headers : Authorization, Account-ID
Body :
{ "value": "nouvelle-valeur" }Toutes les erreurs suivent ce format :
{
"success": false,
"error": "Description de l'erreur",
"code": 400
}| Code | Signification |
|---|---|
| 400 | Requête invalide (body, params) |
| 401 | Non authentifié / token invalide |
| 404 | Route introuvable |
| 500 | Erreur interne du serveur |
| 503 | Module indisponible |
Le bridge injecte automatiquement un header X-Forwarded-For avec une IP française aléatoire sur chaque requête vers EcoleDirecte, en utilisant les préfixes des principaux opérateurs :
| Préfixe | Opérateur |
|---|---|
80.12.* |
Orange |
82.224.* |
Free |
176.128.* |
SFR |
90.1.* |
Orange Mobile |
AGPL 3.0 — Voir LICENSE pour les détails.
{ "allowedOrigins": ["*"], "appName": "bridgeDirecteCustom", "appVersion": "1.0.0", "forceHttps": true, }