,

Dupliquer des événements Google Agenda

Aujourd’hui, je suis ravi de partager avec vous un outil simple mais puissant qui va révolutionner la manière dont vous gérez votre emploi du temps. Si, comme moi, vous avez des journées types qui se répètent ou des événements récurrents que vous souhaitez copier facilement d’un jour à l’autre sur votre Google Agenda, alors cet article est fait pour vous.

J’ai développé un petit Google Apps Script qui va vous faire gagner un temps précieux. Fini les copier-coller manuels d’événements, ou la recréation fastidieuse de vos routines ! Avec ce script, vous pourrez dupliquer en un clin d’œil tous les événements d’une journée « modèle » vers n’importe quelle autre date de votre choix, le tout en conservant tous les détails : titre, description, invités, et même la couleur.

Prêt à automatiser votre calendrier et à libérer du temps pour ce qui compte vraiment ? Suivez le guide !

Ce script vous permet de copier tous les événements d’une journée spécifique de votre calendrier Google principal vers une liste d’autres dates de votre choix. Les événements dupliqués seront des copies exactes, incluant le titre, la description, les invités et la couleur. Un journal d’activités sera généré pour vous informer du succès des duplications et des éventuels doublons.

/**
 * Duplique les événements d'une journée source vers des journées cibles spécifiques.
 * Les événements dupliqués sont des copies exactes (titre, description, invités, couleur).
 * Un journal des activités est généré pour informer des duplications et des doublons.
 */
function dupliquerEvenementsJourneeType() {
  const ID_CALENDRIER_SOURCE = 'primary'; // 'primary' correspond à votre calendrier principal
  const calendrier = CalendarApp.getCalendarById(ID_CALENDRIER_SOURCE);

  if (!calendrier) {
    Logger.log("Erreur : Calendrier introuvable avec l'ID : " + ID_CALENDRIER_SOURCE);
    return;
  }

  // --- PARAMÈTRES À CONFIGURER PAR L'UTILISATEUR ---
  // 1. Date de la journée source (la "journée type" à dupliquer)
  //    Format : 'AAAA-MM-JJ'
  const DATE_SOURCE_STR = '2025-06-15'; // Exemple : le 15 juin 2025

  // 2. Liste des dates cibles où les événements seront dupliqués
  //    Format : ['AAAA-MM-JJ', 'AAAA-MM-JJ', ...]
  const DATES_CIBLES_STR = [
    '2025-06-16', // Exemple : Lundi 16 juin 2025
    '2025-06-17', // Exemple : Mardi 17 juin 2025
    '2025-06-20'  // Exemple : Vendredi 20 juin 2025
  ];
  // ----------------------------------------------------

  const dateSource = new Date(DATE_SOURCE_STR + 'T00:00:00'); // S'assure que l'heure est à 00:00:00
  const debutJourneeSource = new Date(dateSource.setHours(0, 0, 0, 0));
  const finJourneeSource = new Date(dateSource.setHours(23, 59, 59, 999));

  const evenementsADupliquer = calendrier.getEvents(debutJourneeSource, finJourneeSource);

  if (evenementsADupliquer.length === 0) {
    Logger.log(`Aucun événement trouvé pour la date source : ${dateSource.toLocaleDateString()}. Fin du script.`);
    return;
  }

  Logger.log(`--- Début de la duplication des événements depuis le ${dateSource.toLocaleDateString()} ---`);
  Logger.log(`Nombre d'événements à dupliquer : ${evenementsADupliquer.length}`);

  DATES_CIBLES_STR.forEach(dateCibleStr => {
    const dateCible = new Date(dateCibleStr + 'T00:00:00');
    const debutJourneeCible = new Date(dateCible.setHours(0, 0, 0, 0));
    const finJourneeCible = new Date(dateCible.setHours(23, 59, 59, 999));

    Logger.log(`\n--- Traitement de la date cible : ${dateCible.toLocaleDateString()} ---`);

    // Récupérer les événements déjà existants sur la date cible pour éviter les doublons
    const evenementsExistantsCible = calendrier.getEvents(debutJourneeCible, finJourneeCible);
    // Créer une Map pour un accès rapide aux événements existants (titre -> heure de début)
    const carteEvenementsExistants = new Map();
    evenementsExistantsCible.forEach(e => {
      const cleUnique = `${e.getTitle()}@${e.getStartTime().getTime()}`; // Clé unique basée sur titre et heure de début
      carteEvenementsExistants.set(cleUnique, true);
    });

    evenementsADupliquer.forEach(evenement => {
      const titreEvenement = evenement.getTitle();
      const heureDebutEvenement = evenement.getStartTime();
      const heureFinEvenement = evenement.getEndTime();
      const descriptionEvenement = evenement.getDescription();
      const lieuEvenement = evenement.getLocation();
      const invitesEvenement = evenement.getGuests();
      const couleurEvenement = evenement.getColor();
      const estEvenementTouteLaJournee = evenement.isAllDayEvent();

      // Calculer le décalage en millisecondes entre la date source et la date cible
      const decalageHoraire = dateCible.getTime() - dateSource.getTime();

      // Appliquer le décalage aux heures de début et de fin de l'événement
      const nouvelleHeureDebut = new Date(heureDebutEvenement.getTime() + decalageHoraire);
      const nouvelleHeureFin = new Date(heureFinEvenement.getTime() + decalageHoraire);

      // Clé potentielle pour le nouvel événement pour vérifier les doublons
      const nouvelleCleEvenement = `${titreEvenement}@${nouvelleHeureDebut.getTime()}`;

      if (carteEvenementsExistants.has(nouvelleCleEvenement)) {
        Logger.log(`  Doublon détecté : L'événement "${titreEvenement}" existe déjà le ${dateCible.toLocaleDateString()} à ${nouvelleHeureDebut.toLocaleTimeString()}.`);
        return; // Passer à l'événement suivant
      }

      try {
        let nouvelEvenement;
        if (estEvenementTouteLaJournee) {
          // Pour les événements d'une journée entière, les dates de début/fin sont juste le jour
          const nouvelleDateDebutTouteJournee = new Date(dateCible.getFullYear(), dateCible.getMonth(), dateCible.getDate());
          // Pour les événements toute la journée, la date de fin est le jour suivant
          const nouvelleDateFinTouteJournee = new Date(dateCible.getFullYear(), dateCible.getMonth(), dateCible.getDate() + 1);
          nouvelEvenement = calendrier.createAllDayEvent(titreEvenement, nouvelleDateDebutTouteJournee, nouvelleDateFinTouteJournee, {
            description: descriptionEvenement,
            location: lieuEvenement
          });
        } else {
          nouvelEvenement = calendrier.createEvent(titreEvenement, nouvelleHeureDebut, nouvelleHeureFin, {
            description: descriptionEvenement,
            location: lieuEvenement
          });
        }

        // Ajouter les invités si l'événement source en a
        if (invitesEvenement && invitesEvenement.length > 0) {
          const emailsInvites = invitesEvenement.map(invite => invite.getEmail());
          nouvelEvenement.addGuest(emailsInvites.join(','));
          // Décommentez la ligne ci-dessous si vous voulez envoyer une invitation par email aux invités
          // nouvelEvenement.sendInvites(); // ATTENTION : envoie des emails aux invités !
        }

        // Définir la couleur si elle existe
        if (couleurEvenement) {
          try {
            nouvelEvenement.setColor(couleurEvenement);
          } catch (e) {
            Logger.log(`    Avertissement : Impossible de définir la couleur de l'événement "${titreEvenement}" (${couleurEvenement}). Erreur : ${e.message}`);
          }
        }

        Logger.log(`  Dupliqué : "${titreEvenement}" du ${dateSource.toLocaleDateString()} vers le ${dateCible.toLocaleDateString()} ${estEvenementTouteLaJournee ? '(jour entier)' : `de ${nouvelleHeureDebut.toLocaleTimeString()} à ${nouvelleHeureFin.toLocaleTimeString()}`}`);

      } catch (e) {
        Logger.log(`  Erreur lors de la duplication de l'événement "${titreEvenement}" : ${e.message}`);
      }
    });
  });
  Logger.log("\n--- Processus de duplication terminé ---");
}

