Fonctions inline Make : 10 exemples et leurs pièges
Dix fonctions inline de Make expliquées avec un cas réel chacune : if, ifempty, get, map, formatDate, parseNumber, replace et les pièges qui vont avec.

Ouvre un de tes scénarios Make qui a quelques mois de vie. Il y a de bonnes chances que tu y trouves un routeur posé pour une simple condition, deux filtres qui se ressemblent, un module Set Variables qui reformate un champ, et un agrégateur qui recolle le tout. Quatorze modules à l’écran pour un traitement qui, logiquement, en méritait cinq. Ça pique, et ça se soigne.
Chaque module de trop se paie trois fois. En opérations d’abord, puisque chaque exécution de module en consomme : sur un scénario qui tourne mille fois par mois, huit modules superflus font huit mille opérations facturées pour rien. En temps de débogage ensuite, parce qu’une erreur se cherche module par module. En lisibilité enfin, le canvas devenant une carte de métro que plus personne n’ose toucher. Le rasoir d’Ockham, ce principe de philosophie qui recommande de ne pas multiplier les entités sans nécessité, aurait fait un excellent consultant Make.
Les fonctions inline de Make attaquent les trois problèmes à la fois. Elles s’écrivent directement dans les champs des modules, au clavier, dans le panneau de mapping, et chacune remplace une grappe de modules entière : une condition sans routeur, une extraction de tableau sans itérateur, un nettoyage de texte sans module de parsing. Ce guide en détaille dix, chacune avec un cas métier réel, l’expression exacte à écrire, la grappe de modules qu’elle économise, et le piège qui l’accompagne. Toutes les signatures viennent de la documentation officielle des fonctions, vérifiées au moment de la rédaction.

