Automatiser les feuilles de calcul avec Claude Code: CSV, Google Sheets API et Apps Script
Automatisez CSV, Google Sheets API et Apps Script avec Claude Code, scripts copiables et pièges à éviter.
L’automatisation des feuilles de calcul paraît simple, mais elle touche souvent les ventes, les formulaires de contact, les dépenses publicitaires, les factures et les KPI de contenu. Une seule règle d’import cassée peut produire un mauvais chiffre d’affaires, une mauvaise priorité commerciale ou un mauvais arbitrage marketing.
Claude Code est utile ici parce qu’il travaille dans le dépôt, pas seulement dans une cellule. Il peut créer un script de résumé CSV, un script qui ajoute une ligne avec Google Sheets API, une automatisation Apps Script, puis rendre une note de vérification avec les fichiers modifiés, les commandes exécutées et les risques restants.
Ce guide suit un chemin progressif: résumé CSV local, écriture dans Google Sheets, puis classification de leads avec Apps Script. Pour le cadre de travail, lisez aussi les conseils de productivité Claude Code et le workflow de vérification. Les références officielles à garder ouvertes sont Claude Code docs, Claude Code CLI usage, Google Sheets API Node.js quickstart, Apps Script Sheets guide et SheetJS docs.
Définir la frontière des données
Le premier choix n’est pas la bibliothèque. Il faut décider quelle table est la source de vérité. Si un même montant peut être corrigé dans un CSV, une feuille Google, un CRM et un outil comptable, l’automatisation accélère surtout la confusion. Avant de demander du code à Claude Code, séparez l’entrée brute, la couche nettoyée et le rapport lisible.
| Couche | Rôle | Exemple | Tâche pour Claude Code |
|---|---|---|---|
| Raw | Données d’entrée non modifiées | formulaires, CSV de paiement, exports publicitaires | import, validation, lignes en erreur |
| Clean | Données typées et normalisées | dates, montants, statuts | normalisation, dédoublonnage, colonnes obligatoires |
| Report | Sortie pour humains | revenu mensuel, priorité des leads, KPI | agrégats, CSV pour graphiques, alertes |
L’erreur classique consiste à écrire directement dans l’onglet Report. Cet onglet contient souvent des couleurs, formules, notes, cellules fusionnées et colonnes gelées. Une machine préfère des en-têtes stables et des lignes ajoutées sans mise en forme. Écrivez plutôt dans Raw ou Clean, puis laissez les formules, les tableaux croisés, Looker Studio ou un autre script produire le rapport.
Exemple 1: résumer un CSV de ventes
Commencez sans authentification Google. Vous obtenez une base que Claude Code peut modifier et que le reviewer peut exécuter localement.
Créez data/sales.csv.
date,channel,product,amount,status
2026-05-01,organic,Claude Code Cheatsheet,0,won
2026-05-02,gumroad,Prompt Template Pack,2980,won
2026-05-08,consultation,Team Workshop,120000,won
2026-05-11,gumroad,Prompt Template Pack,2980,refunded
2026-06-01,organic,Claude Code Cheatsheet,0,won
2026-06-02,consultation,Implementation Review,80000,won
Enregistrez scripts/summarize-sales.mjs.
import { mkdir, readFile, writeFile } from "node:fs/promises";
import path from "node:path";
const inputPath = process.argv[2] ?? "data/sales.csv";
const outputPath = process.argv[3] ?? "out/monthly-summary.csv";
function parseCsvLine(line) {
const cells = [];
let current = "";
let inQuotes = false;
for (let index = 0; index < line.length; index += 1) {
const char = line[index];
const next = line[index + 1];
if (char === '"' && inQuotes && next === '"') {
current += '"';
index += 1;
continue;
}
if (char === '"') {
inQuotes = !inQuotes;
continue;
}
if (char === "," && !inQuotes) {
cells.push(current.trim());
current = "";
continue;
}
current += char;
}
cells.push(current.trim());
return cells;
}
function parseCsv(source) {
const lines = source.trim().split(/\r?\n/).filter(Boolean);
const headers = parseCsvLine(lines[0]);
return lines.slice(1).map((line) => {
const cells = parseCsvLine(line);
return Object.fromEntries(headers.map((header, index) => [header, cells[index] ?? ""]));
});
}
function toMonth(dateValue) {
const date = new Date(`${dateValue}T00:00:00Z`);
if (Number.isNaN(date.getTime())) {
throw new Error(`Invalid date: ${dateValue}`);
}
return dateValue.slice(0, 7);
}
const rows = parseCsv(await readFile(inputPath, "utf8"));
const summary = new Map();
for (const row of rows) {
if (row.status !== "won") continue;
const amount = Number(row.amount);
if (!Number.isFinite(amount)) {
throw new Error(`Invalid amount: ${JSON.stringify(row)}`);
}
const key = `${toMonth(row.date)},${row.channel}`;
const current = summary.get(key) ?? { month: toMonth(row.date), channel: row.channel, deals: 0, revenue: 0 };
current.deals += 1;
current.revenue += amount;
summary.set(key, current);
}
const output = [
"month,channel,deals,revenue",
...[...summary.values()]
.sort((a, b) => `${a.month}:${a.channel}`.localeCompare(`${b.month}:${b.channel}`))
.map((row) => `${row.month},${row.channel},${row.deals},${row.revenue}`),
].join("\n");
await mkdir(path.dirname(outputPath), { recursive: true });
await writeFile(outputPath, `${output}\n`, "utf8");
console.log(`Wrote ${outputPath} (${summary.size} groups)`);
Exécutez-le.
mkdir -p data out scripts
node scripts/summarize-sales.mjs data/sales.csv out/monthly-summary.csv
cat out/monthly-summary.csv
Le point important est l’échec visible. Un montant vide, une date invalide ou un statut inattendu ne doit pas devenir zéro en silence. Ensuite, demandez à Claude Code d’ajouter les numéros de ligne, un CSV de rejet et des tests pour les remboursements.
Exemple 2: ajouter des leads avec Google Sheets API
Pour une équipe, un compte de service est souvent plus auditable qu’un OAuth personnel. Activez Sheets API dans Google Cloud, créez une clé JSON, partagez la feuille avec l’adresse du compte de service et créez un onglet Raw avec createdAt,source,subject,amount,status.
npm install googleapis
export GOOGLE_APPLICATION_CREDENTIALS="$PWD/service-account.json"
export SHEET_ID="your-google-sheet-id"
Créez scripts/append-lead-to-sheet.mjs.
import { google } from "googleapis";
const { GOOGLE_APPLICATION_CREDENTIALS, SHEET_ID } = process.env;
if (!GOOGLE_APPLICATION_CREDENTIALS) {
throw new Error("GOOGLE_APPLICATION_CREDENTIALS is required");
}
if (!SHEET_ID) {
throw new Error("SHEET_ID is required");
}
const auth = new google.auth.GoogleAuth({
keyFile: GOOGLE_APPLICATION_CREDENTIALS,
scopes: ["https://www.googleapis.com/auth/spreadsheets"],
});
const sheets = google.sheets({ version: "v4", auth });
const source = process.argv[2] ?? "web";
const subject = process.argv[3] ?? "Claude Code consultation";
const amount = Number(process.argv[4] ?? 0);
if (!Number.isFinite(amount)) {
throw new Error(`Invalid amount: ${process.argv[4]}`);
}
await sheets.spreadsheets.values.append({
spreadsheetId: SHEET_ID,
range: "Raw!A:E",
valueInputOption: "USER_ENTERED",
insertDataOption: "INSERT_ROWS",
requestBody: {
values: [[new Date().toISOString(), source, subject, amount, "new"]],
},
});
console.log("Appended lead row");
Exemple d’exécution:
node scripts/append-lead-to-sheet.mjs newsletter "Spreadsheet automation review" 50000
Quand Claude Code modifie ce fichier, demandez-lui de préserver les noms d’environnement, la plage cible, l’ordre des colonnes et la règle de non-commit des secrets. Le JSON du compte de service ne doit pas apparaître dans Git, les tickets, les documents ou les prompts.
Exemple 3: classer les ventes et demandes avec Apps Script
Apps Script est pratique si le workflow vit déjà dans Google Workspace. Il peut réagir à un formulaire, écrire dans Sheets et envoyer des mails sans serveur séparé. Il existe toutefois des quotas, des règles de trigger et des permissions. Avant un usage à fort volume, consultez Apps Script quotas.
Collez ce code dans l’éditeur Apps Script et configurez un trigger installable de soumission de formulaire pour onFormSubmit.
const SETTINGS = {
sheetName: "Leads",
notifyTo: "sales@example.com",
minAmountForHighPriority: 100000,
};
function onOpen() {
SpreadsheetApp.getUi()
.createMenu("Lead Ops")
.addItem("Rebuild lead status", "rebuildLeadStatus")
.addToUi();
}
function onFormSubmit(event) {
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName(SETTINGS.sheetName) || spreadsheet.insertSheet(SETTINGS.sheetName);
ensureHeader_(sheet);
const values = event && event.namedValues ? event.namedValues : {};
const company = first_(values, "Company");
const email = first_(values, "Email");
const plan = first_(values, "Plan");
const budget = Number(first_(values, "Budget") || 0);
const priority = classifyLead_(plan, budget);
sheet.appendRow([new Date(), company, email, plan, budget, priority, "new"]);
if (priority === "high") {
MailApp.sendEmail({
to: SETTINGS.notifyTo,
subject: `High priority lead: ${company}`,
body: `Company: ${company}\nEmail: ${email}\nPlan: ${plan}\nBudget: ${budget}`,
});
}
}
function rebuildLeadStatus() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SETTINGS.sheetName);
if (!sheet) throw new Error(`Sheet not found: ${SETTINGS.sheetName}`);
ensureHeader_(sheet);
const values = sheet.getDataRange().getValues();
for (let rowIndex = 1; rowIndex < values.length; rowIndex += 1) {
const row = values[rowIndex];
const plan = String(row[3] || "");
const budget = Number(row[4] || 0);
const priority = classifyLead_(plan, budget);
sheet.getRange(rowIndex + 1, 6).setValue(priority);
}
}
function ensureHeader_(sheet) {
const header = ["createdAt", "company", "email", "plan", "budget", "priority", "status"];
const current = sheet.getRange(1, 1, 1, header.length).getValues()[0];
if (current.join("") === "") {
sheet.getRange(1, 1, 1, header.length).setValues([header]);
sheet.setFrozenRows(1);
}
}
function classifyLead_(plan, budget) {
const normalizedPlan = String(plan).toLowerCase();
if (budget >= SETTINGS.minAmountForHighPriority || normalizedPlan.includes("team")) {
return "high";
}
if (budget >= 30000) {
return "medium";
}
return "low";
}
function first_(namedValues, key) {
const value = namedValues[key];
return Array.isArray(value) ? value[0] || "" : "";
}
Adaptez les noms de champs au formulaire réel. Si le formulaire est en français, remplacez Company, Plan et Budget par les libellés exacts et demandez à Claude Code de ne pas écrire de données personnelles dans les logs.
Prompt pour Claude Code
Un bon prompt limite le travail et précise la preuve attendue.
You are working on spreadsheet automation for this repository.
Goal:
- Import sales CSV rows from data/sales.csv.
- Write a monthly summary to out/monthly-summary.csv.
- Add a Google Sheets append script for the Raw tab.
Scope:
- You may edit scripts/summarize-sales.mjs and scripts/append-lead-to-sheet.mjs.
- You may add small tests or sample CSV files if needed.
- Do not edit content files, product links, analytics, or deployment settings.
Rules:
- Do not commit credentials.
- Use environment variables for SHEET_ID and GOOGLE_APPLICATION_CREDENTIALS.
- Fail loudly on invalid dates, invalid amounts, and missing required columns.
- Keep the code copy-paste runnable with Node.js 20 or later.
Verification:
- Run node --check on every script you edit.
- Run the CSV summary against data/sales.csv.
- For Google Sheets API, verify syntax locally and list the manual credential checks.
- Return changed files, commands run, output summary, and remaining risks.
Commandes de vérification:
node --check scripts/summarize-sales.mjs
node scripts/summarize-sales.mjs data/sales.csv out/monthly-summary.csv
node --check scripts/append-lead-to-sheet.mjs
git diff -- scripts/summarize-sales.mjs scripts/append-lead-to-sheet.mjs
En équipe, placez cette base dans CLAUDE.md et reliez-la au guide des permissions Claude Code.
Cas d’usage réels
Le premier cas est le reporting mensuel du revenu. Combinez les exports Gumroad, Stripe, factures manuelles et inscriptions gratuites. Les remboursements sont exclus, les leads gratuits restent dans le volume, et les noms de produits sont normalisés.
Le deuxième cas est le tri des demandes. Budget, taille d’équipe, plan choisi et domaine client existant peuvent devenir des règles. Elles doivent rester explicables: “budget supérieur à 100000 yens ou plan team” se relit; “semble prometteur” ne se relit pas.
Le troisième cas est le suivi des articles et publicités. Une feuille peut contenir slug, date de publication, clics de recherche, clics CTA, clics produit et débuts de formulaire. Pour les noms d’événements, reliez ce travail au guide analytics Claude Code.
Le quatrième cas est le contrôle avant facturation. Comparez les journaux de livraison avec le CSV de factures et écrivez seulement les écarts dans une feuille de revue. Ne commencez pas par l’envoi automatique des factures.
Pièges à éviter
Le premier piège est l’instabilité des en-têtes. Si Amount, amount et Revenu coexistent, un script peut réussir tout en ignorant des lignes. Demandez une vérification stricte des colonnes obligatoires.
Le deuxième piège est de traiter Sheets comme une base de données. Sheets est excellent pour la collaboration et la revue, pas pour les transactions, verrous, permissions canoniques ou écritures massives. Les paiements et accès doivent rester dans la base applicative.
Le troisième piège est la fuite de secrets. Le JSON d’un compte de service ne doit jamais entrer dans les prompts, tickets, docs ou commits. Écrivez que Claude Code ne doit ni lire, ni afficher, ni committer les secrets.
Le quatrième piège est l’oubli des triggers Apps Script. Coller le code ne suffit pas. Vérifiez le trigger installable, l’utilisateur d’exécution, la première autorisation, le quota mail et la notification d’erreur.
Le cinquième piège est de regarder seulement le total final. Chaque rapport devrait afficher lignes lues, lignes exclues, erreurs et heure de dernière mise à jour.
CTA: passer du script à l’exploitation
L’automatisation devient fiable lorsque prompts, permissions et vérification sont répétables. Commencez avec la fiche gratuite Claude Code pour les commandes et habitudes de revue. Pour des packs de prompts et modèles CLAUDE.md, consultez les produits ClaudeCodeLab.
Si votre équipe gère ventes, leads, publicités ou factures dans des feuilles, définissez la frontière des identifiants et l’approbation humaine avant d’ajouter des scripts. Pour construire ce cadre, utilisez la formation et consultation Claude Code.
Résultat après essai
Dans le workflow de Masa, le plus utile n’a pas été de brancher l’API Sheets en premier, mais de figer les en-têtes CSV, les règles d’exclusion et le comportement en erreur. Apps Script a bien fonctionné pour classer les leads, mais des règles de notification vagues ont généré trop d’e-mails. L’approche stable consiste à concevoir Raw, Clean et Report, puis à demander à Claude Code de petites implémentations vérifiées.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Workflow Obsidian vers CLAUDE.md avec Claude Code
Transformer des notes Obsidian en notes CLAUDE.md concises pour reprendre les sessions sans réexpliquer.
Claude Code Revenue CTA Routing : relier articles, PDF, Gumroad et consultation
Un workflow Claude Code pour orienter les lecteurs vers PDF gratuit, Gumroad ou consultation selon l'intention.
Règles de handoff Claude Code en équipe: preuves, permissions, rollback et revenus
Un format concret pour transmettre un travail Claude Code avec preuves, permissions, rollback, PDF gratuit, Gumroad et consultation.