Comment utiliser ce script ?

  1. Ouvrez Google Apps Script : Allez sur Google Sheets, créez une nouvelle feuille ou ouvrez-en une existante, puis cliquez sur Extensions > Apps Script.
  2. Collez le code : Supprimez le code par défaut et collez le nouveau script.
  3. Configurez les paramètres :
    • Modifiez la variable DATE_SOURCE_STR avec la date de la journée type que vous souhaitez dupliquer (par exemple, '2025-06-15').
    • Modifiez la variable DATES_CIBLES_STR avec la liste des dates où vous voulez que les événements soient copiés (par exemple, ['2025-06-16', '2025-06-17', '2025-06-20']). Assurez-vous que chaque date est entre guillemets simples et séparée par une virgule.
  4. Sauvegardez le script : Cliquez sur l’icône « Disque » (Enregistrer le projet).
  5. Exécutez le script :
    • Assurez-vous que la fonction sélectionnée dans le menu déroulant est dupliquerEvenementsJourneeType.
    • Cliquez sur le bouton « Exécuter » (l’icône « Lecture »).
  6. Autorisez le script (première exécution uniquement) : Google vous demandera d’autoriser l’accès à votre calendrier. Suivez les instructions pour accorder les autorisations nécessaires.
  7. Vérifiez le journal d’activités : Après l’exécution, consultez le « Journal d’exécution » en bas de l’éditeur Apps Script (ou via Exécution > Journaux) pour voir les détails des opérations effectuées.

N’hésitez pas si vous avez d’autres questions ou si vous rencontrez des difficultés !