google
GoogleAppsScript
gas
GoogleSlides

【GAS】GoogleAppsScriptでGoogleSlidesのスライドを編集する

Google Apps Scriptは自動化を気軽に行えるので、割と色々な場面でお世話になると思います。
自分も最近社内の効率化で使うケースが多くてよく書いています。
普段はスプレッドシートに紐づいたScriptを書くことが多くそっちはネット上に多くの情報があるのですが、今回書いたGoogle Slidesに関するコードの情報は少なかったので書き残しておきます。
また、今回の例ではGoogle Slides APIは使いません。

今回のスクリプトの概要

指定のフォルダにコピー元となるテンプレートを保持しており、それをコピーして日付などの動的に書き換わる情報のみ差し替えるようなScriptです。

毎週行う会議の事前資料を自動的に生成するみたいな用途を想定しています。
以下のコードは金曜に会議があると仮定して、毎週木曜朝とかにトリガー設定して動かします。
スクリーンショット 2018-08-06 1.46.41.png
日付を挿入したい箇所に{DATE}と書き込んでおいたテンプレートファイル。

はじめに

この記事の情報は2018年8月時点のものです。
Gsuite環境下で作成しています。

やり方

準備

事前資料のテンプレートと資料生成用のフォルダを作成して、両方のIDを控えます。
SlideのIDはスライドを開いた状態のURLにhttps://docs.google.com/presentation/d/<スライドのID>/edit#...と記載され、フォルダのIDはGoogleDriveで目的のフォルダを開いた際のURLにhttps://drive.google.com/drive/u/0/folders/<フォルダのID>のように記載されています。

コード

議事録ファイルやフォルダのIDはfunctionとして定義してどこからでも使える定数みたいな感じにしちゃってます。
createMeetingPresenation()を実行すると議事録ファイルが生成されます。また、このfunctionは以下の3つのfunctionに依存しています。
editSlideData()ではスライドの中身をいじっています。
getStringFormatDate()はDate型の値を渡すと2018/08/01みたいな指定の文字で区切ったString型の日付を返すものです。
postSlack()はSlackに投稿するやつです。今回の内容とは関係ないのでカット。

code.gs
// 議事録templateファイルのID
function getSourceFileId() {
  return "<スライドのID>";
}

// 議事録を保存するためのフォルダ
function getDestinationFolderId()  {
  return "<フォルダのID>";
}

function createMeetingPresentation() {
  //ファイル名
  var fileName = "週例会議";
  var date = new Date();
  const friday = 5;  // javascriptで金曜日は5
  var remainDays = friday - date.getDay();
  date.setDate(date.getDate() + remainDays);
  var formatDate = getStringFormatDate(date,"");
  fileName = formatDate + "_" + fileName;
  Logger.log(fileName);

  // templateからコピーしてくる
  var sourceFileId = getSourceFileId();
  // 出力先フォルダ
  var destinationFolderId = getDestinationFolderId();
  var destination = DriveApp.getFolderById(destinationFolderId);

  // ファイル持って来てコピー
  var sourceFile = DriveApp.getFileById(sourceFileId);
  var file = sourceFile.makeCopy(fileName, destination);
  editSlideData(file.getId(), date);
  var message = "週会議の事前資料です!会議までに記入お願いします!";
  postSlack(file.getUrl(), message);  //できたファイルのURLをSlackに通知したり、、、
}

// 文書内の日付などのパラメータ変更
// Slide内で会議の日時を表示したい箇所に{DATE}と記入し、
// 会議がある1週間の日付を表示したい居場所には{THIS_WEEK}とテンプレートに記入しておく。
function editSlideData(slideId,meetingDate){

  const ID_DATE = "{DATE}"
  const ID_THIS_WEEK = "{THIS_WEEK}";

  var dateString = getStringFormatDate(meetingDate,"/");
  var thisWeekStartDate = meetingDate;
  thisWeekStartDate.setDate(thisWeekStartDate.getDate() - 6);  // 前週の1つあとの曜日へ(土)
  var thisWeekStartDateString = getStringFormatDate(thisWeekStartDate, "/");
// "2018/08/04〜2018/08/10"のようになる
  var daysOfThisWeek = thisWeekStartDateString + "〜" + dateString;

  // 全ページ取得
  var slides = SlidesApp.openById(slideId).getSlides();

  // 全てのスライドのシェイプをチェックしていく
  for(var j=0;j<slides.length;j++){
    var slide = slides[j];
    var pageElements = slide.getPageElements();
    for(var i=0;i<pageElements.length;i++){
      var text = pageElements[i].asShape().getText().asString();
      // 指定のフォーマットの文字列を置換
      pageElements[i].asShape().getText().replaceAllText(ID_THIS_WEEK, daysOfThisWeek);
      pageElements[i].asShape().getText().replaceAllText(ID_DATE, dateString);
    }
  }
}

//入って来たDate型の日時をseparatorで区切った文字列にして返す
function getStringFormatDate(date, separator){
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  if(month < 10){
    month = "0" + String(month);
  }
  var date = date.getDate();
  if(date < 10){
    date = "0" + String(date);
  }

  var formatDate = String(year) + separator + String(month) + separator + String(date);
  return formatDate
}

//Slackに投稿する
function postSlack(url, message){
  // 省略
}

終わりに

Google Apps ScriptはJavaScriptなこともあって割と書くのが疲れる。型。。。
けどいろいろなことができて割と助かるので仲良くしていきたいですね。

参考

Class SlidesApp  |  Apps Script  |  Google Developers
Google SlidesをGoogle Apps Scriptからいじる