11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【GAS】クイズアプリで忘年会を盛り上げたい

Posted at

corp-engr 情シスSlack(コーポレートエンジニア x 情シス) Advent Calendar 2019の1日目の記事です。
Google Apps Script(以下GAS)でネタを探していたところで、忘年会で使おうとクイズアプリを作ったので紹介します。
コーポレートエンジニアあんまり関係ないかもw

#はじめに
12月に入って本格的に忘年会シーズンですね。
忘年会盛り上げるためにクイズ大会でもしたいな、と思ってKahoot!使おうと思ってたのですが、Free版だと人数やなにやら制限がありそうなので作れないかとやってみました。
結果、似たようなことができそうだったので紹介します。

クイズアプリに限らずこういったウェブアプリが作れるということを知ってもらい、GAS好きがもっと増えてほしいな。

#想定読者

  • GASは触ったことあるけどWebアプリは作ったことなく、興味のある方
  • 忘年会何するか決めかねている方

#注意点

  • GASってなんぞ?という方には少し難しいかもしれません。
  • 本記事ではCSSを記述していません。これから。
  • 数十人で使った場合ちゃんと動くのか怪しいです。
  • 結局、盛り上がるかは司会者次第でしょう。

#こんな感じの出来上がり
quiz1.gif

#ユーザー登録画面
まずはスプレッドシートを開いて、ツール > スクリプトエディタでScriptEditorを開きます。
プロジェクト名、コード.gsの名前を適当に変更しましょう。
image.png
最初に呼び出すHTMLを作成します。
ファイル > New > HTMLファイル loginと名前をつけてOK

login.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <form method="post" action="(ウェブアプリケーションのURL)?p=0">
      <p><label>ユーザー名を入力してください。</label></p>
      <p><input type="text" name="name"></p>
      <p><input type="submit" value="ENTER"></p>
    </form>
  </body>
</html>

(ウェブアプリケーションのURL)は後ほど説明します。
GASの処理で利用するためURLに?p=0とパラメータを付与しています。
こうすると、GASでe.parameter['p']とすることで付与した0が取得でき、現在のページの判定として使用しています。
0 = login 1 = start など

HTMLを表示させるためquiz.gsに書きます。

function doGet(e){
    return HtmlService.createHtmlOutputFromFile('login');  
}

Google Apps Script Class HtmlService

動作確認のためデプロイしてみましょう。
公開 > ウェブアプリケーションとして導入...
スクリーンショット 2019-11-29 23.53.53.png
デプロイするとURLが発行されるのでコピーして先ほどのlogin.htmlの(ウェブアプリケーションのURL)に設定します。

そしてもう一度デプロイしましょう。
HTMLやGASの変更を動作確認する際は都度デプロイする必要があります。毎回です。
変更を適用するデプロイは必ずProject versionNewにするのを忘れないようにしてください。
ちなみに何度デプロイしてもウェブアプリケーションのURLは変わりません。

URLにアクセスしてみてください。
image.png

#スタート画面
ユーザー名を入力したらスプレッドシートに記録します。
そしてスタート画面に遷移させたいのでHTMLファイルを追加してください。

start.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <form method="post" action="(ウェブアプリケーションのURL)?p=1">
      <p><label><?=name?>さん</label></p>
      <input type="hidden" name="name" value=<?=name?>>
      <p><label>案内があるまでお待ちください...</label></p>
      <p><input type="submit" value="START!!!"></p>
    </form>
  </body>
</html>

login画面の次に表示される画面になるのでパラメータには?p=1を設定します。
GASのdoPostに以下の処理を追記します。

  • login.htmlからのパラメータを受け取る
  • スプレッドシートにユーザー名を記録
  • ユーザー名を付与してstart.htmlを呼び出す
function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSheet(); 
  var columnValue = sheet.getRange('A:A').getValues();
  var lastRow = columnValue.filter(String).length;  //最終行を取得
  var pages = [  //全ページを配列で持つ
    "login",
    "start"
  ];
  var currentPage = pages[e.parameter["p"]];  //URLに付与したパラメータ(?p=0)から現在のページを取得
  var nextPage = pages[parseInt(e.parameter["p"], 10) + 1];  //次のページを取得

  if (currentPage === "login") {
    sheet.appendRow([lastRow, e.parameter.name]);  //ユーザー名をスプレッドシートに追加
  }

  var tpl = HtmlService.createTemplateFromFile(nextPage);
  tpl.name = e.parameter.name;
  return tpl.evaluate();
}

