子育てを効率化したくてGASを妻に教えた結果

[子育てエンジニア Advent Calendar 2018](https://adventar.org/calendars/3178)４日目です。
Google Apps Script を妻に教えた話。

## TL;DR
妻に教えて、だいたい2週間で、こんなところまで出来ました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/247444/ab5b6c9a-1f1a-ffab-3585-35b3af10ea08.jpeg" width="50%">

育児日記ライクなSlack botです。


## 課題
気づけば２児の父のawa2です。普段はセキュリティをやっています。
エンジニアが子供をもつと真っ先に感じるのは「コードを書く時間がない！」ということではないでしょうか。子育てという業務の用件は次のように厳しいです。

 * 常時リアルタイム対応
 * 割り込み命令多数
 * 夫婦で最大2人/月までの工数で対応しなければならない

いやいや、こっち夫婦業務やっと慣れてきたのに、子どもの成長激しすぎる。お前はスタートアップか何かか。お父さんの知らないところで第三者割当増資でもうけてんのか。

## 課題解決の方向性
妻をエンジニアにして、圧倒的な効率化を図る。
具体的には...
「妻が自分で使いやすい育児日誌を作って、情報共有を円滑にする」

## 妻のスキル
 * プログラミングは全くやったことがない
 * エクセルはSUM関数までならわかるけど、vlookupはむり
 * Macbook Airは１年ぐらい前にかわいいので買った

とはいえ、妻自身は「このままでは二人目が生まれたら我が家は大変だ！」「夫婦間の円滑な情報共有が必要だ！」「わたしもプログラミングで圧倒的生産性とやらをやってみたいぞ！」と意欲はありました。さすがです。

## Google Apps Scriptを教えてみた
### Why GAS?
 * 実行環境がすぐ整う（サーバレス最高）
 * Spreadsheetなどわかりやすいものを簡単に動かせる
 * JavaScriptな文法なので、とっつきやすい（はず）

### スケジュール
だいたいこんな流れで教えました。

 * Day1
   * Google Formを使ってみる
   * Google Formの記録をSpreadsheetで見る
   * フロントエンドとデータベースとバックエンドの話
   * Google Apps Scriptとは
   * Spreadsheetからエディタを起動してみる
 * Day2
    * GASコンソールの見方
    * Hello, world!
    * JavaScript is 何
    * 変数 var
    * 出力する：Logger.log
    * 文字列型と数字型
    * 文字列の結合、数字の計算、文字と数字の結合
 * Day3
    * コメント文
    * if文
    * switch文
    * 四則演算と剰余
    * 課題：「うるう年を判定するプログラムをつくる」
 * Day4
    * 配列とオブジェクト
    * スコープっていうのはでかい箱
    * SlackApp
 * Day5
    * 配列とオブジェクトへのアクセス
    * 配列とfor文
 * Day6
    * 関数 function
    * スコープっていうのはでかい箱２
    * SpreadsheeetAppの使い方
    * GmailAppの使い方
 * Day7
    * Triggerの設置
    * デバッグの方法
    * イベントオブジェクトe


## 教えてみた結果

 * 意外とあっさりとアプリをつくれた
    * SlackAppやGmailAppで「実際の動くコードから通知が来るが楽しかった」らしい
    * フロントは、Google Formだけにしたので、フィールドの試行錯誤も楽しかった模様
    * GASすごい
 * ひっかかったところ
    * if文が入れ子になると混乱していた
        * しばらく「うるう年」の課題は難航していた
 
初学者に教える、というのをすごく久しぶりにやったので、僕自身も勉強になりました。

## 実際のソースコード
妻の許可を得て公開。

```JavaScript
function onFormSubmit(e) { //イベントトリガー　登録したら走る

  var TOKEN = '<MASKED>';
  var Slack = SlackApp.create(TOKEN);

  console.log(e);
  Logger.log(e.values);
  var data = e.values;

  var created_at = new Date(data[0]);
  var occured_date = data[1];
  var occured_time = data[2];
  var milk = data[3];
  var poo = data[4];
  var vomit = data[5];
  var medicine = data[6];
  var heat = data[7];
  var height = data[8];
  var weight = data[9];
  var memo = data[10];
  
  var occured_at = new Date();

  var text = '♡なおくん新着情報♡\n';

  if (!occured_date) {
    // [1]日付入力がない場合
    if (!occured_time) {
      // [1-1]日付入力なし＆時刻なし → タイムスタンプから現在時刻を引用する
      text = text + created_at.toLocaleString() + 'に\n';
      occured_at = created_at;
    } else {
      // [1-2]日付入力なし&時刻入力あり → タイムスタンプの現在時刻 + 入力時刻
      text = text + created_at.toLocaleString().split(' ')[0] + '  ' + occured_time + 'に\n';
      occured_at = new Date(created_at.getFullYear(),created_at.getMonth(),created_at.getDate(),occured_time.split(':')[0],occured_time.split(':')[1],occured_time.split(':')[2]);
    }
  } else {
    // [2]日付入力がある場合
    if (!occured_time) {
      // [2-1]日付入力のみで、時刻入力なし 　→ タイムスタンプから現在時刻を引用する ※このパターンは少ないと想定される
      text = text + occured_date + '  ' + created_at.toLocaleString().split(' ')[1] + 'に\n';
      occured_at = new Date(occured_date.split('/')[0],new Number(occured_date.split('/')[1])-1,occured_date.split('/')[2],created_at.getHours(),created_at.getMinutes(),created_at.getSeconds());
    } else {
      // [2-2]日付入力あり&時刻入力あり → そのまま結合
      text = text + occured_date + '  ' + occured_time + 'に\n';
      occured_at = new Date(occured_date.split('/')[0],new Number(occured_date.split('/')[1])-1,occured_date.split('/')[2],occured_time.split(':')[0],occured_time.split(':')[1],occured_time.split(':')[2]);
    }
  }

  if (milk) {
    text = text + 'ミルクを' + milk + '飲みました！\n'
    // ミルクログを作成する部分
    SpreadsheetApp.openById('<SPREADSHEET_ID>').getSheetByName('ミルク').appendRow([occured_at, milk]);
  }

  if (poo == 'なし' || poo == '') {// || orと同じ意味
  } else {
    text = text + '💩' + poo + '！\n'
  }

  if (vomit == 'なし' || vomit == '') {
  } else {
    text = text + vomit + '吐いちゃった｡｡｡\n'
  }

  if (medicine) {
    text = text + medicine + 'GET！\n'
  }

  if (heat) {
    text = text + '熱は' + heat + '度でした！\n'
  }

  if (height) {
    text = text + '身長は' + height + 'cmでした！\n'
  }

  if (weight) {
    text = text + '体重は' + weight + 'gでした！\n'
  }

  if (memo) {
    text = text + '✍' + memo
  }

  //Slack.postMessage('#sandbox',text);
  Slack.postMessage('#homechannel', text);
  
}
```
二人目の子が臨月になってから開発を始め、無事に生まれるまでに完成し、今も夫婦で使っています。
フロントがGoogle Formなので、そのままURLをiPhoneのHomeに登録し、アプリのようにシングルアクションで呼び出せるようにしています。
今後は、Google Calenderに連携させたいと言っていました。

## 学び
 * 「動く」「試行錯誤できる」は、とても大事な環境
    * そういう意味でもGASはいいかも
 * 明確な目的があれば、初学者でも自分の欲しいものを作れる
    * 欲しいものドリブンは大切
 * 夫婦で教え合う
    * 良い経験になりました
    * 妻よ、いつもありがとう