Facebook Pixel
Fit'DistanceDocumentation
Ouvrir l'app
Sur cette page

Relancer les élèves inactifs

Chaque lundi, envoie un court message aux élèves sans séance terminée depuis 14 jours, avec un premier passage sans envoi.

Chaque lundi, les élèves sans séance terminée depuis 14 jours reçoivent un message dans l'app. Ce cas pratique écrit en ton nom : il demande une clé avec Élèves › Lire (students:read), Entraînement › Lire (training: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. L'API ne donne pas la connexion de l'élève : le cas pratique regarde les séances terminées. Un événement remplacera cette lecture régulière.

Ce que fait ce cas pratique

  1. Déclencheur : chaque lundi, puis GET /me pour coach.first_name, la signature.
  2. Séances : GET /workouts?status=done&since=<J-14>, toutes les pages (status vaut scheduled, done, in_progress, draft ou missed). since porte sur updated_at : on ne garde donc que les student_id des séances dont ended_at, ou updated_at s'il manque, est supérieur ou égal à J-14.
  3. É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 est PAUSED ou EXPIRED.
  4. Envoi : un POST /operations/messaging.send par é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: inactif-42-2026-10-26" \
  -d '{"text": "Salut Léa, …", "studentId": 42}'

L'Idempotency-Key vaut inactif-<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 vu de séance terminée de ta part depuis deux semaines. Si quelque chose te gêne, écris-le-moi ici.

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. Cent élèves à trois séances par semaine : 600 séances en 14 jours, donc 14 pages lues avec limit=50, 4 avec limit=200, élèves compris, puis un message par élève relancé. À ce volume, les séances tiennent sur plus d'une page et le scénario Make s'arrête à chaque passage : passe par n8n ou par un script. 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

  1. Choisis Import from URL… et colle https://fitdistance.io/documentation/api/cas-pratiques/eleve-inactif-relance.n8n.json, ou télécharge le workflow et choisis Import from File…. Choisis l'identifiant Fit'Distance API de Brancher n8n dans chaque nœud HTTP Request.
  2. 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 inactif est relancé chaque semaine, donc déclenche une semaine sur deux pour espacer.

  1. 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 workouts, qui garde les identifiants des pages lues.

Dans Make

  1. Premier module HTTP › Make a request sur GET /me ; planning sur son horloge : chaque lundi.
  2. HTTP › Make a request : GET sur https://api.fitdistance.io/api/partner/v1/workouts, limit = 200, status = done, 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 la séance est sur la page suivante (n8n lit toutes les pages). Puis un Iterator sur data, un filtre ifempty(ended_at; updated_at) postérieur ou égal à {{addDays(now; -14)}} et un Flow Control › Array aggregator sur student_id.
  3. HTTP › Make a request : GET sur /students avec limit = 200, un Iterator sur data, puis un filtre : joined_at antérieur à {{addDays(now; -14)}}, contract_status différent de PAUSED et de EXPIRED, et contains(map(<tableau agrégé>; student_id); id) faux.
  4. Lis le résultat du filtre, puis ajoute HTTP › Make a request : POST sur /operations/messaging.send, Idempotency-Key = inactif-{{id}}-{{formatDate(now; YYYY-MM-DD)}}, Body content type application/JSON, Body input method JSON string, corps {"text": "…", "studentId": {{id}}}.

Référence : élèves, entraînement, envoi d'un message.

Page suivanteUn achat en ligne → une invitationQuand un client règle un achat sur Stripe, invite-le dans ton coaching avec Fit'Distance, après un premier passage en aperçu, avec n8n ou Make.