(Laissez les deux au défaut pour générer tous les badges.)
6e | 6ème. Si une fiche correspond à plusieurs règles, la première (en haut) s'applique.
Cette section contient des outils spécialisés pour la gestion de l'infrastructure et des modèles de données.
L'application nécessite une connexion pour activer toutes les fonctionnalités de génération et de sauvegarde.
Avant de pouvoir synchroniser des données ou déployer le formulaire étudiant, vous devez créer le classeur qui stockera les informations.
Pour que votre formulaire d'inscription dynamique soit accessible via un lien public (URL), vous devez **déployer** le script associé au classeur Google Sheets.
Code.gs :
/**
* saveBadgeDriveId(driveId) — persiste un ID de dossier Drive dans ScriptProperties.
* Appelé depuis le frontend (fire-and-forget).
*/
function saveBadgeDriveId(driveId) {
try {
if (!driveId || typeof driveId !== 'string') return;
PropertiesService.getScriptProperties().setProperty('BADGE_DRIVE_FOLDER_ID', driveId.trim());
} catch (e) { Logger.log('[saveBadgeDriveId] error: ' + e.message); }
}
/**
* saveBadgesToDrive(folderId, badgeImagesData) — sauvegarde un tableau de badges
* (data URIs ou objets {data, name, code}) dans le dossier Drive indiqué.
* Retourne { saved, errors, results:[{code,url,fileId}] }.
*/
function saveBadgesToDrive(folderId, badgeImagesData) {
if (!folderId || !Array.isArray(badgeImagesData) || badgeImagesData.length === 0) {
return { saved: 0, errors: ['Aucun fichier à sauvegarder ou ID de dossier manquant.'], results: [] };
}
try {
const rootFolder = DriveApp.getFolderById(folderId.trim());
// Store in Badges sub-folder
let folder;
const fi = rootFolder.getFoldersByName('Badges');
folder = fi.hasNext() ? fi.next() : rootFolder.createFolder('Badges');
let saved = 0;
const errors = [], results = [];
badgeImagesData.forEach(function(item, index) {
try {
const dataUrl = typeof item === 'string' ? item : (item && item.data ? item.data : '');
const recipientCode = String(item && (item.code || item.Code || item.recipientCode) || '').trim();
const safeCode = recipientCode.replace(/[^A-Za-z0-9_-]/g, '_');
const baseName = (item && typeof item === 'object' && item.name)
? String(item.name)
: (safeCode || 'badge_' + (index + 1) + '_' + Date.now());
const name = String(baseName).replace(/\.(png|jpg|jpeg)$/i, '') + '.png';
if (!dataUrl) return;
const parts = dataUrl.split(',');
if (parts.length < 2) return;
const mime = (parts[0].match(/data:(.*?);base64/) || [])[1] || 'image/png';
const blob = Utilities.newBlob(Utilities.base64Decode(parts[1]), mime, name);
// Overwrite existing same-name file to avoid duplicates
const existing = folder.getFilesByName(name);
while (existing.hasNext()) existing.next().setTrashed(true);
const file = folder.createFile(blob);
try { file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); } catch (_) {}
const fileId = file.getId();
const driveUrl = 'https://drive.google.com/file/d/' + fileId + '/view?usp=sharing';
saved++;
results.push({ code: recipientCode, url: driveUrl, fileId: fileId });
} catch (err) { errors.push('Badge ' + (index + 1) + ': ' + err.message); }
});
return { saved: saved, errors: errors, results: results };
} catch (e) {
throw new Error('Erreur accès Drive (dossier ' + folderId + '): ' + e.message);
}
}
/**
* saveSingleBadgeToDrive(badge) — sauvegarde un seul badge et retourne son URL.
* @param {{code:string, name:string, base64:string}} badge
* @returns {{url:string, fileId:string}}
*/
function saveSingleBadgeToDrive(badge) {
const folderId = PropertiesService.getScriptProperties().getProperty('BADGE_DRIVE_FOLDER_ID')
|| PropertiesService.getScriptProperties().getProperty('DRIVE_FOLDER_ID') || '';
if (!folderId) throw new Error('BADGE_DRIVE_FOLDER_ID not set in Script Properties.');
const folder = DriveApp.getFolderById(folderId);
const b64 = badge.base64.replace(/^data:image\/\w+;base64,/, '');
const bytes = Utilities.base64Decode(b64);
const name = (badge.name || badge.code || 'badge') + '.png';
const blob = Utilities.newBlob(bytes, 'image/png', name);
const existing = folder.getFilesByName(name);
while (existing.hasNext()) existing.next().setTrashed(true);
const file = folder.createFile(blob);
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
return { url: file.getUrl(), fileId: file.getId() };
}
Personnalisez le visuel et les champs de la carte avant de générer les badges.
⚠️ **IMPORTANT :** Cliquez toujours sur **💾 Sauvegarder Tous les Paramètres** après une modification.
Générateur de Cartes Professionnelles