子供の体温表を楽に作る

# はじめに
子供が熱を出すと、小児科で「はい、これ書いてきてね」と渡される体温記録の紙。ネット上にもいろいろあります。HAL先生の[こちら](http://halproject01.blogspot.jp/2017/04/dl.html)とか。
でも、これがよく忘れるんですよ。体温を測ったのにすぐに書かなかったら何度だったか忘れた、点をうつ位置を間違えた、はてはせっかく書いた体温表なのに医者に持っていくのを忘れた（我が家はこれがすごく多い）。
そういうわけで、もう少し楽をすることにしました。
もともと夫婦間で情報共有のため、slackに子供のことを書く専用channelがあります。そこに体温を投稿したら、Googleスプレッドシートに登録されるようにしました。

# 参考サイト
[Slack BotをGASでいい感じで書くためのライブラリを作った](https://qiita.com/soundTricker/items/43267609a870fc9c7453)
[SlackとGASを使って会社のお弁当発注を自動化した話](https://qiita.com/kazuooooo/items/3a605a4d0e20df870eaf)
　コードの大半はお弁当発注のものを参考にさせていただきました。ありがとうございます！

# 作ったもの
## 仕様
slackのOutgoing WebHooksを設定したchannelで
```
taion: 36.8
```
とかつぶやくと、Googleスプレッドシートに記録されます。
正常に登録できると「ok」が返ってくる。

![taion_slack.JPG](https://qiita-image-store.s3.amazonaws.com/0/143174/38eb128b-e8ff-59f1-f925-f46ca3f4a826.jpeg)

登録される値は
- 日時
- 体温
- 登録者

![taion_spreadsheet.JPG](https://qiita-image-store.s3.amazonaws.com/0/143174/557f105d-9d45-a3be-50eb-d9014aed3fdb.jpeg)

デフォルトではつぶやいた日時を「日時」として採用、体温のあとにスペース区切りで時刻を入れた場合は、その時刻の記録として登録されます。

```
taion: 36.9 6:30
```
→　つぶやいた当日の6:30の記録になる。
また、当日+つぶやいた時刻が、現在時刻よりも先の場合は、前日に補正して記録します。
```
(12/31 7:00に以下をつぶやく)
taion: 36.7 19:00
```
→ 12/30 19:00の記録になる。

## 実装と設定
ううむ、作ったのが半年くらい前だからもう記憶が怪しい
### Googleスプレッドシート側の設定
- GASコード

```js:code.js
Const = {
  spreadSheetId: 'GoogleスプレッドシートID',
  sheetName: '記録するスプレッドシートのシート名',
  verifyToken: 'slackのverify Token'
}

function verifyToken(e) {
  return Const.verifyToken == e.parameter.token;
}

function parseRequest(e) {
  var request = {};
  request.user = e.parameter.user_name;
  var data = parseText(e.parameter.text);
  if (! data){
    request.raw = e.parameter.text;
  } else {
    request.temp = data[0];
    request.dateTime = data[1];
  }
  return request;  
}
function parseText(str){
  var reg = /(^taion:|^体温:)\s*(\d{2}\.?\d?)[℃度]?\s*(\d{1,2})?\s*[:時]?\s*(\d{1,2})?/;
  var matches = str.match(reg);
  if (matches) {
    var temp = matches[2];
    var dt = new Date();
    if(matches[3] != null){
      var hour = parseInt(matches[3] ? matches[3] : '0');
      var min = parseInt(matches[4] ? matches[4] : '0');
      dt = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), hour, min, 0);
      if (dt > new Date()){
        dt = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate() - 1, hour, min, 0);
      }
    }
    return [temp, dt];
  }
  return null;
}
function doPost(e) {
  var prop =  PropertiesService.getScriptProperties().getProperties();
  
  if (! verifyToken(e)) {
    throw new Error("invalid token.");
  }

  var result;
  if (e.parameter == undefined) {
    result = 'error';
  }else{
    var sheet = SpreadsheetApp.openById(Const.spreadSheetId).getSheetByName(Const.sheetName);

    var request = parseRequest(e);
    if (request){
      var array = [request.dateTime, request.temp, request.user];
      if (request.raw != null){
        array.push(request.raw);
      }
      sheet.appendRow(array);
      result = 'ok';
    } else {
      result = 'parseError:' + e.parameter.text;
    }
  }
  var slackApp = SlackApp.create(prop.slackToken); 

  slackApp.chatPostMessage(e.parameter.channel_id, result, {
    username : e.parameter.user_name});

  return null;
}
```
- コードの簡単な説明
    - slackからpostされてきた値を、tokenのverifyして、値をparseして、体温と時間を取り出し、スプレッドシートの一番下に追加して、slackに「ok」って返してます。
    - slackへの返却にはSlackAppを使わせていただいています（https://qiita.com/soundTricker/items/43267609a870fc9c7453）
    - function
        -   doPost : post時処理。
        -   verifyToken : slack tokenのverify処理
        -   parseRequest: slackから来たrequest内容のパース。user名の取得と、テキスト内容の取得。
        -   parseText: テキスト内容のパース。コードが超イマイチなのは自覚している。 

- GAS公開
    - https://qiita.com/soundTricker/items/a4878d7e3100082576e4 あたりを参考に、ウェブアプリケーションとして導入を行った。
    - ウェブアプリケーションのURLを後でslackに設定するので保存しておく
    - アプリケーションにアクセスできるユーザは「全員」
![GAS_web_application.PNG](https://qiita-image-store.s3.amazonaws.com/0/143174/ebbaeb36-4895-db04-5fee-aa094e657bb4.png)
- シート作成
    - シート名はコードの Const.sheetName　にいれる。
    - シートのA, B, C列を使う。
    - 必須ではないけれど、先頭行に日時、体温、登録者をいれておくほうがわかりやすい。

### Slack側の設定
- Outgoing WebHooks追加
    - App追加でOutgoing WebHooksを追加
    - 設定項目
        - Channel: 特定のchannelのみ連動するようにした
        - Trigger Word(s): taion:.体温:
        - URL(s): GASのウェブアプリケーションのURLをいれる
        - Token: GASのコードのConst.verityTokenの値を入れるか、あるいは、ここの値を、GASのコードのConst.verityTokenに入れて、再度ウェブアプリケーションの公開を行う。
        
![slack_outgoing_webhook_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/143174/0a2f4e1e-ed16-8e46-731c-e083fd87b01c.png)

# 蛇足
## 我が家での使い方
我が家ではこれで記録された体温のシートにグラフを作って表示しています。
![体温シート.PNG](https://qiita-image-store.s3.amazonaws.com/0/143174/9ef014e1-e929-768f-0bbc-bf5703e8ed4c.png)
グラフの範囲とかは毎回手作業で修正。
時系列を逆に投稿しちゃったものなども手作業で修正。

なぜ作って半年近くたってから公開をしたかというと、またしても子供が熱をだしてこの機能のお世話になったからです。いつになったら熱を出さなくなるのか。。。