見出し画像

【GAS】電子チケット自動生成を実現した話~1段階進化~

先日のコードを進化させたので変更したところなどを記載していきます!
具体的に進化した点は「生成した画像のIDを取得して展開可能なURLを準備。その後申込者に割り当てした画像データをURLを添付したメールで送る」というものです。

今回のイベントでは間に合わなかったですが次回からはボタン一つでメール送信まで出来る仕組みに変えていきます!(まだまだ進化は止まりません!)

function ticket() 
  {
    //変数設定
      let startTime = new Date(); // ①実行開始時点の日時
      //スプレッドシートファイルを取得
      var mainSpreadsheetID = '*******'
      var saveFolderID = '********'
      var tempFileID = '*********'
      var sheetName1='シート1'
      var sheetName2='シート2'
   //作業フォルダ、シートの指定と生成
  var spreadsheet = SpreadsheetApp.openById(mainSpreadsheetID);
  //シートを取得  
  var sheet = spreadsheet.getSheetByName(sheetName1); //※利用時はシート名を差し替え
  //保存先のフォルダを指定
  var folder1 = DriveApp.getFolderById(saveFolderID); //※利用時はフォルダIDを差し替え
  //チケットを格納するための新規フォルダを作成します
  var folder2 = folder1.createFolder("チケットデータ処理待ち"); //※利用時はフォルダ名を差し替え
   Logger.log('作業時間計測開始');

  //チケットの作成準備
   var id_program = '{program}';   //var id_***** = '{******}';「''」内をテキストボックスのオリジナルテキスト(置換前のテキスト)に差し替えてください。

   //申し込み者リストを全行取得します。
  var sheetRows = sheet.getDataRange().getValues();
 
    //繰り返し処理start!
    for(let row of sheetRows) 
      {
      let currentTime = new Date(); // ②ループx周目時点の日時
      let seconds = (currentTime - startTime)/1000; // 経過秒数を計算(①と②の差分)
      if(seconds > 300){//6分間の壁対策
      setTrigger();
      return;
      }

      //配列のなかの列を指定(A列=0)
      let program = `${row[0]}`; //列を差し替え
      let name = `${row[1]}`; //列を差し替え
      let dantai = `${row[2]}`; //列を差し替え
      //ファイル名を指定(複製したスライドおよび画像出力した際のファイル名として使います。違う名前にすることも可能です)
      let proof_name = program+'_'+name+'_'+dantai; 
              Logger.log(proof_name);

      //テンプレートのスライドファイルを複製
      let templatefile1 = DriveApp.getFileById(tempFileID); //※利用時ファイルIDを差し替え
      let copied_proof = templatefile1.makeCopy(proof_name); //ファイル名、保存フォルダを指定
        //複製したファイルを取得し、テキスト置換を行います。
        //コピーしたファイルのID取得
        let cp_id = copied_proof.getId();
        //コピーしたファイルを編集する準備
      let slides_file = SlidesApp.openById(cp_id);
      let slides =slides_file.getSlides();

      //今回は1ページ目(=0)のみ編集します。
      let page_no = 0
      let slide = slides[page_no];
      let pageElements = slide.getPageElements();

      //スライドのテキストボックス(シェイプ)を取得
      for(let shape_no=0;shape_no<pageElements.length;shape_no++)
      {
        //指定のフォーマットの文字列を置換(★で指定したID,置換後テキスト)
        pageElements[shape_no].asShape().getText().replaceAllText(id_program, program);  //テキスト置換2
      }
      //編集したスライドを保存(これがないと最初に取得したスライドの状態のまま画像変換されるので注意)
      slides_file.saveAndClose();

      //スライドから画像に変換します
      //変換url(エクスポート)
      let export_url = 'https://docs.google.com/presentation/d/'+ cp_id +'/export/png';  //ファイル形式を指定
      //オプションを指定
      let options = 
      {
        method: "get",
        headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
        muteHttpExceptions: true
      }
      let res = UrlFetchApp.fetch(export_url, options);
      if (res.getResponseCode() === 200) 
        {
          var file = folder2.createFile(res.getBlob())
          file.setName(proof_name + ".png");  //ファイル名、保存フォルダを指定
              Logger.log(proof_name + '画像作成完了');
              var pngID = file.getId();
        //作成した画像のデータを保持。
        Logger.log(pngID);

        //※ID保存用のスプレッドシートを作成
        var idSheet = SpreadsheetApp.openById(mainSpreadsheetID).getSheetByName(sheetName2); //※利用時はシート名を差し替え
         idSheet.appendRow([program,pngID]);
        }

      //複製したファイルを取得し、削除を行います。
        let fileData = DriveApp.getFileById(cp_id);
      //IDから取得したファイルをゴミ箱のフラグをtrueにする
      //ファイルから処理済みのデータを削除します。
      let getData = fileData.setTrashed(true);
      Logger.log('複製ファイルを削除済み');

  //スクリプトに紐づいたスプレッドシートのアクティブなシートを読み込み
  //deleteRowメソッドで引数指定した1行を削除
  sheet.deleteRow(1);//ここでは1行目指定
        Logger.log('処理済みの行を削除');

            // 処理し終えたらトリガーを削除
  let triggers = ScriptApp.getProjectTriggers();
  for(let trigger of triggers){
    if(trigger.getHandlerFunction() == 'ticket'){
      ScriptApp.deleteTrigger(trigger);
    }
  }
}
}

