【Linebot＋GAS】単語の一問一答ができるボットの完成まで（2）

# 前回記事
https://qiita.com/yugakai72/items/b9af4a324a645c83a9a7
# 使用技術
* Google App Script
* LINE Messaging API
# 機能紹介
今回の記事で解説する機能
### 選択肢
答えの選択肢を ダミー(2) + 正答(1) で出してくれる機能です。<br>
<img width='400' alt="IMG_0910.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115537/bb52fc97-172a-4d74-579d-acf1abfb1d7e.png">

## 選択肢機能
**まずは使っている関数をざっと**<br>
分岐処理の```doPost```
```javascript:doPost
case '選択肢':
      choices(event, targetColumn);
      break;
```
スプレッドシートを読み込み、正答とダミーの誤答2つを生成し、選択肢として返答する```choices```
```javascript:choices
function choices(event, column) {
  var Spreadsheet = SpreadsheetApp.openById(SPREADSHEET_ID);
  let sheet = Spreadsheet.getSheetByName(SpreadsheetName);
  let answer_box = [];
  var str_answer = getData(column);
  answer_box.push(str_answer)

  var false_answerNumber = generateRandomNumArray(35, 2);
  var false_answer1 = sheet.getRange(false_answerNumber[0], 1).getValue();
  var false_answer2 = sheet.getRange(false_answerNumber[1], 1).getValue();
  answer_box.push(false_answer1);
  answer_box.push(false_answer2);

  var question_number = generateRandomNumArray(4, 3);
  let options = makeChoicesOption(event, answer_box[question_number[0] - 2], answer_box[question_number[1] - 2], answer_box[question_number[2] - 2]);
  UrlFetchApp.fetch(URL, options);
}
```
## コードの解説
### 1. スプレッドシートを取得
```javascript
  var Spreadsheet = SpreadsheetApp.openById(SPREADSHEET_ID);
  let sheet = Spreadsheet.getSheetByName(SpreadsheetName);
```
### 2. 正答の取得
[前回の記事](URL"https://qiita.com/yugakai72/items/b9af4a324a645c83a9a7")の```insert```で登録した正答を```getData```で取得。その正答を```answer_box```に代入している。
```javascript
  let answer_box = [];
  var str_answer = getData(column);
  answer_box.push(str_answer)
```
### 3. 誤答の作成
```generateRandomNumArray```で乱数を2つ取得し、ダミーを2つ作成。その後```answer_box```に代入
```javascript
  var false_answerNumber = generateRandomNumArray(35, 2);
  var false_answer1 = sheet.getRange(false_answerNumber[0], 1).getValue();
  var false_answer2 = sheet.getRange(false_answerNumber[1], 1).getValue();
  answer_box.push(false_answer1);
  answer_box.push(false_answer2);
```
ランダムな整数を配列にして返してくれる```generateRandomNumArray```
```javascript:generateRandomNumArray
/** 
ランダム整数を生成して配列に格納するクラス
引き数1：最大値
引き数2：配列に格納するランダムな数字の数
**/
function generateRandomNumArray(maxNum, generateArrayLength) {
  let generateArray = []; //ランダム格納用配列
  let numberArray = []; // ランダム生成用配列

  //(2~maxNum)ランダム生成用配列を作成
  for (let i = 2; i <= maxNum; i++) {
    numberArray[i - 2] = i;
  }

  //ランダム格納用配列にランダム整数を格納
  for (let j = 0, len = numberArray.length; j < generateArrayLength; j++, len--) {
    let rndNum = Math.floor(Math.random() * len);
    generateArray.push(numberArray[rndNum]);
    numberArray[rndNum] = numberArray[len - 1];
  }

  return generateArray;
}
```
### 4. 正答と誤答の選択肢順番をシャッフルして返答
現在のまま配列を返答してしまうと、毎回選択肢が（正答、誤答1、誤答2）の順番で固定されてしまうため、```question_number```に出題順番を乱数で決定。その後、選択肢返答用の```options```を作成して```UrlFetchApp.fetch(URL, options)```で返答。
```javascript
  var question_number = generateRandomNumArray(4, 3);
  let options = makeChoicesOption(event, answer_box[question_number[0] - 2], answer_box[question_number[1] - 2], answer_box[question_number[2] - 2]);
  UrlFetchApp.fetch(URL, options);
```
返答用のFlexMessageを作成する```makeChoicesOption```
（※前回の記事の```makeQuestionOption```とは異なるので注意）
```javascript:makeChoicesOption
//選択肢用のFlexMessageOption作成
function makeChoicesOption(event, choice1, choice2, choice3) {
  HEADERS = {
    "Content-Type": "application/json; charset=UTF-8",
    "Authorization": "Bearer " + ACCESSTOKEN,
  }
  postData = {
    "replyToken": event.replyToken,
    "messages" : [
      {
        'type':'flex',
        'altText':'選択肢',
        'contents': 
        {
          "type": "bubble",
          "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
              {
                "type": "text",
                "text": "選択肢",
                "weight": "bold",
                "color": "#4F6F52",
                "size": "sm",
                "align": "center"
              },
              {
                "type": "separator",
                "color": "#4F6F52",
              },
              {
                "type": "text",
                "text": '1. ' + choice1,
                "weight": "bold",
                "size": "md",
                "margin": "md",
                "scaling": true,
                "adjustMode": "shrink-to-fit"
              },
              {
                "type": "separator",
                "color": "#4F6F52",
              },
              {
                "type": "text",
                "text": '2. ' + choice2,
                "weight": "bold",
                "size": "md",
                "margin": "md",
                "scaling": true,
                "adjustMode": "shrink-to-fit"
              },
              {
                "type": "separator",
                "color": "#4F6F52",
              },
              {
                "type": "text",
                "text": '3. ' + choice3,
                "weight": "bold",
                "size": "md",
                "margin": "md",
                "scaling": true,
                "adjustMode": "shrink-to-fit",
              },
              {
                "type": "separator",
                "color": "#4F6F52",
              },
            ],
            "backgroundColor": '#E8DFCA'
          },
          "styles": {
            "footer": {
              "separator": true
            }
          }
        }
      }
    ]
  }
  let options = {
    "headers": HEADERS,
    "method": "post",
    "payload": JSON.stringify(postData),
  };
  return options;
}
```
```"type": "box"```、```"layout": "vertical"```で垂直レイアウト方向を定義。
```"type": "text"```でテキストコンポーネントを作成
```"type": "separator"```で分割線を作成
```scaling```プロパティを```true```、```adjustMode```プロパティを```shrink-to-fit```にすることでテキストサイズが自動調節され、選択肢が1行になる。
FlexMessageのコンポーネントについてより知りたい方は[こちら](URL"https://developers.line.biz/ja/docs/messaging-api/flex-message-elements/#component")。
FlexMessageのレイアウトについてより知りたい方は[こちら](URL "https://developers.line.biz/ja/docs/messaging-api/flex-message-layout/#other-component-size")。
# 次回に続く
https://qiita.com/yugakai72/items/895eb609342f31519e03