見出し画像

【GAS】Gメール投稿するだけでWEBページの掲載画像を更新できる、かんたん日報表示システム(実装編)実装用のスプレッドシートとGASのコード

グループ内のメンバーに対して画像を介して簡単な情報を共有するための、かんたんな日報ページをGAS(Google Apps Script)で作ってみました。

----------------

過去の解説記事は、こちらです。

・システム構成

・ログイン部分の実装

・Gメールからの画像収集

・画像のWEBページ反映

----------------

今回の記事では、このアプリを実装するための、GASのスクリプトとテンプレートのコード、スプレッドシートのひな型をご紹介します。その他、画像を保存するためのサブフォルダ1つはご自身で新規作成ください。

システムではその他にGメールを使います。

本記事では実装コードをご紹介していますが、様々な理由により、この説明通りにいかない場合がしばしばあります。こうした場合の対応は、申し訳ありませんが、自己責任・自己解決でお進めくださるよう、お願いいたします。 

GASによるプログラムはの内容は、個人や小規模なグループ内での利用を想定しており、規模の大きなグループや商用での利用は想定しておりませんのでご注意下さい。


『かんたん日報表示システム』のシステム構成


システム概要

このWEBアプリのシステムは、1つのGASプロジェクトファイル、1つのスプレッドシート、画像保存用のサブフォルダ、およびGメールアプリから構成されています。


最後のGASプロジェクトでは、ファイル内にテンプレート(拡張子がhtml)が2つ、スクリプトファイル(拡張子がgs)が3つあります。

システムの各構成要素の準備

画像保存用のフォルダ

ご自身のGドライブの中に、適当なサブフォルダを作成ください。

フォルダ名は何でも結構です。

サブフォルダを作成したら、フォルダ内を選択した状態でブラウザのURLを参照して、フォルダIDを控えておきましょう。(ブラウザのヘッダ部を確認してください。最後の「/」より後の文字列がフォルダIDです)

サンプル画像

このサブフォルダ内に、テスト用の適当なサンプル画像を用意しました。

宜しければ、上のリンクからダウンロードしてお使いください。上に示した画像ファイルが2つ入った圧縮ファイルとなっています。

これを、画像保存用フォルダに保存しておきましょう。

画像保存フォルダ

画像リスト用のスプレッドシート

次に、画像リストを表記するスプレッドシートを1つGドライブ内に作成します(ファイル名は何でも可です)。

スプレッドシートを新規作成し、シート名を「投稿一覧」としたものを用意しておきます。(スプレッドシートファイル名は何でもよいですが、シート名は固定ですので変えないでください)

以下(ただのシートがあるだけのファイルですが)のエクセルフェイルをダウンロードしてスプレッドシートにインポートして利用いただいても結構です。

準備ができたら、ブラウザからURLを参照して、スプレッドシートIDを控えておきます。

スプレッドシートIDは、URLでspreadsheets/d/と/editに挟まれた部分です。
~/spreadsheets/d/★スプレッドシートID★/edit

GASプロジェクトファイル

Gドライブ内に、プロジェクトファイルを新規作成します。

作成は、Gドライブの新規作成ボタン(+マークのアイコン)をクリックして、「その他」を選択します。

次いで、Google Apps Script をクリックすると、作成されます。


次いで、プロジェクトファイルを開き、「+」のアイコンをクリックして、
プロジェクト内に、以下の名称でテンプレートファイルを2つ、スクリプトファイルを3つ作成します。

テンプレート: INDEX.html、LoginForm.html

スクリプト:かんたん日報表示.gs、ログイン.gs、作品の抽出と保存.gs

作成後は、以下の様なファイル構成になるはずです。

プロジェクト内のファイルにコードを記述する


プロジェクト内に作成したテンプレートやスクリプトファイルにコードを記述します。

対象ファイルをクリックすると、以下の様にエディタ画面になりますので、ここに本記事でご紹介するコードをコピー&ペーストします。

INDEX.htmlのコード

以下となります。元のコードを削除した上で貼り付けてください。

★スプレッドシートID★とある部分が2ヵ所ありますが、ここは、さきほど用意したスプレッドシートのスプレッドシートIDに、各自で打ち替えてください。