C’est ce panneau qui s’ouvre au clic dans n’importe quel champ, et il contient déjà tout : les onglets du haut classent les fonctions par famille, générales, mathématiques, texte, dates, tableaux, et les touches du dessous s’insèrent d’un clic. Le champ en cours de saisie montre l’amorce d’une expression entre doubles accolades, et deux champs plus haut se lisent des expressions déjà posées, un calcul de pourcentage et une conversion de date imbriquée. Tout ce guide se passe dans cette fenêtre.
Ce qu’il te faut
- un compte Make, n’importe quel plan
- un scénario existant un peu encombré, qui servira de terrain d’entraînement
- savoir ouvrir le panneau de mapping d’un champ, tout se joue dedans
- 45 minutes pour lire, puis le double pour refactoriser ton premier scénario
Si tu n’as pas encore de scénario à refactoriser, prends l’une de ces automatisations Make pour freelance comme terrain d’essai : les conditions, dates et tableaux qu’elles manipulent couvrent plusieurs fonctions de ce guide.
if() et ifempty(), décider sans poser de routeur
Commençons par la grappe la plus répandue de toutes, celle qui naît d’une simple décision. Le cas revient chaque semaine : un email de confirmation dont une phrase change selon la situation. Un montant au-dessus de 1 000 euros mérite la mention « dossier prioritaire », les autres non. Le réflexe visuel, dans Make, pousse vers un routeur, deux routes, un filtre sur chaque, deux modules email presque identiques. Cinq modules, et deux versions du même email à maintenir.
La fonction if(expression; valeur1; valeur2) fait tenir la décision dans le champ lui-même :
{{if(1.montant >= 1000; "Ton dossier est traité en priorité."; "Ton dossier suit le traitement standard.")}}
Un seul module email, une seule version à maintenir, et la condition lisible à l’endroit exact où elle s’applique. Sa sœur ifempty(valeur1; valeur2) couvre le cas encore plus fréquent de la donnée manquante, le prénom absent d’un formulaire :
Bonjour {{ifempty(1.prenom; "à toi")}},
Le piège du duo se cache dans la définition du mot « vide ». La documentation est précise : ifempty() renvoie la valeur de repli pour une chaîne vide et pour une valeur inconnue. Un test manuel if(1.prenom = ""; ...) attrape la chaîne vide mais laisse passer la valeur inconnue, celle d’un champ que le module précédent n’a simplement pas renvoyé. Résultat : « Bonjour , » dans l’email. La virgule orpheline, signature des scénarios montés trop vite. Pour tester la présence d’une donnée, ifempty() gagne à tous les coups.
switch(), traduire une valeur sans multiplier les routes
Après la condition binaire vient son grand frère, le cas à plusieurs branches. Ton CRM renvoie des statuts techniques, won, lost, open, et le document client doit afficher « Gagné », « Perdu », « En cours ». En modules, ce serait un routeur à trois routes et trois Set Variables. La fonction switch(expression; valeur1; resultat1; valeur2; resultat2; ...) compare une valeur à une liste de paires et renvoie le résultat de la première correspondance :
{{switch(1.statut; "won"; "Gagné"; "lost"; "Perdu"; "open"; "En cours"; "Statut à vérifier")}}
Le dernier argument, seul, sans valeur associée, sert de clause par défaut, et la documentation confirme ce comportement : sans correspondance, c’est lui qui sort. Ne le saute jamais. Le jour où le CRM ajoute un statut on-hold que ton expression ne connaît pas, la clause par défaut affiche « Statut à vérifier » au lieu de laisser un trou dans le document, et le problème se voit au lieu de se cacher.
get(), atteindre une valeur enfouie sans module d’itération
Les décisions traitées, reste à aller chercher les données là où elles se nichent, et elles se nichent souvent profond. Un webhook livre un tableau de réponses, et seule la première t’intéresse ; un objet client contient une adresse qui contient une ville. La fonction get(objet ou tableau; chemin) va chercher la valeur directement, avec la notation à points pour les niveaux imbriqués :
{{get(1.reponses; 1)}}
{{get(1.client; "adresse.ville")}}
La grappe économisée est l’une des plus chères du catalogue : un Iterator pour dérouler le tableau, un filtre pour ne garder que le premier élément, et les opérations consommées par chaque élément parcouru.
Deux pièges, tous deux silencieux. D’abord, les tableaux de Make sont indexés à partir de 1, et la documentation l’assume tranquillement : le premier élément est get(tableau; 1), et quiconque vient de la programmation écrira 0 par réflexe et recevra du vide. Bienvenue au club, la cotisation se paie en heures de débogage. Ensuite, un index qui n’existe pas, demander le cinquième élément d’un tableau qui en compte trois, renvoie du vide sans erreur. Le scénario continue, le vide se propage, et le symptôme éclate trois modules plus loin, dans un email sans objet ou une ligne de base de données à moitié remplie. Quand une valeur manque en aval, remonte systématiquement jusqu’au get() le plus proche.
map(), extraire et filtrer un tableau complexe en une expression
get() attrape un élément ; pour en attraper toute une colonne, il y a plus fort. Le cas : un tableau de participants, chacun avec un nom, un email et un statut, et tu veux les emails des seuls participants confirmés, en une liste à coller dans un champ destinataires. En modules : Iterator, filtre sur le statut, Text Aggregator, trois modules et une opération par participant parcouru.
La fonction map(tableau complexe; cle; [cle de filtrage]; [valeurs de filtrage separees par des virgules]) fait l’extraction et le filtre d’un coup, et join() recolle le résultat :
{{join(map(1.participants; "email"; "statut"; "confirme"); ", ")}}
Lue de l’intérieur vers l’extérieur : map() parcourt les participants, ne garde que ceux dont statut vaut confirme, extrait leur champ email, et join() assemble la liste avec des virgules. Une expression, zéro module supplémentaire, zéro opération d’itération. Sur les scénarios à gros volumes, cette seule substitution change la facture du mois, et c’est généralement elle qui fait le plus gros de la fonte quand on passe un scénario de quatorze modules à cinq. Du lourd, pour une seule ligne.

