急性中耳炎の重症度が分かるLINE Botの作成

##概要
プログラムの勉強を始めて4か月ほどの開業医です。
病気のおすすめの診断法や、治療法などを記載した診療ガイドランというものがあります。診療ガイドラインに従うことは強制ではないのですが、エビデンスに基づいた治療をするためにはガイドラインは重要です。しかし、忙しい臨床現場ではガイドライン通りに診療を進めることが難しい場合もあります。
今回、小児急性中耳炎の診療ガイドライン（2018年-日本耳科学会)に沿って、急性中耳炎の重症度と推奨治療が簡単に分かるLINE Botを作成しました。
医師が臨床現場で使えることはもちろんですが、一般の方でも医療機関で**「鼓膜の赤さ・腫れ・耳垂れ」の程度**を医師に聞いていただくと急性中耳炎の重症度が判定できます。


##実装
LINE上で質問に答えていくとスコアリングが行われ、急性中耳炎の重症度と推奨治療が分かるLINE Bot。
##概念図
node.js expressでLINE bot APIを連携しました。
<img width="287" alt="line nodejs.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/339f9691-c138-e002-e9c2-5f513e8104ab.png">

##作成方法
**1. Botアカウントを作成する**

**2. Node.jsでBot開発**

**3. ngrokでトンネリング**

上記の1～3を以下の参考記事の通りに行います。
[1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 ](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)

**4. プログラム作成**

コードを以下のように書き換えます。
今回は、LINE Developersの**クリックリプライ**を使いました。
[LINE Developers](https://developers.line.biz/ja/reference/messaging-api/?fbclid=IwAR2DtZhpwt5RTYMnWfpnCOkhsXWbBBt5Dw3qTIOazY-rjb1sowRzcTkQyW8#confirm
)

