Relancer les élèves sans bilan depuis 14 jours
Chaque lundi, envoie un court message aux élèves qui n'ont pas envoyé de bilan depuis 14 jours, avec un premier passage sans envoi.
Chaque lundi, les élèves sans bilan depuis 14 jours reçoivent un court message dans l'app. Ce cas pratique écrit en ton nom : il lui faut une clé avec Élèves › Lire (students:read), Bilans › Lire (bilans:read) et Messages › Écrire (messaging:write), et une offre qui inclut les écritures. Crée la clé dans l'app, conditions d'usage acceptées.
Ce que fait ce cas pratique
- Déclencheur : chaque lundi, puis
GET /mepourcoach.first_name, la signature (gratuit). - Bilans :
GET /bilans?since=<J-14>, toutes les pages.sinceporte surupdated_at, que bouge aussi un commentaire : on ne garde donc que lesstudent_iddes bilans dontsubmitted_atest supérieur ou égal à J-14. - Élèves :
GET /students, toutes les pages. Chaque élève absent de cet ensemble reçoit un message, sauf s'il est arrivé il y a moins de 14 jours ou si son contrat estPAUSEDouEXPIRED. - Envoi : un
POST /operations/messaging.sendpar élève relancé.
curl -X POST https://api.fitdistance.io/api/partner/v1/operations/messaging.send \
-H "Authorization: Bearer fd_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: bilan-42-2026-10-26" \
-d '{"text": "Salut Léa, …", "studentId": 42}'L'Idempotency-Key vaut bilan-<id>-<AAAA-MM-JJ>, avec la date du passage : un rejeu le même jour est remboursé. Voir Écritures et idempotence.
Le message
Salut Léa, je n'ai pas reçu de bilan de ta part depuis deux semaines. Quand tu as un moment, tu peux le remplir dans l'app ? Il m'aide à suivre ton évolution.
Mathias
Ce que ça coûte
Une page lue coûte un crédit, débité avant l'appel ; chaque message envoyé en coûte un. Avec 100 élèves et 40 bilans récents : 3 pages lues avec limit=50, 2 avec limit=200, puis un message par élève relancé. Un paramètre refusé coûte quand même un crédit ; un 401, un 403 ou un 429 ne coûtent rien ; un rejeu est remboursé.
Un premier passage sans rien envoyer
messaging.send n'a pas d'aperçu avec studentId : dry_run: true donne un 400 DRY_RUN_UNSUPPORTED, gratuit. Le premier passage liste donc les élèves sans les prévenir, pour le seul prix des lectures.
Dans n8n
- Choisis Import from URL… et colle
https://fitdistance.io/documentation/api/cas-pratiques/eleve-sans-bilan-relance.n8n.json, ou télécharge le workflow et choisis Import from File…. Choisis l'identifiantFit'Distance APIde Brancher n8n dans chaque nœud HTTP Request. - Exécute-le et lis la sortie de Students to remind : un élément par élève, avec son texte.
L'envoi écrit à de vrais élèves
Send message est livré désactivé : active-le seulement après ce premier passage. L'Idempotency-Key évite un doublon le même jour, pas d'un lundi à l'autre : un élève silencieux est relancé chaque semaine, donc déclenche une semaine sur deux pour espacer.
- Active Send message, exécute à nouveau, puis active le workflow. Il envoie un message par seconde au plus.
Le texte est en haut du code de Students to remind. La boucle est celle de Brancher n8n, plus un nœud Code, Collect check-ins, qui garde les identifiants des pages lues.
Dans Make
- Premier module HTTP › Make a request sur
GET /me; planning sur son horloge : chaque lundi. - HTTP › Make a request :
GETsurhttps://api.fitdistance.io/api/partner/v1/bilans,limit=200,since={{addDays(now; -14)}}. Un filtre sur le lien qui suit :has_moreégal àfalse, pour s'arrêter plutôt que de relancer à tort un élève dont le bilan est sur la page suivante. Puis un Iterator surdata, un filtre sursubmitted_atet un Flow Control › Array aggregator surstudent_id. - HTTP › Make a request :
GETsur/studentsaveclimit=200, un Iterator surdata, puis un filtre :joined_atantérieur à{{addDays(now; -14)}},contract_statusdifférent dePAUSEDet deEXPIRED, etcontains(map(<tableau agrégé>; student_id); id)faux. - Lis le résultat du filtre, puis ajoute HTTP › Make a request :
POSTsur/operations/messaging.send,Idempotency-Key=bilan-{{id}}-{{formatDate(now; YYYY-MM-DD)}}, Body content typeapplication/JSON, Body input methodJSON string, corps{"text": "…", "studentId": {{id}}}.
Le workflow n8n, lui, lit toutes les pages. Référence : élèves, bilans, envoi d'un message.