CAM TECH BLOG

株式会社CAMのエンジニア・デザイナーの活動を綴るブログです

株式会社CAMの技術ブログです。 エンジニアとデザイナーの活動や組織文化を綴ります。

Web初心者がGASでいいね!ボタン作ってみた

f:id:cam-engineer:20181207104727p:plain

こんにちは。シーエー・モバイル19内定者の木戸優奈です。北海道の函館から、リモートで広報インターンさせて頂いています!

今回は、社内カルチャー発信サイトである、CAMedia (キャメディア)に導入させていただいた、「 GAS を用いたいいね!ボタン」について紹介しようと思います。


f:id:cam-engineer:20181206185445p:plain
▲ 社内カルチャー発信サイト「CAMedia」の1ページ。右下にいいねボタンを設置します

CAMediaは Google Sites を利用しており、そこで自由に javascript を書くには、少し不便な環境です。そこで、今回は GAS を使用することにしました。


GAS ( Google Apps Script ):

GAS は Google が提供するサーバサイド・スクリプト環境であり、独自にサーバ構築する必要がなく、Web アプリケーション等を公開することができます。

いいね!機能の概要

ページを開く際に、そのページ ID に対応するカウント数をスプレッドシートから取得し、表示させる該当するページ ID がなかった場合(初めてそのページを開く場合)、新しいページID をスプレッドシートに追加する(その際、カウント数は0とする)

いいね!ボタンがクリックされたら、そのページ ID に対応する行をスプレッドシートから探し、見つけたら2列目のカウント数に+1する


f:id:cam-engineer:20181206175645p:plain
f:id:cam-engineer:20181206175652p:plain


以下、コードです。


【1】ページを開く際に、そのページ ID に対応するカウント数をスプレッドシートから取得し、表示させる

最初に、URL からパラメータを取得し、ページ ID と type (今回は利用していませんが、判定を入れることで「いいね!」と「へぇ〜」の切り替えを可能とします)を変数に代入しています。次に、スプレッドシートの情報を取得しています。

/*コード.gs*/
function doGet(e){
  var id = e.parameter['id']; //URLからパラメータ取得
  var type = e.parameter['type'];
  var t = HtmlService.createTemplateFromFile('index'); //htmlファイル名

  if(id){
    var data = SpreadsheetApp
    .openById('XXXXXX') //スプレッドシートID
    .getActiveSheet()
    .getDataRange()
    .getValues();  //シートの値全てを、data配列に格納
    
    t.data = data;
    t.id = id; 
    t.type = type;
    
    var flag = false;
    
    for (var i = 1; i < data.length; i++) {
      // 行からデータ取る
      var pageId1 = data[i][0];  //ページIDの列
      var count1 = data[i][1];  //カウント数の列
      
      if(pageId1 == id){     
        t.count = count1;
        flag = !flag;
        break; //ループ終了
      }
    }
  

最初に flag を false とすることで、該当するページ ID の行がなかった際の処理を書く分岐としています。該当するページ ID があれば、flag を true とし、ループは終了します。


【2】該当するページ ID がなかった場合(初めてそのページを開く場合)、新しいページID をスプレッドシートに追加する(その際、カウント数は0とする)

また、ID が null の場合は、ボタンに表示させるためのカウント数の部分を「機能は準備中です」と設定します。その場合、下の画像のように表示します。

if(flag === false){ //ページIDがシートになかったら
      t.count = 0;  
      SpreadsheetApp
      .openById('XXXXXX')
      .getActiveSheet().appendRow([id,0]); //最後の行に追加
    }
  }else{
    t.id = null;
    t.count = "機能は準備中です";
  }

表示させるためのカウント数が取得できたら、ページを開きます。

return t.evaluate();
}
f:id:cam-engineer:20181206175656p:plain


【3】いいね!ボタンがクリックされたら、そのページ ID に対応する行をスプレッドシートから探し、見つけたら2列目のカウント数に+1する

上記のコードでもそうですが、スプレッドシートの情報をやり取りするので、API の呼び出しは必然的に多くなってしまいます。 そこで、配列を活用し呼び出し回数が少なくなるように工夫しています。

function Count(PageIdClick){  //クリックされたら
  
   var spreadSheet = SpreadsheetApp.openById('XXXXXX'); 
   var sheet = spreadSheet.getSheetByName('シート1'); 
   var list = sheet.getDataRange().getValues();  //シートの値全てを、List配列に格納

    // ループ
  for(var i = 1; i < list.length; i++) {
     // 行からデータ取る
     var pageId2 = list[i][0];  //ページIDの列
     var count2 = list[i][1];  //カウント数の列

     // 実際のカウント判定&処理
     if( pageId2 == PageIdClick ){
       sheet.getRange(i+1, 2).setValue( ++count2 );
       break; // ここでループ終了
     }
   }
 }

以上で GAS 側の処理は終了です。あとは、これらを html で表示させます。

<!-- GoodCounter.html -->
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
        <style type="text/css">
        </style>
  </head>
  <body>
  <script>
   
 function changeValue(pageNumber){ //リアルタイムに+1
    if(pageNumber){
      var values = document.getElementById("number").value.split(" ");
      values[1]++;
      document.getElementById("number").value = values[0] + " " + values[1];
    }
   }
   
   
  </script>
  
  <? var likeNumber = count?> <!--GAS側の変数を使用 -->
  <? var pageNumber = id ?>
        
    <input type="button" class="square_btn" id="number" value=<?= "いいね! " + likeNumber ?> onclick= "this.disabled = true;changeValue(<?= pageNumber ?>);google.script.run.Count(<?= pageNumber ?>)"  />


  
  </body>
</html>

css は割愛させていただきます。 ボタンを押した時に、スプレッドシートに+1するのと別に、見かけだけの数字も+1しています。これは、リアルタイムでの+1表示をするためです。

google.script.run.Count(<?= pageNumber ?>)

ここで、GAS 側の Count 関数に、ページ ID を引数として渡しています。

流れは以上です。これで、以下の画像のように「いいね!」の文字と、そのページに対応するカウント数が表示されます。

f:id:cam-engineer:20181206175652p:plain


最後に

GAS と html での値引き渡しに苦労しました。。。

(参考:GAS ⇔ html 間の値の渡し方 ) teratail.com

また、スプレッドシートの万能さに感動しました!

最初はいいね!機能と聞いて「サーバが必要?」「どうやって保存しよう」と困ったのですが、見事に解決してくれました。

また、運用するにあたって、コードのスリム化や読みやすさの向上など仕事でコードを書く上での大切なことをたくさん学びました。

まだまだスマートなコードには程遠いですが。。。先輩方からたくさん吸収して、もっともっと学んでいこうと思いました。



著者紹介

f:id:cam-engineer:20181206182124p:plain
木戸優奈 ( きど ・ ゆうな )
公立はこだて未来大学 システム情報科学部 複雑系知能学科4年在学中。大学では数学・データサイエンスを専攻。Web は独学。HTML・Javascript を目下勉強中。