LINEBotをみんなで作ろう〜Messageを分岐させるぞ編〜【5日目】

この記事は下記の [#GWアドベントカレンダー](https://gw-advent.9wick.com/calendars/2020/72) の 5日目の記事になります。

1週間でサーバレスLINEBotを生み出す( @inoue2002  ） | GWアドベントカレンダー

# はじめに
こちらの内容は超初心者向けです。
[公式ドキュメント](https://developers.line.biz/ja/docs/messaging-api/overview/#messaging-api%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF)を読める方はこちらをお読みいただく方が正確です。

[昨日の記事](https://qiita.com/drafts/35fab5b7901aa94fafd2)をご覧になってない方はぜひ。
こちらの記事はGWアドベントカレンダーを通してLINEBotをサーバレスで作れるようになろう！ということを目標に書いている記事です。

LINEBotでMessageを送る実装はした事あるけど、ユーザーが送ってきたMessageによって条件分岐して処理した事ないわーというような方向けの記事です

昨日の記事でさまさまなMessagemを送信する方法をご紹介しました。本日はユーザーが送ってきたMessageごとに処理を変えていきます。

#始める前に注意！
現在ngrokを利用したデバック環境で実装をしておりますが、最近動きが悪くなってきており、一発では起動しない場合があるように感じます。
うまくいかない場合は何度か`control + C`→`ngrok http 3000`で再起動してみてください。（URLが毎回変わるので注意！）

#linebotで受け渡しされるWebhookの中身をみてみる
linebotはwebhookを利用してユーザーとボットサーバーを行き来しています。その内容によって処理を変えていきます。
まずは[ドキュメントを読んでいきましょう](https://developers.line.biz/ja/reference/messaging-api/)
Webohokのイベントオブジェクトは以下のように定義されています。
![スクリーンショット 2020-05-03 19.25.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/d737385b-1166-ea7c-226f-f020e2d8af83.png)

画像やテキスト、ステッカーなどのJSONがどのようになっているのかを確認できたら、以下のコードに書き換えて実行してみてください。

```index.js
"use strict";

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

const config = {
  channelSecret: "先ほどLINEBotのアクセストークンを入れる", 
  channelAccessToken: "先ほど発行したBOTのチャンネルアクセストークンを入れる"
};

const app = express();

app.post("/webhook", line.middleware(config), (req, res) => {
  console.log(req.body.events);
  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});

const client = new line.Client(config);

async function handleEvent(event) {
       let mes;
       switch (event.message.type) {
           case "text":
             mes= { type: "text", text: "めっせーじをありがとう！" };
           break;
           case "image":
             mes = { type: "text", text: "がぞうを受け取ったよ！" };
           break;
           case "sticker":
             mes= { type: "text", text: "ステッカーを送ってくれたんだね！" };
           break;
       };

     if (mes !== undefined) {
          return client.replyMessage(event.replyToken, mes);
      };
};

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```
上記のコードでは`switch`を使い、`event.message.type`をテキストか画像か、ステッカーかを判別して返すメッセージを決定します。

コードが無事に動くと以下のような挙動をします。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">わーい！メッセージや画像、スタンプを判別できるようになった！ <a href="https://t.co/HV1wjQLAEq">pic.twitter.com/HV1wjQLAEq</a></p>&mdash; ようかん (Yosuke Inoue) (@inoue2002) <a href="https://twitter.com/inoue2002/status/1256895688354328579?ref_src=twsrc%5Etfw">May 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今回は`event.message.type`で分けましたが、そもそも`event.type`を利用してメッセージ以外のフォローイベントやポストバックイベント等にも対応しなければなりません。それらを反映するために色々分岐すると以下のようなコードが完成します。

```index.js
"use strict";

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

const config = {
  channelSecret: "先ほどLINEBotのアクセストークンを入れる", 
  channelAccessToken: "先ほど発行したBOTのチャンネルアクセストークンを入れる"
};

const app = express();

app.post("/webhook", line.middleware(config), (req, res) => {
  console.log(req.body.events);
  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});

const client = new line.Client(config);

async function handleEvent(event) {
  let mes;

  switch (event.type) {
    case "message":
      mes = await messageFunc(event);
      break;
    /*case'postback':
    break;*/
    case "follow":
      mes = { type: "text", text: "追加ありがとううううううううう！" };
      break;
  }
  if (mes !== undefined) {
    return client.replyMessage(event.replyToken, mes);
  }
}

async function messageFunc(event) {
  let message;
  switch (event.message.type) {
    case "text":
      message = { type: "text", text: "めっせーじをありがとう！" };
      break;
    case "image":
      message = { type: "text", text: "がぞうを受け取ったよ！" };
      break;
    case "sticker":
      message = { type: "text", text: "ステッカーを送ってくれたんだね！" };
      break;
  }
  return message;
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```
変更箇所としては、先ほどまであった`event.message.type`を分岐するswitch文をmessageFuncの関数の中に入れ、新しく`event.type`で分岐するswitchを作り、そこで`event.message`だった時だけ呼び出しに行くようにしました。

`event.type`がフォローだった場合（友達登録された時）に`追加ありがとうううううう！`とメッセージを送信するようにしました。
正常に動くとこんな感じ↓
![37977.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/83f19dc5-f26f-0c7d-776f-bc9b58ef6226.jpeg)

このままだと、友達追加された時に２つもメッセージを返すことになるので、LINEコンソールから標準で送られるメッセージをオフにします。
[LINE Developerのサイト](https://developers.line.biz/ja/)に行ってBotの設定画面にいきます。
Messaging API設定をクリック
![スクリーンショット 2020-05-03 20.02.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/969bbe71-993e-37ef-0f20-e818d026a482.png)
スクロールして、左下にある「編集」をクリック（応答メッセージ/挨拶メッセージ共に同じページに飛びます）
![スクリーンショット 2020-05-03 20.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/1608f586-3473-0311-8d55-9aa607c7eb29.png)
ここの挨拶メッセージの項目を「オフ」にするだけでLINEからのメッセージは送られなくなります！
![スクリーンショット 2020-05-03 20.02.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/ca2aeb14-e012-a6cd-b659-3630501a5e71.png)
反映に成功するとこんな感じ↓
![37967.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/4e7b3d9d-bc8e-c773-4415-1db37723c160.jpeg)


これで無事、色々なイベントに対して異なった処理を行えるようになってきました。
次はユーザーが送ってきた特定のメッセージにだけ反応する処理を実装していきましょう！
index.jsのmessageFuncを以下のように書き換えてください

```index.js

async function messageFunc(event) {
  let message;
  switch (event.message.type) {
    case "text":
      if(event.message.text ==='おはよう'){
        message = {type:"text",text:"おやすみ"}

      }if(event.message.text ==='おやすみ'){
        message = {type:"text",text:"おはよう"}
      }
      break;
    case "image":
      message = { type: "text", text: "がぞうを受け取ったよ！" };
      break;
    case "sticker":
      message = { type: "text", text: "ステッカーを送ってくれたんだね！" };
      break;
  }
  return message;
}
```
このコードを実際に動かしてみると、、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">『おはよう』→『おやすみ』<br>『おやすみ』→『おはよう』 <a href="https://t.co/4WlmkgNeF5">pic.twitter.com/4WlmkgNeF5</a></p>&mdash; ようかん (Yosuke Inoue) (@inoue2002) <a href="https://twitter.com/inoue2002/status/1256905079543623681?ref_src=twsrc%5Etfw">May 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんな感じになります。あとはこのメッセージを写真にしたり、ステッカーにしたり。ドキュメントを読んで他のメッセージを送ることだって可能です。
色々遊んでみてください。いよいよ動くようになってきたLINEBotをサーバレスにしていきます。

本記事：[LINEBotをみんなで作ろう〜Messageを分岐させるぞ編](https://qiita.com/inoue2002/items/650eca3f7dd6a5fccb63)
次の記事：[LINEBotをみんなで作ろう〜AWSアカウントを作るぞ編](https://qiita.com/inoue2002/items/ad945981150c859911fc)

[LINEBotをみんなで作ろう〜環境構築編〜](https://qiita.com/inoue2002/items/a87df2b520f8b6e37f42)
[LINEBotをみんなで作ろう〜LINEBot is 何？編](https://qiita.com/inoue2002/items/3a5019c07801bcf5ff75)
[LINEBotをみんなで作ろう〜おうむ返しbotを作ろう編〜](https://qiita.com/inoue2002/items/dcf40d5ebfe2454796fa)
[LINEBotをみんなで作ろう〜色々なメッセージを送ってみよう編](https://qiita.com/inoue2002/items/35fab5b7901aa94fafd2)
[LINEBotをみんなで作ろう〜レイヤーとAPIgateway設定編](https://qiita.com/inoue2002/items/ab226d9836a891b01bc9)
[LINEBotをみんなで作ろう〜コードを実装編](https://qiita.com/inoue2002/items/dbbd862d6149c83f6513)