【Make】この商品はいつくるの？LINEが商品の納品日を教えてくれる。

# これいつ入ってくるんだっけ？
みなさんこんにちは。

北海道の某小売り業で朝から働くおじさん（主任）です。

普段から働いていて、部下からよくこんなことを言われるのです。
**「主任！この商品Aがないよ！次いつ入ってくるの！？」**
そう言われると大体
**「ちょっとまって！今調べてくるわ！」**

こんなやり取り日常茶飯事です。

調べるって言っても、パソコン（またはタブレット）のある場所まで行って、立ち上げて、発注画面を開くためにログインして、発注確認して、現場に戻る・・・。

1回ならいいけど、五月雨式に言われると結構手間がかかります。 ~~あと、歩くのが疲れる。~~


なので、LINEBotを活用して、
「商品名を聞いたら、その商品の発注内容を返してくれる」
そんなものを作ろうと思います。

素人だから、いろいろ苦労すると思いますが、まずは手を！頭を！動かそう！

## 完成品

![line完成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/341f2dd4-2c83-4e43-a923-70f76f99d211.gif)


## 使用ツール
* [LINEmessagingAPI](https://developers.line.biz/ja/services/messaging-api/)
* [LINE Developers](https://developers.line.biz/ja/)
* [Make](https://www.make.com/en)
* Googleスプレッドシート

※Makeのフリープランの場合、1か月の利用制限があるのでご注意を！

## Make全体の構造

![構造全体.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/45a25bbc-8359-4472-96cd-0ea39d2952e7.png)

この処理一連の流れを、**Scenario**（**シナリオ**）と言います。

## 作成開始
### Googleスプレッドシートの作成
まずデータの素となる発注表を作成します。
サンプルとしてこんな感じ。

![スプレッドシート１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/7f66afaf-e0a7-4fff-b549-460788da0ab1.png)



実際の発注画面から似たような形で出力が可能です。
データは出力した日から1週間分です。実際の発注画面も1週間分の表示しかできないため、この形をフォーマットとします。

### Scenarioの作成

LINEトークで商品名を打ち、同じ商品があるかを検索し、あった場合はその商品の1週間分の発注を出力し、ない場合は存在しない旨を出力します。

#### 1.トーク内容から商品名を探す

まず、LINEのトーク内容から、Googleスプレッドシートの商品名（A列）を探します。Googleスプレッドシートモジュールの中身は

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/cfc96ad1-eb1f-41cd-a282-47436adff5d2.png" width = "300" />

こんな形で、商品を探す際の条件を加えます。条件として、**equal to**（完全一致）にしたいところですが、ここでは探しやすいように**Contains**（部分一致）にしました。Containsにした理由は後述します。

#### 2.条件分岐させる


一つも該当しない場合と区別するために、一致した件数を取得します。ここでは、Flow Control→Array aggregatorモジュールを使用します。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/baaf6f4c-78e5-4c64-9bf4-2c7e0e60a8cd.png" width="300"/>


このモジュールを活用することで、一致した商品名を配列化してくれます。そして、その配列の要素数(Total number of bundles)を取得することで、件数を求めることが出来ます。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/d8c8ea34-a203-4b45-b735-72e972b7e813.png" />

↑Routerを用いて分岐させる

<table>
<tr>
<td> <img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/2d83f358-61c7-4fae-907f-97ef5beacfba.png" width="300"/></td>

<td><img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/b59e55bd-8824-4631-8a2b-c8745b717f19.png" width="300"/></td>
</tr>
</table>

↑左：0件の場合 右：1件の場合

見つかった場合と、見つからなかった場合の条件を分岐させます。先ほど取得した件数が1の時は、
入荷日1→個数
入荷日2→個数
入荷日3→個数

となるように出力させます。また、0件の場合は「その商品はないようです・・・。」

と出力させます。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/72c41f55-6118-4d13-b76f-1b9f797a1589.png" width="300"/>

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/08fc5cf5-d132-495e-9649-6aecf7ee0260.png" width="300"/>


これで基本ベースは完成になります。

![line2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/0bf40213-c2d7-43ed-bab5-5a8e33005310.gif)


↑動作

### 色々なパターンを考える
このままでも確かに使うことは可能ですが、商品名が似たようなパターン（りんごとりんご酢）の場合や、そもそも商品名が長すぎてトークを打つのに時間がかかってしまう場合があります。そこで、商品名の選択肢を表示させ、その選択肢をタップすることで、求めたい商品の発注状況を表示できるようにしよう。

似たような商品名を載せたスプレッドシートになります。A、AA、AB、Cのパターンを入れてあります。

![スプレッドシート2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/3c74f877-6e8f-42ba-8d64-61523b2fc87f.png)


このパターンを考慮し、LINEトークで打った内容がGoogleスプレッドシートの商品名の文字列を含む場合も条件分岐させます。このために、**equal to**（完全一致）ではなく、**Contains**（部分一致）にしたというとになります。

件数が2件以上見つかった場合の条件分岐をさせます。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/1ffd49b6-ad9f-43db-9ec6-0a4d79a333b1.png" width="300"/>

<br>

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/58b7a828-66b0-4064-ba6c-dc7a6942dec6.png" width="300"/>


↑Greataer thanは、〇〇以上大きい になります。

2件以上候補に出た場合、LINEからFlex messageを送信し、ユーザーに発注を表示したい商品を選ばせる形にします。

:::note info
* LINE Flex messageとは、複数のブロックを自由に組み合わせて、パネル型のメッセージを作成できる機能です。ブロックにはテキストやボタン、画像や動画を設定できます。色や大きさもカスタマイズできるので、イメージに合わせて柔軟にメッセージを作れるのが特徴です。
* LINE Developersが提供する[Flex Message Simulator](https://developers.line.biz/ja/docs/messaging-api/using-flex-messages/#checking-behavior-in-flex-message-simulator)を使うと、メッセージを実際に送信しなくても、描画された状態を確認できます。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/02a070ec-8a59-4223-ac5a-4b08aa919ee0.png" width="600"/>

:::

LINE Flex messageを使うために、**HTTPモジュール→Make a request**を使います。
モジュールの設定の参考画像を載せておきます。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/63c5fdda-d577-406f-9c4d-8fe4dc190b60.png" width="300"/>

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/8ca22f83-0557-4ee5-b73b-3de824949725.png" width="300" height="200"/>

:::note warn
Bearerとチャネルアクセストークンの間には、半角スペースが必要です！
:::

右画像のRequest contentにFlex messageを送信するためのJSONを打ち込みます。先ほど紹介したFlex Message Simulatorを使って作成するのがオススメ。
実際に自分が打ち込んだJSONを貼っておきます。

```rb
{
  "to": "{{LINE.events[].source.userId}}", 
  "messages": [
    {
      "type": "flex",
      "altText": "発注商品を選択してください",
      "contents": {
        "type": "bubble",
        "body": {
          "type": "box",
          "layout": "vertical",
          "contents": [
            {
              "type": "text",
              "text": "発注商品を選んでください",
              "weight": "bold",
              "size": "lg",
              "margin": "md"
            },
            {
              "type": "separator",
              "margin": "md"
            },
            {
              "type": "button",
              "action": {
                "type": "message",
                "label": "{Googleスプレッドシートの商品名を選択}",
                "text": "{Googleスプレッドシートの商品名を選択}"
              },
              "style": "primary",
              "margin": "md"
            }
          ]
        }
      }
    }
  ]
}
```

更に実行する前に、Makeで実行タイミングを設定する必要があります。
画面左下の「Immediately as data arrives」をONにして、「OK」を選択します。もし画面左上にキューに関する表示がされたら、今回は「Delete old data」で削除して大丈夫です。設定できたらScenarioを保存します。

![RUN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/4736108e-b5da-4cba-87ff-1e3fa02b6028.png)

そしてScenarioを有効化します。

![ONにしよう.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/a4411b7e-21d2-42c8-9626-d513980dc656.png)

この設定をすることで、LINEにイベント（商品名を打つ）が発生したら、常にこのScenarioが起動するようになります。実はこの設定が大事！

Flex messageを使った際の処理は下図のようになります。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/9ce35db6-5b70-4ed2-97a2-161939f21e9b.png" width="300"/>

<br>

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/35313467-9d9b-46aa-a608-49337d030e0e.png" width="300"/>

このような形で、選択した商品の発注状況を返してくれます。仮にABの品名がかなり長い商品名だったとしても、タップするだけで打てれば楽ですよね！

ちなみに、Scenarioの処理としては、

![疑似ループ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/4bd84139-7b3c-4565-b86a-a72b6be09792.png)

↑Scenario処理の図

①LINEで商品名を入力
②Routerで条件分岐し、2件以上候補が出た場合上のHTTPモジュールへ処理が進む。
③ここで候補の商品名すべてがFlex message で返ってきて、**処理が終了**。
④Flex messageの選択肢をタップすることで、**タップした商品名が入力される**。
⑤条件分岐の際に、タップした商品名1件が見つかり、下の分岐へと進む。
⑥見つかった商品の発注状況が返ってくる。

先ほど実行タイミングを設定したことで、③で処理が終了してしまうが、④で再びScenarioが始まるので、疑似的なループのような処理になります。

# 課題と反省点
似たような商品名の場合ですが、よっぽど似てない限りは正しく動作してくれます。が、先ほど紹介した「りんご、りんご酢」のパターンでりんごを選択してしまうと、先ほどのScenario処理の図⑤で再び2件以上の候補が見つかってしまうので、またHTTPモジュールへと進み、Flex messageが返ってきます。結果として発注状況を返す処理に進むことができません。

![lineエラー.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4077785/61c4d01d-bacc-4640-8e7e-be2bfbd71d4f.gif)


商品とJANコードのような判別する何かと関連付けたりとか・・・いろいろ方法はありそうですね。考えることはまだまだ多い！


# 最後に
今回はLINEBotを用いてGoogleスプレッドシートにアクセスさせたり、Flex messageを使ってみましたが、Makeは奥が深い！モジュールも沢山あるし、やれること無限大なんだろうなーと感じました。

また、今回初めて生成AIを使って情報収集してみましたが非常に便利で、なんで今まで使ってこなかったんだろう？と後悔しています。（笑）
これから世の中の便利なツール生かして、デジタルおじさんになれるよう頑張っていきます。

ここまで見ていただき、ありがとうございました！