Voilà à quoi ressemble le problème sur un vrai scénario d’onboarding. Chaque champ préparé occupe son propre module, l’Iterator et l’agrégateur encadrent un simple nettoyage de texte, et le routeur triple la fin du parcours : trois Set variable, trois envois d’email, pour un traitement dont seule la formulation change. Les quatre fonctions vues jusqu’ici en dissolvent déjà la moitié, le routeur avec if() et switch(), l’Iterator et l’agrégateur avec map(). Les suivantes s’occupent du reste.
formatDate(), afficher une date sans se faire piéger par le fuseau
Les tableaux domptés, place aux dates, le terrain le plus glissant de Make. Le cas : l’email de confirmation d’un rendez-vous, où « 2026-09-14T08:30:00Z » doit devenir « 14/09/2026 à 10:30 ». La fonction formatDate(date; format; [fuseau]) fait la conversion :
{{formatDate(1.date_rdv; "DD/MM/YYYY à HH:mm"; "Europe/Paris")}}
Tout se joue dans le troisième paramètre, optionnel, et c’est précisément son caractère optionnel qui fait le piège. La documentation est claire : en son absence, la conversion utilise le fuseau configuré dans ton organisation Make, silencieusement. Tant que ton organisation est réglée sur Paris et tes clients aussi, rien ne se voit. Le jour où le scénario tourne pour un client à la Réunion, ou le jour où quelqu’un change le réglage de l’organisation, tous les horaires se décalent d’un coup, sans erreur nulle part. Écris le fuseau explicitement, au format de la base TZ (Europe/Paris, Indian/Reunion), sur chaque date destinée à des yeux humains. Et souviens-toi que le décalage Paris-UTC change deux fois par an : un fuseau nommé gère les heures d’été et d’hiver tout seul, un décalage écrit en dur comme +01:00 se trompe six mois sur douze.
La fonction sœur parseDate(texte; format; [fuseau]) fait le chemin inverse, du texte vers une vraie date, avec les mêmes règles de fuseau.
parseNumber(), lire un montant français sans le casser
Le piège des dates a un jumeau côté nombres, et il vise directement les francophones. Un formulaire envoie « 1 756,45 » et le module suivant doit calculer dessus. Traité comme du texte, le calcul échoue ou, pire, produit un résultat faux sans broncher. La fonction parseNumber(nombre; separateur decimal) convertit proprement, à condition de lui dire quel caractère joue le rôle de virgule :
{{parseNumber(1.montant; ",")}}
L’exemple de la documentation officielle utilise justement un nombre au format français, 1 756,456 avec la virgule en séparateur, signe que le cas est connu. Le piège tient dans le croisement des conventions : un montant français parsé avec le point en séparateur, ou un montant anglo-saxon 1,756.45 parsé avec la virgule, produit un nombre différent de plusieurs ordres de grandeur, et aucune erreur ne te préviendra. Un devis multiplié par mille, ambiance garantie en réunion. Fixe la convention à l’entrée du scénario, une fois, et fais confiance au type nombre partout ensuite.
replace() avec les regex, nettoyer sans module de parsing
Après les nombres mal formés, les textes mal formés, et le champion toutes catégories : le numéro de téléphone saisi par un humain. « 06 12 34 56 78 », « 06.12.34.56.78 », « +33 6 12 34 56 78 ». La fonction replace(texte; recherche; remplacement) accepte, d’après la documentation, une expression régulière entre barres obliques comme chaîne de recherche, avec les drapeaux g, i et m :
{{replace(1.telephone; /[^0-9+]/g; emptystring)}}
L’expression retire tout ce qui n’est ni un chiffre ni un signe plus, en un seul passage grâce au drapeau g. Le mot-clé emptystring désigne la chaîne vide de Make. La grappe remplacée : le module Text Parser et sa configuration, pour chaque nettoyage.
Le remplacement sait aussi réutiliser ce qu’il capture, avec $1, $2 pour les groupes entre parenthèses et $& pour la correspondance entière. Un détail documenté fera gagner une heure à quelqu’un : les groupes nommés provoquent une erreur. Si tu recycles une regex écrite ailleurs avec la syntaxe des groupes nommés, Make la rejettera ; repasse aux groupes numérotés et tout rentre dans l’ordre. Une heure d’arrachage de cheveux évitée, gratos.
split() et join(), découper et recoudre
Les regex impressionnent, mais la moitié des manipulations de texte se règlent avec deux fonctions plus simples. Le cas : un champ « Dupont, Marie » à retourner en « Marie Dupont ». La fonction split(texte; separateur) découpe en tableau, get() pioche dedans, et l’ordre se réassemble :
{{get(split(1.nom_complet; ", "); 2)}} {{get(split(1.nom_complet; ", "); 1)}}
Le deuxième élément d’abord, le premier ensuite, et l’indexation à partir de 1 vue chez get() s’applique ici au grand jour. La fonction inverse join(tableau; separateur) recolle un tableau en texte, comme dans l’exemple de map(). À elles deux, elles couvrent la quasi-totalité des « il faut juste réarranger ce champ » qui, en modules, mobiliseraient un Text Parser ou un Set Variables de plus.
toArray() et toCollection(), convertir sans module
Réarranger un texte est une chose, changer la forme même de la donnée en est une autre, et c’est là qu’intervient le duo le moins connu de cette liste. Les API renvoient tantôt des collections, des objets à clés fixes, tantôt des tableaux d’objets, et Make ne les traite pas pareil. Le cas classique : les champs personnalisés d’un CRM arrivent en tableau de paires {nom, valeur}, et tu veux la valeur du champ « budget » sans dérouler tout le tableau.
toCollection(tableau; cle; valeur) transforme, d’après la documentation, un tableau d’objets à paires clé-valeur en collection, que get() peut alors interroger par nom :
{{get(toCollection(1.champs_personnalises; "nom"; "valeur"); "budget")}}
La fonction miroir toArray(collection) fait le chemin inverse, une collection devient un tableau de petites collections clé-valeur, ce qui permet de passer un objet aux clés imprévisibles dans un Iterator ou un map(). La grappe économisée est ici la plus laide du catalogue : les montages à base d’Iterator plus filtre sur le nom du champ, qui consomment une opération par champ personnalisé parcouru, sur chaque exécution.
length() et contains(), tester avant d’agir
Les deux dernières fonctions de la liste sont des sentinelles : elles ne transforment rien, elles vérifient. length(texte) renvoie la longueur d’un texte, contains(texte; recherche) dit si une chaîne s’y trouve. Leur poste de garde naturel : les filtres et les conditions, pour ne déclencher un traitement que lorsqu’il se justifie.
{{if(contains(join(1.produits; ","); "formation-avancee"); "oui"; "non")}}
{{if(length(1.commentaire) > 0; 1.commentaire; "Aucun commentaire client.")}}
La première expression vérifie qu’un produit précis figure dans la commande, en recollant d’abord le tableau en texte avec join(), puisque contains() travaille sur du texte : le détour rend le comportement prévisible quelle que soit la forme de l’entrée. La seconde évite d’insérer un bloc vide dans un document. Modestes en apparence, ces gardes remplacent les filtres posés « au cas où » sur le canvas, et chaque filtre retiré est un module de moins à traverser.