```js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: 'channelSecretを入力',
    channelAccessToken: 'channelAccessTokenを入力'
};


const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
  console.log(req.body.events);
  
  //ここのif分はdeveloper consoleの"接続確認"用なので削除して問題ないです。
  if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
    res.send('Hello LINE BOT!(POST)');
    console.log('疎通確認用');
    return; 
  }
  
  Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

    
const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  // LINE botのプログラム 
  let message = event.message.text;
  let question = "";
  let label1, label2, label3 = "";
  let text1, text2, text3 = "";
  
  let [mes, currentScore] = message.split(":");  
 
  if (message == "開始") {    
    currentScore = 0;
    question = "2歳未満ですか？";
    label1 = "いいえ";//0
    text1 = "2歳以上 トータルスコア:"+String(currentScore);
    message = text1;
    label2 = "はい";//3
    text2 = "2歳未満 トータルスコア:"+String(currentScore+3);
    message = text2;
    label3 = "選択できません";
    text3= "開始";
    message = text3;
  } else if (mes == "2歳以上 トータルスコア"|| mes==  "2歳未満 トータルスコア") {
    question = "耳は痛いですか？";
    label1 = "いいえ";//0
    text1 = "耳は痛くない トータルスコア:"+String(currentScore);
    message = text1;
    label2 = "痛い、痛かった";//1
    text2 = "耳が痛い、痛かった トータルスコア:" + String(Number(currentScore)+ 1);
    message = text2;
    label3 = "とても痛いのが続いている";//2
    text3= "耳がとても痛いのが続いている トータルスコア:" + String(Number(currentScore)+2);
    message = text3;
  } else if (mes == "耳は痛くない トータルスコア"||mes=="耳が痛い、痛かった トータルスコア" ||mes== "耳がとても痛いのが続いている トータルスコア" ) {
    question = "熱はありますか？";
    label1 = "37.5未満";//0
    text1 = "37.5未満 トータルスコア:" + String(currentScore);
    message = text1;
    label2 = "38.5未満";//1
    text2 = "38.5未満 トータルスコア:" + String(Number(currentScore)+1);
    message = text2;
    label3 = "38.5以上";//2
    text3= "38.5以上 トータルスコア:" + String(Number(currentScore)+2);
    message = text3;
  } else if (mes == "37.5未満 トータルスコア"||mes== "38.5未満 トータルスコア"||mes== "38.5以上 トータルスコア") {
    question = "泣いたり、機嫌が悪いですか？";
    label1 = "いいえ"//0
    text1 = "機嫌は悪くない トータルスコア:" + String(currentScore);
    message = text1;
    label2 = "はい";//1
    text2 = "泣いたり、機嫌が悪い トータルスコア:" + String(Number(currentScore)+1);
    message = text2;
    label3 = "選択できません";
    text3= "開始";
    message = text3;
  } else if (mes == "機嫌は悪くない トータルスコア" ||mes== "泣いたり、機嫌が悪い トータルスコア" ) {
    question = "鼓膜が赤いですか？";
    label1 = "いいえ";//0
    text1 = "鼓膜は赤くない トータルスコア:" + String(currentScore);
    message = text1;
    label2 = "一部だけ赤い";//2
    text2 = "一部だけ赤い トータルスコア:" + String(Number(currentScore)+2);
    message = text2;
    label3 = "全体に赤い";//4
    text3= "全体に赤い トータルスコア:" + String(Number(currentScore)+4);
    message = text3;
  } else if (mes ==  "鼓膜は赤くない トータルスコア" ||mes== "一部だけ赤い トータルスコア" ||mes== "全体に赤い トータルスコア") {
    question = "鼓膜は腫れていますか？";
    label1 = "いいえ";//0
    text1 = "鼓膜は腫れていない トータルスコア:" + String(currentScore);
    message = text1;
    label2 = "一部だけ腫れている";//4
    text2 = "一部だけ腫れている トータルスコア:" + String(Number(currentScore)+4);
    message = text2;
    label3 = "全体に腫れている";//8
    text3= "全体に腫れている トータルスコア:" + String(Number(currentScore)+8);
    message = text3;
  } else if (mes == "鼓膜は腫れていない トータルスコア"||mes=="一部だけ腫れている トータルスコア" ||mes== "全体に腫れている トータルスコア" ) {
    question = "耳垂れは出ていますか？";
    label1 = "いいえ";//0
    text1 = "耳垂れは出ていない トータルスコア:" + String(currentScore);
    message = text1;
    label2 = "少し出ている";//2
    text2 = "少し出ている トータルスコア:" + String(Number(currentScore)+2);
    message = text2;
    label3 = "たくさん出ている";//4
    text3= "たくさん出ている トータルスコア:" + String(Number(currentScore)+4);
    message = text3;
  } 
  console.log(message);
  
  if (mes == "耳垂れは出ていない トータルスコア"  || mes == "少し出ている トータルスコア" || mes == "たくさん出ている トータルスコア" ) {
    let result;
    if (currentScore <= 5) {
      result="急性中耳炎は軽症です。抗生物質は使わずに3日間様子を見ましょう。"
    } else if (currentScore < 11) {
      result="急性中耳炎は中等症です。 AMPCを高用量で3～5日間投与しましょう。"
    } else {
      result="急性中耳炎は重症です。AMPCを高用量で使うか、CVA / AMPC１：１４製剤を通常量で使うか、CDTR-PIを高用量で使いましょう。鼓膜切開も考慮しましょう。"
    }
    return client.replyMessage(event.replyToken, {
        type: 'text', 
        text:result    
    });
  } else {
    return client.replyMessage(event.replyToken, {
      "type": "text", 
      "text": question,
      "quickReply": { 
        "items": [
          {
            "type": "action", 
              "action": {
              "type": "message",
              "label": label1,
              "text": text1
            }
          },
          {
            "type": "action",
              "action": {
              "type": "message",
              "label": label2,
              "text": text2
            }
          },
          {
            "type": "action", 
            "action": {
              "type": "message",
              "label": label3,
              "text": text3
            }
          }
        ]
      }
    });
   } 
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

##動作確認
ちゃんと動いています。
クイックリプライボタンで表示されます。
![耳痛１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/048825d3-a99f-aab2-a1be-f72b3300c741.png)

![耳痛.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/357844b3-cae9-8783-c907-c460dcc98e3f.png)
![鼓膜発赤３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/15861237-19ef-163a-9f2d-7edff2341eac.png)

![IMG-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/a9368829-463f-08e4-1643-fda94885afcb.png)



動画です。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">急性中耳炎重症度判定line bot <a href="https://t.co/SnYJHZgutt">pic.twitter.com/SnYJHZgutt</a></p>&mdash; 病気のセルフチェック (@Selfcheckhealt1) <a href="https://twitter.com/Selfcheckhealt1/status/1188340381068300288?ref_src=twsrc%5Etfw">2019年10月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



##考察
LINE Developersのクリックリプライを使いUIのなかなか良いLINE Botを作ることができました。handleEvent(event)を通るとScoreが0に戻ってしまうので、Scoreを足していくプログラムを書くのが難しかったです。サーバーで情報を管理できればもっと簡単にできそうなのでサーバー管理の勉強をしたいと思いました。