Automatiser avec Apps Script et Workspace
Google Apps Script combiné à l'APIAPIApplication Programming Interface : une interface standardisée qui permet aux applications de communiquer et d'échanger des données sans connaître leur fonctionnement interne respectif.Voir la définition complète → Gemini peut transformertransformerUn Transformer est une architecture de réseau de neurones qui utilise le self-attention pour traiter des séquences en parallèle. Elle est au cœur de la plupart des modèles de langage et d'IA générative actuels.Voir la définition complète → Workspace : d'un endroit où vous travaillez, il devient un endroit qui travaille pour vous. Labelliser automatiquement les emails entrants selon l'intention, rédiger des réponses, ou compiler un rapport hebdomadaire dans un Sheet depuis des lignes brutes sans que vous y touchiez. Ce qui débloque tout, c'est qu'Apps Script vit déjà à l'intérieur de Gmail, Sheets, Drive et Calendar, avec un accès authentifié à vos données, et que Gemini lui apporte le jugement. Vous branchez les deux avec un seul appel HTTP.
Cette leçon montre le câblage, un exemple concret qui fonctionne, et les garde-fous qui comptent dès lors que le script tourne sans surveillance sur un trigger.
Pourquoi Apps Script est la bonne colle
Apps Script est le runtime JavaScript serverless de Google intégré à Workspace. Vous ne provisionnez rien. Un script peut lire vos threads Gmail (GmailApp), écrire dans une feuille de calcul (SpreadsheetApp), et s'exécuter sur un trigger temporel, le tout avec les permissions de votre compte.
Ce qu'il n'a pas nativement, c'est le raisonnement. C'est la partie Gemini. Vous appelez l'API Gemini depuis le script avec `UrlFetchApp`, vous lui envoyez du texte, et vous récupérez une sortie structurée.
Deux façons d'authentifier l'appel :
- Clé API depuis [Google AI Studio](https://aistudio.google.com) : le plus rapide pour démarrer. Bien pour les automatisations personnelles et les prototypes.
- Vertex AI avec un service account : le bon choix quand l'automatisation appartient à une organisation, nécessite des contrôles IAM, une résidence des donnéesrésidence des donnéesL'exigence de stocker et traiter les données physiquement dans un pays ou une région précise, souvent pour des raisons légales ou contractuelles.Voir la définition complète → ou des périmètres VPC. Voir cloud.google.com/vertex-ai.
Pour un rapport hebdomadaire personnel, la voie clé API convient. Nous l'utiliserons et signalerons où vous basculeriez.
L'exemple : un rapport hebdomadaire des emails support
L'objectif : chaque lundi à 7h, scanner les emails de la semaine passée labellisés `support`, faire classer chacun par Gemini selon la catégorie et l'urgence, et ajouter une ligne de synthèse propre à un Sheet de suivi.
L'astuce qui rend cela fiable, c'est la sortie structurée : vous demandez à Gemini de renvoyer du JSON conforme à un schémamaUtiliser un logiciel pour automatiser les tâches et campagnes marketing répétitives, afin de personnaliser à grande échelle sur des canaux comme l'email, le web et le social.Voir la définition complète → plutôt que de la prose. L'API Gemini prend en charge un responseSchema, ce qui contraint le modèle à produire du JSON valide. Cela supprime l'étape fragile du « parser le paragraphe du modèle ».
L'appel de classification
Voici le cœur : une fonction qui envoie un batch de sujets et d'extraits d'emails et récupère des classifications typées.
const GEMINI_KEY = PropertiesService.getScriptProperties().getProperty('GEMINI_KEY');
const MODEL = 'gemini-2.5-flash';
function classifyEmails(emails) {
const url = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent?key=${GEMINI_KEY}`;
const prompt = 'Classify each support email. Categories: billing, bug, feature_request, other. ' +
'Urgency: low, medium, high.\n\n' +
emails.map((e, i) => `[${i}] Subject: ${e.subject}\nSnippet: ${e.snippet}`).join('\n\n');
const payload = {
contents: [{ parts: [{ text: prompt }] }],
generationConfig: {
responseMimeType: 'application/json',
responseSchema: {
type: 'array',
items: {
type: 'object',
properties: {
index: { type: 'integer' },
category: { type: 'string', enum: ['billing', 'bug', 'feature_request', 'other'] },
urgency: { type: 'string', enum: ['low', 'medium', 'high'] }
},
required: ['index', 'category', 'urgency']
}
}
}
};
const res = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
if (res.getResponseCode() !== 200) {
throw new Error(`Gemini API ${res.getResponseCode()}: ${res.getContentText()}`);
}
const body = JSON.parse(res.getContentText());
return JSON.parse(body.candidates[0].content.parts[0].text);
}Ce dont un ingénieur senior se soucierait :
- La clé vit dans les Script Properties, jamais dans le code source. Définissez-la une fois dans Project Settings, ou avec
PropertiesService.getScriptProperties().setProperty('GEMINI_KEY', '...'). gemini-2.5-flashest le bon niveau ici. Flash est rapide et peu coûteux, et la classification est exactement son terrain de jeu. Réservez Pro aux tâches exigeant un raisonnement plus profond (synthèse longue, jugement multi-étapes difficile). Vérifiez les noms de modèles actuels sur ai.google.dev avant de déployer, car les niveaux évoluent.muteHttpExceptions: truevous permet de lire le corps de l'erreur au lieu d'obtenir une exception générique. Vous voudrez ce texte dans vos logs.- Regroupez les emails dans un seul appel. Envoyer une requête par email consomme du quota et du temps. Un seul prompt avec tous les extraits de la semaine coûte bien moins cher, et le schéma garde les résultats alignés par
index.
Le brancher à Gmail et Sheets
L'orchestration autour de l'appel, c'est de l'Apps Script ordinaire :
function weeklyReport() {
const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const query = `label:support after:${Utilities.formatDate(since, 'GMT', 'yyyy/MM/dd')}`;
const threads = GmailApp.search(query, 0, 50);
const emails = threads.map(t => {
const msg = t.getMessages()[0];
return { subject: msg.getSubject(), snippet: msg.getPlainBody().slice(0, 400) };
});
if (emails.length === 0) return;
const results = classifyEmails(emails);
const sheet = SpreadsheetApp.openById('YOUR_SHEET_ID').getSheetByName('Weekly');
const counts = { billing: 0, bug: 0, feature_request: 0, other: 0, high: 0 };
results.forEach(r => {
counts[r.category]++;
if (r.urgency === 'high') counts.high++;
});
sheet.appendRow([new Date(), emails.length, counts.billing, counts.bug,
counts.feature_request, counts.other, counts.high]);
}Ensuite, crcrLe pourcentage de visiteurs ou de prospects qui réalisent une action attendue (achat, inscription, formulaire de contact), calculé en divisant les conversions par le nombre total d'opportunités.Voir la définition complète →éez un trigger pour qu'il tourne sans surveillance : dans l'éditeur, cliquez sur l'icône horloge (Triggers), ou faites-le une fois en code :
function installTrigger() {
ScriptApp.newTrigger('weeklyReport')
.timeBased().onWeekDay(ScriptApp.WeekDay.MONDAY).atHour(7).create();
}Exécutez installTrigger une fois. À partir de là, `weeklyReport` se déclenche chaque lundi matin sans aucun humain dans la boucle. C'est tout l'intérêt, et c'est aussi précisément là que le risque commence.
Garde-fousGarde-fousRègles et contrôles qui maintiennent un système d'IA dans des limites sûres, légales et conformes à la marque, en bloquant les sorties et actions hors cadre.Voir la définition complète → pour les exécutions sans surveillance
Un script qui tourne pendant que vous dormez, qui détient votre scope Gmail et qui appelle un modèle externe exige de la discipline. Les modes de défaillance sont différents du prompting interactif parce que personne ne regarde la sortie.
1. Limitez le rayon d'action
Cet exemple lit seulement Gmail et ajoute des lignes à un Sheet. Il ne supprime jamais, n'envoie jamais, ne modifie jamais de thread. Gardez vos automatisations en lecture-et-ajout par défaut. Dès qu'un script peut envoyer des emails ou supprimer des fichiers sans surveillance, une mauvaise sortie du modèle ou un bug devient une action irrirrLe taux de rendement interne est le taux d'actualisation qui annule la valeur actuelle nette d'un projet. Il exprime le rendement annualisé attendu d'un investissement.Voir la définition complète →éversible.
Si vous passez ensuite aux réponses automatiques ou au labelling automatique qui déplace du courrier, ajoutez un mode dry-run : écrivez l'action proposée dans un Sheet pendant une semaine et relisez-la avant de laisser le script agir pour de vrai.
2. Ne demandez que les scopes dont vous avez besoin
Apps Script déduit les scopes OAuth des API que vous appelez, mais vous devriez les épingler explicitement dans le manifeste, pour qu'une nouvelle fonction égarée ne puisse pas élargir l'accès silencieusement. Dans appsscript.json :
{
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.external_request"
]
}gmail.readonly signifie que même une version buguée ne peut littéralement pas envoyer ni supprimer. Cette seule ligne est votre garde-fou le plus solide.
3. Ne faites jamais confiance à la sortie du modèle comme flux de contrôle
Le modèle renvoie des catégories. Validez-les contre votre enum avant de les utiliser comme clés d'objet, exactement comme le schéma l'impose. Si une valeur inattendue arrive, loguez-la et passez, plutôt que de faire planter toute l'exécution ou d'écrire n'importe quoi. La sortie structurée rend cela rare, mais la défense en profondeur ne coûte pas cher.
4. Gérez le quota, la latence et les échecs partiels
Les appels UrlFetchApp échouent parfois. Apps Script a aussi des limites de temps d'exécution par run. Enveloppez l'appel API dans un retry avec backoff pour les erreurs transitoires, et concevez le job de sorte qu'un échec du lundi ne perde pas silencieusement les données du lundi :
function fetchWithRetry(url, options, tries = 3) {
for (let i = 0; i < tries; i++) {
const res = UrlFetchApp.fetch(url, options);
if (res.getResponseCode() < 500) return res;
Utilities.sleep(1000 * Math.pow(2, i));
}
throw new Error('Gemini API failed after retries');
}5. Surveillez le coût et la confidentialité
Flash est peu coûteux, mais une boucle incontrôlée ou un trigger mal configuré pour tourner toutes les heures, ça chiffre. Mettez une alerte de facturation sur le projet. Côté confidentialité : vous envoyez du contenu d'emails à une API. Pour un usage personnel, la clé AI Studio est acceptable, mais pour tout ce qui touche à des données clients ou collaborateurs, passez à Vertex AI, où vous obtenez un traitement des données de niveau entreprise, IAM, et la possibilité de garder les données dans une région. Ce n'est pas un confort pour des déploiements organisationnels ; c'est la frontière entre un prototype et quelque chose que la conformité approuvera.
Build a Gmail automation with Apps Script and Gemini
Vérification des acquis
1. Selon la leçon, qu'apporte fondamentalement la combinaison d'Apps Script et de l'API Gemini, qu'aucun des deux ne possède pleinement seul ?
2. Pourquoi la leçon recommande-t-elle d'utiliser la sortie structurée (un responseSchema) lors de l'appel à Gemini depuis le script ?
3. Dans quel scénario préféreriez-vous Vertex AI avec un service account plutôt qu'une clé API Google AI Studio ?
4. Sélectionnez TOUTES les affirmations qui décrivent correctement pourquoi Apps Script est décrit comme « la bonne colle » pour ce type d'automatisation.
Sélectionnez toutes les réponses correctes.
5. Sélectionnez TOUTES les tâches que la leçon présente comme des choses que cette automatisation Apps Script + Gemini peut faire pour vous.
Sélectionnez toutes les réponses correctes.
Quand aller au-delà d'Apps Script
Apps Script est parfait pour « ça vit dans Workspace et fait une tâche délimitée sur un planning ». C'est le mauvais outil dès que vous avez besoin d'un véritable comportement d'agent multi-étapes : des outils qui appellent d'autres outils, de la planification, de la mémoire entre les étapes, ou une orchestration que vous voulez tester et versionner comme du vrai logiciel.
À ce stade, l'écosystème Gemini vous offre des options mieux adaptées :
- [Agent Development Kit (ADK)](https://google.github.io/adk-docs/) : un framework open-source pour construire des agents avec outils, planification et orchestration multi-agents, déployable sur votre propre infrastructure ou sur Vertex AI AgentAI AgentLogiciel qui poursuit un objectif seul : il planifie, utilise des outils et agit avec une intervention humaine limitée.Voir la définition complète → Engine. À utiliser quand la logique déborde d'un seul script.
- Gemini CLI et Gemini Code Assist : pour l'automatisation côté développeur dans votre terminal et votre IDE, pas pour les workflows documentaires Workspace.
- Gems : pour des assistants réutilisables et instruction-tuned dans l'application Gemini, quand un humain est dans la boucle et que vous n'avez pas besoin de code du tout.
La règle de décision : si la tâche est « lire des données Workspace, poser à Gemini une question précise, écrire le résultat quelque part dans Workspace, sur un planning », Apps Script gagne par sa simplicité. Si la tâche implique un agent qui décide quelles actions entreprendre au fil de nombreuses étapes, passez à ADK sur Vertex AI.
Un pattern à voler : ancrer le rapport
Vous pouvez rendre la synthèse hebdomadaire plus intelligente en demandant à Gemini de rédiger un court récit des tendances, pas seulement des compteurs. Ajoutez un deuxième appel qui prend les compteurs de la semaine plus la ligne de la semaine précédente et demande une note « ce qui a changé » en deux phrases, ajoutée au Sheet. Gardez ce prompt étroitement délimité et toujours contraint par un schéma (un seul champ texte `summary`) pour qu'il reste prévisible dans une exécution sans surveillance. Peu de raisonnement, gros gain de lisibilité, et toujours peu coûteux sur Flash.
À retenir
- Apps Script est la colle, Gemini est le jugement. Lisez les données Workspace avec les services natifs, appelez l'API Gemini avec
UrlFetchApp, réécrivez les résultats, le tout sous votre propre authentification et un trigger temporel. - Utilisez la sortie structurée (`responseSchema`) et regroupez vos requêtes. Le JSON contraint élimine le parsing fragile, et un appel groupé par exécution bat un appel par élément en coût, en vitesse et en quota.
- Faites de la lecture-et-ajout le défaut et épinglez des scopes OAuth minimaux.
gmail.readonlydansappsscript.jsonest une garantie de sécurité plus forte que n'importe quel commentaire de code. Ajoutez une revue en dry-run avant qu'un script n'envoie, ne déplace ou ne supprime quoi que ce soit. - Concevez pour l'échec sans surveillance : retries avec backoff, validation contre vos enums, alertes de facturation, et erreurs loguées que vous pouvez réellement lire.
- Changez d'outil délibérément. Restez sur Apps Script pour les tâches planifiées délimitées ; passez à ADK sur Vertex AI quand vous avez besoin d'une véritable orchestration d'agents ou de contrôles de données de niveau entreprise.