Le même scénario, une fois toutes ces fonctions appliquées : cinq modules au lieu de quatorze, et le routeur disparu. Le panneau ouvert montre où est passée la logique, dans un unique module Set multiple variables où les variables sujet et accroche se construisent avec des if() imbriqués sur le score. Le canvas ne raconte plus les décisions, les champs s’en chargent. Ce déplacement a ses contreparties, et elles se paient toujours au même endroit : les quatre pièges qui suivent.
Ce qui va te bloquer
Quatre pièges transversaux reviennent, quelle que soit la fonction.
L’imbrication qui devient illisible. Deux niveaux d’imbrication se lisent, join(map(...); ", ") reste limpide. Au troisième niveau, l’expression devient une énigme, et au quatrième, une dette : personne, toi compris dans trois mois, ne modifiera cette expression sans la casser. La parade consiste à décomposer dans un module Set Variables : une variable pour l’étape intermédiaire, nommée clairement, puis l’expression finale qui s’appuie dessus.
La variable invisible dans son propre module. La parade précédente a son propre piège, corroboré par de nombreux fils de la communauté Make : dans un module Set Multiple Variables, une variable définie plus haut dans la liste ne peut pas être référencée par une variable définie plus bas dans le même module. Le test pour t’en convaincre tient en une minute : deux variables dans le même module, la seconde référençant la première, et la seconde sort vide. Enchaîne deux modules Set Variables, le second lisant les sorties du premier, et la chaîne fonctionne.
Le vide qui voyage. Le get() sur index absent, l’ifempty() oublié sur un champ optionnel, le map() dont le filtre ne matche rien : tous produisent du vide sans erreur, et ce vide traverse tranquillement les modules suivants jusqu’à provoquer un symptôme loin de sa cause. Prends le réflexe inverse du débogage habituel : devant un champ vide en bout de scénario, remonte le flux jusqu’à la première expression qui touche cette donnée, elle est presque toujours la coupable.
La regex recyclée qui explose. Une expression régulière copiée depuis un autre outil, avec des groupes nommés, provoque une erreur dans replace(). Le message ne dit pas clairement pourquoi ; maintenant tu le sais : groupes numérotés uniquement, $1 et $2 en remplacement.
Les limites
L’inline a un plafond, et le connaître évite de transformer une bonne pratique en obfuscation. Une expression de six lignes tassée dans un champ de module a tous les défauts d’un module en trop et aucun de ses avantages : elle ne se commente pas, ne se nomme pas, ne se teste pas isolément. Un module, lui, porte un nom sur le canvas et se désactive d’un clic pour tester. La règle de partage est simple : la logique d’une ligne ou deux vit dans le champ, la logique qui raconte une histoire vit dans des modules nommés. Make fait d’ailleurs évoluer cet arbitrage avec ses nouveaux modules de branchement conditionnel If-else et Merge, qui ont leur propre examen.
L’autre limite est collective. Une expression inline n’apparaît pas sur le canvas : ton collègue qui ouvre le scénario voit cinq modules sobres et rien des dix décisions cachées dans les champs. Sur un scénario partagé, documente les expressions non triviales dans les notes du module, sinon la lisibilité gagnée pour toi devient de l’opacité pour l’équipe. Cet équilibre entre assembler du visuel et écrire du code en miniature rejoint un débat plus large, celui du choix entre no-code et code généré : plus tu écris d’expressions, plus ton no-code ressemble à du code, avec ses exigences.
La table de correspondance, pour refactoriser ton scénario
En guise de récapitulatif opérationnel, voici la table à garder ouverte pendant la refactorisation d’un scénario existant. La colonne de droite compte les modules retirés du canvas ; l’économie d’opérations réelle dépend de tes volumes, et les grappes à base d’Iterator sont celles qui pèsent le plus lourd.
| La grappe sur ton canvas | La fonction qui la remplace | Modules en moins |
|---|---|---|
| Routeur + 2 filtres + 2 modules jumeaux | if() dans le module unique |
4 |
| Routeur + N routes + N Set Variables | switch() |
2N |
| Iterator + filtre « premier élément » | get(tableau; 1) |
2, plus une opération par élément |
| Iterator + filtre + agrégateur | map() + join() |
3, plus une opération par élément |
| Set Variables de reformatage de date | formatDate() dans le champ cible |
1 |
| Text Parser de nettoyage | replace() avec regex |
1 |
| Iterator + filtre sur champs personnalisés | toCollection() + get() |
2, plus une opération par champ |
| Filtre « au cas où » avant un module | if() avec length() ou contains() |
1 |
Refactorise un scénario à la fois, et garde l’ancien en copie désactivée le temps de valider trois ou quatre exécutions réelles : le gain de lisibilité est immédiat, la confiance se gagne sur les exécutions.
Le vrai bénéfice se mesure au moment du débogage suivant : cinq modules à inspecter au lieu de quatorze, des expressions qui disent leur intention là où la donnée circule, et une facture d’opérations qui a fondu sans toucher au résultat. Si tu as une expression fétiche qui t’a sauvé un scénario, viens la partager sur le hub lesnocodeurs : les bibliothèques d’expressions qui circulent entre makers valent souvent mieux que la documentation. Ramène ta meilleure, la collection est ouverte.


