見出し画像

少数スタッフでも大丈夫!Google1本でQRコード承認システムを作ろう!!

こんにちは。小学生向けのプログラミング教室で勤務をしている腰越です。この内容は現職でハマったGAS(=Googleが開発したプログラミング言語)についてご紹介をしています。


ある依頼から始まった

私は2021年3月に「プペルトラックを呼びたい!」という意気込みだけで市内の学生を対象としたイベントを行いました。

コロナ禍での開催でしたが、来場者の事前予約も取り入れ三密を防げる対応をしたため、大きな混乱もなく無事終了しました。
そして時はたち、今年度も市内の学生を対象としたイベントを開催することとなったのですが、コロナ禍はまだ継続しており、市内でもまだピリピリムードなので、昨年よりも更にスムーズなイベント運営が出来るよう「今年は事前予約者が来場した際の受付確認作業を自動化を出来ないか」とのミッション依頼が私にきました。ということで、GASでチャレンジしてみることにしました。

今年は右側のイメージで受付がスムーズに出来るようにしたい!

その①:QRコード生成&更新システム

まずはYoutubeで同じようなシステムを作っている人を探しました。
そしたらいきなりヒントとなる動画を発見。

上記動画は「QRコードを読み込むだけで、スプレッドシートに読み込んだ日時が更新される」という機能を解説してくれています。
何とありがたいことにコード等も公開してくれている神動画だったため、かなり参考にさせていただきました。上記サイトでコードを公開していますので、概要欄よりご確認ください。

上記URLから、参考コードをチェック出来ます!神すぎる!
拡張機能からGASの参考コードが確認できます。
この2つのコードを参考にします!
私は上記サイトのコードを、
自分のシートの範囲に合わせて、QRコード生成コードを作りました。
//barcode.jsを改良
//QRコード生成&来場者承認ページ生成用URLを作成

function qrcodeURL(){
  //アクティブなスプレッドシートを取得
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getSheetByName('シート名を入力');
  let lastRow = sheet.getLastRow();
  for (let i=3; i<=lastRow; i++) {
      //7列目-9列目の文字列を削除
      sheet.getRange(i, 7).clear();
      sheet.getRange(i, 8).clear();
      sheet.getRange(i, 9).clear();
      //[000]を表記するための準備用コード
      sheet.getRange(i, 7).setNumberFormat("@");
      let visitor_code = "000" + String(i-2);
      Logger.log(visitor_code);
      let qrc1 = '=\"https://script.google.com/macros/s/\"&$B$1&\"/exec?no=\"&G' + i;
      let qrc2 = '=\"https://chart.apis.google.com/chart?chs=250x250&cht=qr&chl=\"&H' + i;
      sheet.getRange(i, 7).setValue(visitor_code);
      sheet.getRange(i, 8).setValue(qrc1);
      sheet.getRange(i, 9).setValue(qrc2);
  }
}

おかげで「QRコードを読み込む→来場者の受付時間を自動更新」という機能は完了。次のステップに。

その②:QRコードを1枚ずつ画像変換&保存

参考動画は「QRコードは印刷して使用しましょう」という解説でしたが、私はイベントで来場者1人1人に個人確認用QRコードを事前に配布したいので、データとして来場者に事前配布しておく必要があります。
そこでまずは生成したQRコードを1枚ずつ画像として保存する方法を探しました。半日がかりでやっと見つけたのがこちら。

ウェブサイトの画像をJPGやPNG形式でGoogleドライブにダウンロードして保存する方法が載っているのですが、この方法を使えば1枚ずつ画像データとして保存することができました。

//barcode.jsを改良
//QRコードを指定したGoogle Driveに保存

function getQRcode({

  //URLから画像を生成→指定のドライブフォルダに保存
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getSheetByName('シート名を入力');
  let lastRow = sheet.getLastRow();

  //保存したい画像URLを変数で定義
  for (let i=3; i<=lastRow; i++) {
    let imageName = sheet.getRange(i,7).getValue();
    let imageUrl = sheet.getRange(i,9).getValue();

    //UrlFetchAppで画像URLにリクエストし、画像ファイルを取得
    let image = UrlFetchApp.fetch(imageUrl).getBlob().setName(imageName + ".png");
    //指定したGoogleDriveフォルダに取得した画像を保存
    DriveApp.getFolderById('フォルダID名を入力').createFile(image);
  }
}
きちんと1人1人のQRコードが作ることが出来ました。

その③:予約者にQRコード画像を添付したメールを一括送信

あとは送信システムの準備のみ。
一括送信の機能は以前作ったので、すぐ実装できたのですが、問題はQRコードの画像を添付したメールを送るシステム。
手間が掛からないようにインライン画像を挿入して送る方法にしたかったのですが、これも参考コードを探すのに相当苦労しました。で、みつけたのがこちら。

先程のコードに追記して、何とか作ったのがこちら。

//barcode.jsを改良
//QRコードを指定したGoogle Driveに保存し、来場者にQRコード画像付きメールを一斉送信する

function getQRcode_sendmail({

  //①URLから画像を生成→指定のドライブフォルダに保存
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getSheetByName('シート名を入力');
  let lastRow = sheet.getLastRow();

  //保存したいWebpフォーマットの画像URLを変数で定義
  for (let i=3; i<=lastRow; i++) {
    let imageName = sheet.getRange(i,7).getValue();
    let imageUrl = sheet.getRange(i,9).getValue();
    Logger.log(imageName);
    Logger.log(imageUrl);


    //UrlFetchAppで画像URLにリクエストし、画像ファイルを取得
    let image = UrlFetchApp.fetch(imageUrl).getBlob().setName(imageName + ".png");
    //指定したGoogleDriveフォルダに取得した画像を保存
    DriveApp.getFolderById('フォルダID名を入力').createFile(image);

  
    //②ドライブから画像を検索し、メールにて送信
    //メールのアドレスの取得
    let address = sheet.getRange(i,2).getValue();
    Logger.log(address);
    //メールの件名の記述
    let mailTitle = "件名を入力";
    //メール本文の記述
    let name = sheet.getRange(i,3).getValue();
    let mailText = name + "様\n\n当日は、ご来場の際に受付スタッフに下記QRコードをお見せください。\n\n運営事務局"; 
    //1度、Google Driveに保存した画像を取得しインライン画像の挿入
    let driveImage = DriveApp.getFilesByName(imageName + ".png").next();
    Logger.log(driveImage);

    //GMailAppにsendEmailメソッドを実行してメールを送信する
    //送信元メールアドレスに指定できるメールアドレスは、GAS実行者が所有しているメールエイリアスのみ
    GmailApp.sendEmail(address, mailTitle, mailText,{from"送信元のアドレスを入力",attachments: [driveImage]});
  }
}

実際にやってみた

現段階では読み込み後に若干人を介する必要がまだあるものの、1つ1つ確認する必要は無くなったので大分スムーズにはなるのではないかと思います。

改めてGoogleの凄さを感じます。
GASに触れて2年目に突入するので、今後も自分の仕事の効率化や地方のデジタル推進に貢献して「プログラミングと社会のつながり」を行動で子どもたちに見せていきたいと思います。

ではではまた。

この記事が参加している募集

つくってみた

よろしければサポートお願いします。いただいたサポートはデジタルツール活用に関する記事作成の活動費用にします!