<!---「かんたん日報表示」日報のWEBページ---->
<!---作成者:ParticleMethod---->
<!---作成日:2024.03.27---->
<!---無断複製・転載・配布を禁じます---->

<!DOCTYPE html>
<html>

  <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>かんたん日報表示</title>
        <p>件名”日報画像送信”でGメールに投稿されたJPEG画像を共有します</p>
        <p>1画像ずつ投稿、かつ次の投稿までに1度は日報を閲覧する前提です</p>


      <p>現在Gドライブのフォルダにある画像:<?=nElm ?>個</p>

      <div>
        <p>本日の報告画像です</p>
        <img  id="myIMG0" width="25%" height="25%"> <BR>
      <div>

      <div>
        <p>前日の報告画像です</p>
        <img  id="myIMG1" width="25%" height="25%"> <BR>
      <div>


  </body>


<!--Img要素のソース設定-->
  <script type="text/javascript">
     //強制実行する無名関数
   (function() {

      //img要素を取得
      var img0= document.getElementById("myIMG0");
      var img1= document.getElementById("myIMG1");


      //スクリプト関数の実行1
      google.script.run
        //成功時の処理:ソースとしてBASE64エンコードされた文字列(res)を設定
        .withSuccessHandler(res => {
          var img= document.getElementById("myIMG0");
          img.setAttribute("src", "data:image/png;base64," + res);
        })
        //実行する関数|★スプレッドシートID★は各自のものを記入
        .getBae64DATAonCell('★スプレッドシートID★','投稿一覧',1,3);


      //スクリプト関数の実行2
      google.script.run
        //成功時の処理:ソースとしてBASE64エンコードされた文字列(res)を設定
        .withSuccessHandler(res => {
          var img= document.getElementById("myIMG1");
          img.setAttribute("src", "data:image/png;base64," + res);
        })
        //実行する関数|★スプレッドシートID★は各自のものを記入
        .getBae64DATAonCell('★スプレッドシートID★','投稿一覧',2,3);


    })();
  </script>

</html>


LoginForm.htmlのコード

以下となります。元のコードを削除した上で貼り付けてください。

★デプロイID★とある部分には、一旦このままでプロジェクトファイルをデプロイし、URLが付与されたら、これを参照して貼り付け、再度デプロイする様にします。

デプロイIDは、デプロイして付与されたリンク先の★~★部分になります。https://script.google.com/macros/s/★~★

---------------
デプロイの補足

このテンプレートでは、デプロイIDを記述する必要がありますが、初回のデプロイ時まで、デプロイIDは判りません。

そのため、とりあえず仮のIDを記述してプロジェクトをデプロイし、デプロイIDが付与されたら、再度同じURLでデプロイし直します。

デプロイIDを打ち替えて再度デプロイする場合は、「新しいデプロイ」ではなく、「デプロイを管理」を選んでください。

「デプロイを管理」を選択し、右側の鉛筆アイコンをクリックして、「新バージョン」を選んでから「デプロイ」をクリックすることで、同じURLでデプロイを更新できます。


この様な手順で、URLを変えないで再デプロイする様にしてください。

(デプロイの補足終わり)
------

コードは以下となります。

パスワードに関する以下のカッコの記述は削除してもかまいません。

<p>
<!---デモなのでパスワードを表示させています---->
パスワードを入力ください(toko)
</p>

<!---「かんたん日報表示」ログイン画面のWEBページ---->
<!---作成者:ParticleMethod---->
<!---作成日:2024.03.27---->
<!---無断複製・転載・配布を禁じます---->

<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>

<body>
  <h1>ログインフォーム</h1>
  <p>
    <!---デモなのでパスワードを表示させています---->
    パスワードを入力ください(toko)
  </p>

  <!---POST送信します。自分自身のリンクへaction【↓ここから】--->
  <!---★デプロイID★は各自のものを記入--->

  <form method="post" action="https://script.google.com/macros/s/★デプロイID★/exec">
    <p>
      <!---相手先では、e.parameter.<name要素名>で取り出せます--->
      <label>パスワード:<input type="text" name="PW"></label>
    </p>
    <p>
      <input type="submit" value="送信する">
    </p>
  </form>
  <!---POST送信します【↑ここまで】--->