デプロイするとスプレッドシートへのアクセス承認が必要になりますので指示に従って承認します。
終わったらlogin画面でtestと入力してENTERをクリックして確認してみましょう。
image.png
image.png
image.png
#あとは複製するだけ
ここまで理解できればあとは複製してクイズ画面を作っていきます。
quiz1.html を作り、複製してquiz2.html quiz3.htmlとクイズの終わりに表示するend.htmlファイルを作成しそれぞれHTMLを記述します。

quiz1.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <form method="post" action="(ウェブアプリケーションのURL)?p=2">
      <p><label><?=name?>さん</label></p>
      <input type="hidden" name="name" value=<?=name?>>
      <p><label>第 1 問</label></p>
      <p><label>Twitterで、一度に投稿できるテキストの文字数は最大何文字?</label></p>
      <p><input type="submit" name="quiz" value="120文字"></p>
      <p><input type="submit" name="quiz" value="140文字"></p>
      <p><input type="submit" name="quiz" value="160文字"></p>
      <p><input type="submit" name="quiz" value="180文字"></p>
    </form>
  </body>
</html>
end.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <form method="post" action="(ウェブアプリケーションのURL)?p=5">
      <p><label><?=name?>さん</label></p>
      <input type="hidden" name="name" value=<?=name?>>
      <p><label>お疲れ様でした〜!</label></p>
    </form>
  </body>
</html>

そして最終的なquiz.gsはこんな感じです。

function doGet(e){
    return HtmlService.createHtmlOutputFromFile('login');  
}
function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSheet(); 
  var columnValue = sheet.getRange('A:A').getValues();
  var lastRow = columnValue.filter(String).length;
  var pages = [
    "login",
    "start",
    "quiz1",
    "quiz2",
    "quiz3",
    "end"
  ];
  var currentPage = pages[e.parameter["p"]];
  var nextPage = pages[parseInt(e.parameter["p"], 10) + 1];
  var tpl = HtmlService.createTemplateFromFile(nextPage);

  if (currentPage === "login") {
    sheet.appendRow([lastRow, e.parameter.name]);
  }
  if(currentPage.indexOf("quiz") === 0){
    //quizの場合は回答を記録
    answer(sheet, lastRow, e.parameter.name, e.parameter.quiz, parseInt(e.parameter["p"]) + 1)
  }

  tpl.name = e.parameter.name;
  return tpl.evaluate();
}
function answer(sheet, row, user, answer, column) {
  var users = sheet.getRange(1,2,row).getValues();

  for(var i = 0; i < users.length; i++) {
    if (users[i] == user) {
      sheet.getRange(i + 1, column).setValue(answer);
    }
  }
}

#これからやること

  • CSS
  • 結果やランキングがわかるようにする

#最後に
とりあえず作ってみようって感じで調べつつ、動かしつつ進めたのですが、なんだかんだであとデザインちゃんとしたら普通に使えそうだなって思いました。
スプレッドシートへの書き込みとか大人数で期待通り動くかは少し心配。
あと問題文はプロジェクターで投影して、回答のみ手元のアプリでやってもらう方がいいんじゃ...?

#おまけ
CSS適用するとなかなか良い感じ。
image.png

#参考記事
GoogleAppsScript(GAS)でページ遷移を擬似的に実装する方法
Google Apps Scriptで簡単にWebアプリケーションを公開する方法
Google Apps ScriptでWebアプリケーションを作る最初の一歩 HtmlServiceオブジェクトとは
htmlとgoogle apps script間の値の引渡しについて
GASでGetパラメータを受け取ってスプレッドシートに書き込む方法
GASでWebページを作るときにHTMLとCSSを別ファイルに記述する方法
コピペでできる!cssとhtmlのみでフォームのテキストエリアをわかりやすくするデザイン15選

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?