D’un outil interne au SaaS : automatiser le téléchargement des relevés bancaires
Nous avons créé un script pour télécharger automatiquement nos relevés bancaires Wise. C’est une tâche réalisable en un après-midi. La question plus intéressante, qui a demandé beaucoup plus de temps, était de savoir si cet outil pouvait servir à d’autres entreprises confrontées au même problème, et comment effectuer cette transition de façon responsable. Le passage d’un script en ligne de commande sur l’ordinateur portable d’un développeur à un service conteneurisé avec notifications par e-mail a révélé des décisions qui méritent d’être documentées, notamment pour les équipes qui envisagent de transformer une automatisation interne en produit.
Le problème initial
Wise propose une API d’accès aux données des comptes, mais la plupart des équipes financières se connectent encore à l’interface web pour télécharger manuellement un relevé CSV à la fin de chaque mois. Pour un compte dans une seule devise, cela prend deux minutes. Avec plusieurs devises et plusieurs comptes Wise, une configuration fréquente dans les entreprises aux flux de paiement régionaux, cela devient une tâche récurrente que quelqu’un doit penser à effectuer, réaliser systématiquement et archiver correctement.
L’API Wise fournit les points de terminaison nécessaires : liste des profils, soldes par devise et exports de relevés en CSV ou PDF pour n’importe quelle période. L’authentification utilise un jeton d’accès personnel généré dans le tableau de bord développeur de Wise. Si son périmètre est correctement défini, il permet uniquement de lire les données du compte. Son stockage et son utilisation ne présentent donc pas le même profil de risque que ceux d’un jeton permettant d’initier des virements.
Notre première implémentation comptait environ 80 lignes de Python. Elle lisait les identifiants d’authentification dans les variables d’environnement, parcourait les profils et les soldes par devise, préparait les demandes de relevés du mois précédent et écrivait les fichiers dans un répertoire local. Nous la lancions manuellement. Cela suffisait à nos besoins à l’époque.
Du script au service planifié
Passer d’une exécution manuelle à une exécution automatique introduit d’autres préoccupations. Un échec silencieux lors d’une exécution manuelle se remarque immédiatement. Le même échec dans un script planifié le premier de chaque mois peut passer inaperçu pendant plusieurs mois, jusqu’à ce qu’un audit révèle des lacunes dans les archives de relevés.
Nous avons placé le script dans un conteneur Docker avec un point d’entrée simple et ajouté une couche d’exécution qui envoie un e-mail à la fin, en cas de réussite comme d’échec. Il récapitule les comptes et devises traités, le nombre de fichiers téléchargés et leur taille. En cas d’échec, il contient la sortie d’erreur. Cet investissement minimal en observabilité change le contrat opérationnel : l’automatisation est supervisée même lorsqu’elle fonctionne sans intervention.
La planification passe par GitHub Actions, plutôt que par cron dans le conteneur. Un déclencheur schedule lance un flux de travail au début de chaque mois ; une planification cron seule ne permet pas de cibler les jours ouvrables. Pour exclure les week-ends et les jours fériés, il faut donc ajouter une vérification de la date dans le flux de travail. Celui-ci récupère le dépôt, construit l’image Docker si elle a changé, exécute le conteneur avec les secrets injectés depuis GitHub Secrets et téléverse les fichiers de sortie comme artefacts du flux de travail. Conservés pendant 90 jours, ils constituent des archives récupérables indépendantes du stockage local.
GitHub Actions présente un avantage pratique sur une tâche cron de serveur : la visibilité. L’historique montre chaque exécution, sa durée, son code de sortie et les artefacts produits. Les journaux d’une tâche cron peuvent facilement passer inaperçus, et la tâche dépend de la disponibilité du serveur. Pour une opération mensuelle, un historique auditable associé à une définition de flux de travail versionnée justifie le faible effort de configuration supplémentaire.
Ce qu’exige réellement une architecture multi-tenant
Après plusieurs mois de fonctionnement fiable de la version conteneurisée, des collègues d’autres entreprises ont demandé s’ils pouvaient l’utiliser. La question paraît simple, mais permettre à d’autres d’exécuter votre outil recouvre des modèles opérationnels très différents.
Le modèle le plus simple consiste à partager le dépôt et la documentation. Les utilisateurs exécutent l’outil dans leur propre environnement GitHub Actions ou Docker, sans assistance de votre part. C’est une distribution open source, pas un produit SaaS. Toute la charge d’exploitation reste à la charge de l’utilisateur.
L’étape suivante consiste à héberger l’outil et à laisser les utilisateurs fournir leurs jetons API Wise dans une interface de configuration. Vous détenez alors leurs identifiants d’authentification, ce qui crée des obligations de sécurité et de conformité d’une autre nature que pour une automatisation personnelle. Il faut déterminer comment ils sont stockés, qui y accède, ce qui se passe si le stockage est compromis et quelle est votre responsabilité si quelqu’un accède au compte Wise d’un utilisateur par votre plateforme.
Viennent ensuite la facturation, l’assistance, les engagements de niveau de service et l’exploitation d’une infrastructure pour plusieurs utilisateurs. Rien d’insurmontable, mais chaque élément exige de décider du travail d’ingénierie à investir et des coûts d’exploitation récurrents que vous acceptez d’assumer.
L’évaluation du modèle SaaS
Nous avons recensé les exigences d’une version multi-tenant minimale et chiffré chacune sans minimiser l’effort. La seule gestion des identifiants d’authentification — stockage sécurisé des jetons API Wise, interface de gestion et contrôles empêchant les accès entre clients — représente une semaine d’ingénierie avant même de traiter le téléchargement des relevés. Ajoutez l’authentification utilisateur, la facturation, un service d’envoi d’e-mails avec gestion des désabonnements et la supervision des échecs de tâches par client : vous obtenez un produit exigeant un investissement continu pour être maintenu en sécurité.
Le marché de cet outil est également limité. Les entreprises assez grandes pour vouloir automatiser leurs relevés disposent souvent déjà d’un logiciel comptable intégré à Wise ou d’une équipe financière ayant résolu le problème. Le marché potentiel se situe entre les deux : des entreprises assez grandes pour ressentir cette difficulté, mais sans système comptable intégré.
Nous avons conclu que cet outil ne constituait pas un bon candidat SaaS pour notre équipe à ce stade. Les revenus potentiels ne justifiaient pas l’investissement en ingénierie et en exploitation. La distribution open source répond au besoin réel sans créer d’obligations que nous ne pouvons pas assumer durablement.
Ce que nous avons conservé et ce que nous avons changé
L’outil interne fonctionne toujours. Nous l’avons progressivement étendu pour produire des PDF en plus des CSV, envoyer les relevés directement par e-mail plutôt que de dépendre de la récupération des artefacts et accepter des périodes configurables. Il peut ainsi être lancé manuellement pour des demandes ponctuelles sans modifier l’exécution mensuelle planifiée.
Le flux de travail GitHub Actions est devenu le mode de déploiement de référence. Le README du dépôt contient assez de détails pour qu’une personne n’ayant pas utilisé l’outil depuis six mois comprenne son fonctionnement et son exploitation. Cette discipline s’applique à toute automatisation interne : préparez vos outils comme si vous deviez les transmettre à quelqu’un d’autre, car cela finira par arriver.
La leçon la plus durable concerne l’écart entre « cela fonctionne pour nous » et « cela fonctionne pour les autres ». Les outils internes épousent vos contraintes : pratiques de gestion des identifiants d’authentification, conventions de stockage et infrastructure e-mail. Les rendre utilisables par d’autres ne se limite pas à ajouter un fichier de configuration. Il faut supprimer la dépendance à des hypothèses qui ne deviennent visibles que lorsqu’un autre utilisateur s’y heurte.