function setTrigger() {
  let triggers = ScriptApp.getProjectTriggers();
  for(let trigger of triggers)
    {
      if(trigger.getHandlerFunction() == 'ticket')
      {
        ScriptApp.deleteTrigger(trigger);
      }
    }
  // 1分後にトリガーをセット(1分 = 60秒 = 1秒*60 = 1000ミリ秒 * 60)
  ScriptApp.newTrigger('ticket').timeBased().after(1000 * 60).create();
          Logger.log('トリガーをセット');
  }

前回作成した部分は割愛です。

変数ボックス

繰り返し使うコードはメンテナンスが自分以外の人が出来るかが大切。
ケアレスミスを無くすためにも、変数は冒頭で設定しきってしまうのが良いですね。

 {
    //変数設定
      let startTime = new Date(); // ①実行開始時点の日時
      //スプレッドシートファイルを取得
      var mainSpreadsheetID = '*****'// 申込者情報、席番号が記載されているファイルのID
      var saveFolderID = '*******'//画像データを保存するフォルダID
      var tempFileID = '*******'//画像テンプレートスライドのID
      var sheetName1='シート1'// 申込者情報、席番号の乗っているシート名
      var sheetName2='シート2'//画像IDを転記するシートのID

画像データのIDを保存

   //スライドから画像に変換します
      //変換url(エクスポート)
      let export_url = 'https://docs.google.com/presentation/d/'+ cp_id +'/export/png';  //ファイル形式を指定
      //オプションを指定
      let options = 
      {
        method: "get",
        headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
        muteHttpExceptions: true
      }
      let res = UrlFetchApp.fetch(export_url, options);
      if (res.getResponseCode() === 200) 
        {
          var file = folder2.createFile(res.getBlob())
          file.setName(proof_name + ".png");  //ファイル名、保存フォルダを指定
              Logger.log(proof_name + '画像作成完了');
              var pngID = file.getId();
        //作成した画像のデータを保持。
        Logger.log(pngID);

        //※ID保存用のスプレッドシートを作成
        var idSheet = SpreadsheetApp.openById(mainSpreadsheetID).getSheetByName(sheetName2); //※利用時はシート名を差し替え
         idSheet.appendRow([program,pngID]);
        }

大部分は一緒ですが、生成した画像データのIDを保存しておく部分を追加しました。(var pngID = file.getId();)
スプレッドシートにはappendRowを用いて席番号と画像IDを隣のシートに書き込んでいきます。名前などの他の情報もこのシートに欲しい場合にはそれらを定義したうえで、「idSheet.appendRow([program,pngID,name,address]);」のように一次元配列に追加してください。

まとめ

画像データ自体を添付する方法もあるのですが、相手方の端末の容量不足などでエラーがかえってきてしまうことがままあったのでURLで対応することにしました。

URLを送る場合はフォルダの共有設定をリンク共有で全員が見られるようなものにしておき、IDの前に「https://drive.google.com/uc?id=」をつけると閲覧できるURLになりますのでスプレッドシートにそのように設定ください。

参考


応援したいと思ってくれた方、いらっしゃいましたらサポートお願いします!