</body>
</html>


かんたん日報表示.gsのコード

以下となります。元のコードを削除した上で貼り付けてください。

★スプレッドシートID★とある部分が1ヵ所ありますが、ここは、さきほど用意したスプレッドシートのスプレッドシートIDに、各自で打ち替えてください。

------------
ログインパスワードの補足

ログインパスワードは、このモジュールに記述しています。

myPW == "toko"

以下のソースでここを修正すれば、パスワードは、自由に変えられます。
(ログインパスワードの補足終わり)
------------

//「かんたん日報表示」テンプレートINDEXを表示します
//作成者:Particlemethod
//作成日:2024.03.27 
//日報を表示します

function doPost(e) {
 
  //POST送信された要素名<PW>のデータを取得
  var myPW = e.parameter.PW;

  //パスワードは適宜なものに変えて使用ください
if(myPW == "toko"){
  //アプリケーションを取得|★スプレッドシートID★は各自のものを記入
  var myApp = SpreadsheetApp.openById('★スプレッドシートID★');

  //対象シートをシートの名前を指定して取得
  var mySheet = myApp.getSheetByName('投稿一覧');


  //スプレッドシートのデータ行数を取得
  var nRow=mySheet.getLastRow();



//HTMLファイルのテンプレートをファイル名を指定して取得
  var myHTML = HtmlService.createTemplateFromFile('INDEX');
  
  //★★画像の数をテンプレートに埋め込む★★  
   myHTML.nElm = nRow;
  
  return myHTML.evaluate().addMetaTag("viewport", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=10.0");
}

}

//=====セル上のファイルIDを読み込みBase64エンコードする関数======
function getBae64DATAonCell(SSid,SName,Row,Col) {

  var myApp = SpreadsheetApp.openById(SSid);

  //対象シートをシートの名前を指定して取得
  var mySheet = myApp.getSheetByName(SName);

  var id2=mySheet.getRange(Row,Col).getValue();
 //Gドライブから、ファイルIDでファイルを取得
  const file = DriveApp.getFileById(id2);
  
 //バイナリデータを取得
  const data = file.getBlob().getBytes();
 
 //BASE64エンコードで文字列に変換
   return Utilities.base64Encode(data);
}


ログイン.gsのコード

以下となります。元のコードを削除した上で貼り付けてください。

//「かんたん日報表示」テンプレートLoginFormを表示します
//作成者:Particlemethod
//作成日:2024.03.27 
//ログイン画面を表示します

//★★★★doGet関数はURLから呼び出された時に実行する関数|1つだけ定義できます★★★★
function doGet(e){

//投稿画像をGメールのスレッドから検索しリストを更新
fetchFile_List()

//ログイン画面であるOpenFoam.HTMLをWEBページとしてレスポンスする
  var myOpenHTML = HtmlService.createTemplateFromFile('LoginForm');
  return myOpenHTML.evaluate().addMetaTag("viewport", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=10.0");
}


作品の抽出と保存.gsのコード

以下となります。元のコードを削除した上で貼り付けてください。

★スプレッドシートID★、および★フォルダID★とある部分が各1ヵ所ありますが、ここは、さきほど用意したスプレッドシートのおよび画像保存用のフォルダIDに、各自で打ち替えてください。

//「かんたん日報表示」Gメールから画像を抽出し保存します
//作成者:Particlemethod
//作成日:2024.03.27 
//1.表題が「投稿一覧」であるメールから、添付画像を抽出
//2.画像を所定のフォルダへの保存し、スプレッドシートのリストを更新します


function fetchFile_List() {

  //スプレッドシートとGoogleドライブのフォルダの取得

      //アプリケーションを取得|★スプレッドシートID★は各自のものを記入
      var myApp = SpreadsheetApp.openById('★スプレッドシートID★');
 
      //対象シートをシートの名前を指定して取得
      var mySheet = myApp.getSheetByName('投稿一覧');
      

      //保存フォルダを取得する|Googleドライブの★フォルダID★は各自のものを記入
      const myFolder = DriveApp.getFolderById('★フォルダID★');

  
  //Gメールのスレッドの検索

        //検索条件を設定する |表題に受付番号を含む
      const SEARCH_TERM = 'subject:' + '日報画像送信';
 
      //メールを検索条件で検索する |念のため最大値を30としておく
      const threads = GmailApp.search(SEARCH_TERM, 0, 30);
 
      //検索結果からメールを抽出する
      const messages = GmailApp.getMessagesForThreads(threads);
 
 
  //スターが無いスレッドからファイルを抽出しフォルダに保存する
 
      //検索結果(2次元配列)からメッセージを抽出する
      for(const thread of messages){
        for(const message of thread){
          //スターがないメッセージのみ処理   
          if(!message.isStarred()){ 
            //メッセージから添付ファイルを抽出する
            const attachments = message.getAttachments();                  
            //処理済みのメッセージにスターをつける
            message.star(); 
            for(const attachment of attachments){
              myFolder.createFile(attachment);
            }
          }
        }
      }

  //  フォルダ内のファイルを取得します
  var files = myFolder.getFiles();
  
  // ファイル変数から配列に追加します(最新ファイルが最初の要素になります)
  var list = [];
  while(files.hasNext()) {
    var buff = files.next();
    list.push([buff.getName(), buff.getUrl(), buff.getUrl().slice(32,32+33)]);
  };

  // folder.getFiles()では、ファイルは新しいものが最初に来ます
  // 登録された順にしたい場合は、reverse() で逆順にします
  //list = list.reverse()

  // 対象の範囲にまとめて書き出します
  var range = mySheet.getRange(1, 1, list.length, list[0].length);
  range.setValues(list);

}

一通りコードを貼り付け終わったら、プロジェクトを保存し、一旦仮にデプロイし、デプロイURLを取得します。

次いで、プロジェクトの LoginForm.html のコードで「★デプロイID★」の部分を、デプロイURLから得られるデプロイIDに打ち変えて、再度デプロイします。

試しに作動させてみる


ここまでできたら、作動させてみましょう。

デプロイURLにアクセスしてみます。

以下の様なログインフォームが見られましたか。

次いで、パスワードで「toko」を入力します。ログインが完了し、以下の様な日報が参照できるはずです。

スプレッドシートを確認すると、画像ファイルのリストが以下の様に自動記載されているはずです。

次いで、GASを作成しているgoogleIDのGメールアドレスに、件名を”日報画像送信”として、掲示したい画像ファイルを添付ファイルで送信します。

すると、次にアクセスしたときには、画像が更新されているはずです。

画像ファイルはサイズを小さめでお願いします。

以上、実装コードのご紹介でした。

・コードは実装して稼働することを手元環境で確認しておりますが、環境によっては稼働しない場合もあるかもしれません。こうしたトラブル等をフォローできないため、申し訳ありませんが、不具合時に自己責任・自己解決で対応する事をご了承くださる方だけご利用ください。


・表示させたWEBページからボタンをクリックしても反応しない場合があります。そんな場合は「yahoo!検索」など先にブラウザを開いて、デプロイしたURLを改めて読み込む様にすると、稼働する場合があります。

・個人や小規模なグループ内での利用を想定しており、規模の大きなグループや商用での利用は想定しておりませんのでご注意下さい。

前の記事


GAS(Google Apps Script)でWEBアプリを作成する一般的な手順は、以下にkindle本としてまとめました。かんたんな帳簿アプリを例示して解説しています。

ネットで情報を得ることもできますが、「WEBアプリ」の作成に絞って、端的にまとまった資料を見たい方はどうぞ。(手間代程度の値段ですが、Amazon読み放題で無料で読めると思います)

コードの一般的な解説は以下を参考にしてください。

データベース代わりのGgoogleスプレッドシートと、ブラウザに表示させたテンプレートを使って、簡単な帳票アプリを実装するコードを解説しています。

サーバ側(スプレッドシート)とユーザ側(テンプレート)で、インタラクティブにデータを読み書きする方法を、まとまって解説したGASの解説書は少ないと思います。

実装しているのは、簡単な帳票アプリですが、これを発展させることで多くのWEBアプリを作ることが可能です。アマチュアでも簡単にWEBアプリを作成できるGASについて、少し知りたい方はどうぞお手に取ってみて下さい。

---------------





この記事が気に入ったらサポートをしてみませんか?